【AICon】 如何构建高效的 RAG 系统?RAG 技术在实际应用中遇到的挑战及应对策略?>>> 了解详情
写点什么

Redis 计数在新浪微博的应用

  • 2014-03-17
  • 本文字数:1925 字

    阅读完需:约 6 分钟

微博业务的迅速发展,对基础架构层面的要求也越来越高。新浪作为国内最早使用 redis,并且是国内最大的 redis 使用者,在 redis 的使用上,也在逐步优化和提高。

作为微博中一项重要的数据,计数类业务在微博业务中占的比重和重要性逐步提高。计数结果的准确度直接影响用户体验,并且很容易引起用户的投诉。在计数业务上,在不断的优化和改进中,我们主要经历了以下三个阶段:

初级阶段

从 2010 年开始,使用 redis-2.0 版本。在最初业务数据比较少的时候,表现相当不错。但随着数据量和请求量的不断增加,一些问题逐渐暴露出来。

  • 主从同步问题

    首先遇到的是主从的同步问题。它的原理是当 master 接收到 slave 的同步请求后,把内存的数据 fork 出一个子进程 dump 出来,形成 rdb 文件,然后传到 slave,slave 再把这个文件加载到内存,之后的增量更新由 master 在执行完每条修改命令后立即同步给 slave。 在网络出现问题时,比如瞬断,会导致 slave 里的数据全部重传。对单个端口来说,如果数据量小,那么这个影响不大,而如果数据量比较大的话,就会导致网络流量暴增,同时 slave 在加载 rdb 时无法响应任何请求。

  • 持久化问题

    计数业务中多数使用 redis 作为存储,因此都开启了 aof,并配置为每秒做一次 fsync 操作将写操作刷新到磁盘。随着 aof 的增长,需要定期 rewrite。Rewrite 的机制和生成 rdb 的过程类似,都是 fork 出一个子进程来完成的,子进程对于磁盘的持续写入会导致父进程的 fsync 操作阻塞,造成大量请求超时。

  • 版本升级问题

    由于 redis 在使用初期 bug 较多,版本迭代频繁,而版本升级需要关闭 redis 进程并重新加载 aof。对于大量使用 redis 的微博业务来讲,这样的升级成本也越来越难以承受。

  • 内存使用问题

    2.0 版本的 redis,在内存使用上相对比较粗放,对于计数这样一个简单的 key-value,占用的内存达到 100 字节以上,存在比较多的优化空间。

进阶阶段

针对 redis 使用初期存在的问题,我们逐个进行了改进。主从复制参考 mysql 的同步方式,使用 rdb+aof 结合的方式,解决了网络瞬断引起的重传问题,同时限制子进程做后台 dump 时对磁盘的写入,期间暂停主进程的 fsync 操作,解决了慢请求的问题。

针对计数业务,我们开发了专用的版本 redisscounter,单个 key-value 占用的内存 key 的长度加 4 个字节的 value,将内存的使用量降低到原来的 1/4 以下。通过预先分配内存数组和 double hash 技术,消除了 redis 中 hash 表的大量指针开销。

对于版本升级的问题,我们将 redis 的核心处理逻辑封装到动态库,内存中的数据保存在全局变量里,通过外部程序来调用动态库里的相应函数来读写数据。版本升级时只需要替换成新的动态库文件即可,无须重新载入数据。通过这样的方式,版本升级只需执行一条指令,即可在毫秒级别完成代码的升级,同时对客户端请求无任何影响。

有了上面的改进后,新版本开始大量应用,多数业务都可以作为完整的存储替代以前的 mysql+memcached 组合。对于微博的评论数和转发数,由于微博条目不断增加,无法保存全量数据,因此采用 mysql+redisscounter 组合的方式,mysql 保存全量数据,使用两组 redisscounter 保存最近几个月的热数据,通过定期滚动两组 redisscounter 里的数据来清理冷数据。

高级阶段

随着微博的发展,针对单条微博的计数也不断增加,从原来的评论数、转发数,又增加了表态数,2013 年还上线了阅读数。Redisscounter 不能很好的解决这类扩展问题,同时上面的 mysql+redisscounter 的滚动方式也过于复杂,定期的滚动操作很容易出现问题。针对这类问题,我们再度做出改进,将 key 由原先的字符串改成微博 id,同时对于每条微博的评论转发等计数,我们统计发现,绝大多数微博的计数都可以用 10~15 个 bit 来保存,因此可以将多个计数保存到一个 4 字节的 value 里,过大的计数值在内存中另外开辟一块空间来保存。这样通过一条 get 命令即可获取该微博的所有计数。同时针对微博业务的特点,越老的微博被访问的次数就会越少,在内存使用多个数组保存不同范围的微博,内存不足时将最老的一组微博 dump 到 ssd 上,内部自动实现的滚动可以保证热微博全部在内存里。对于落到 ssd 上的老数据的访问,通过异步的 io 线程来读写,经过这样的改进后,去掉了原先的 mysql 存储,降低了业务开发成本和运维成本。

从 redis 在计数业务上的发展经历可以看出,技术的进步是由业务的需求推动的。随着业务的发展,还会遇到更多新的挑战。希望我们走过的这些改进之路对于读者在使用 redis 的过程中能有所帮助。

感谢张龙对本文的审校。

给InfoQ 中文站投稿或者参与内容翻译工作,请邮件至 editors@cn.infoq.com 。也欢迎大家通过新浪微博( @InfoQ )或者腾讯微博( @InfoQ )关注我们,并与我们的编辑和其他读者朋友交流。

2014-03-17 22:2810651

评论

发布
暂无评论
发现更多内容

Java面试题jvm调优,牛客刷题指南,Java面试题

Java 程序员 后端

Java项目视频百度云,vue做视频教程,dubbo面试题总结

Java 程序员 后端

Java面试视频教学,java视频黑马,linux运维视频教程全集

Java 程序员 后端

Java面试题总结及答案,牛客网竞赛中复制别人的答案,Java工程师面试题

Java 程序员 后端

Java高级工程师进阶学习,2021Java高频精选面试题讲解

Java 程序员 后端

Java高级架构师面试题,李玉婷尚硅谷漂亮,程序员怎样优雅度过35岁中年危机

Java 程序员 后端

Java高级知识体系,java性能调优实战网盘,大厂首发

Java 程序员 后端

Java面试手写算法,极客时间数据结构算法地图,Java岗面试12家大厂成功跳槽

Java 程序员 后端

Java面试题大全,尚硅谷dubbo下载,面试经历分享

Java 程序员 后端

Java高级工程师必看系列,Java程序员面试常问的问题

Java 程序员 后端

JDK、JRE与JVM的区别与联系,springmvc基础知识pdf下载

Java 程序员 后端

Java面试必备的集合源码详解,小白勿进

Java 程序员 后端

Java项目实战网盘资源分享,千锋java课程大纲,含小米、腾讯、阿里

Java 程序员 后端

Java高级工程师面试题目,尚硅谷kafka文档,和腾讯大牛的技术面谈

Java 程序员 后端

Java高级面试手册,架构师修炼之道pdf百度云,Java开发实战经典答案

Java 程序员 后端

Java面试知识点总结宝典助你通关,Java校招笔试面试题目

Java 程序员 后端

Java面试题集2021版,2万字20个项目实例

Java 程序员 后端

Java高级互联网架构师,java韩顺平最新教程,程序人生

Java 程序员 后端

Java面试技巧和注意事项,java开发实例教程,阿里巴巴Java编程笔试题

Java 程序员 后端

Java面试知识点总结,mongodb权威指南pdf网盘,SpringBoot

Java 程序员 后端

Java面试秘籍,java调用百度地图接口,含面试题+答案

Java 程序员 后端

Java高级开发面试视频,nginx教程pdf,linux初学者入门书籍

Java 程序员 后端

Java高级软件工程师面试题,java菜鸟教程多态,Java程序员面试笔记pdf

Java 程序员 后端

Java面试问题及答案,java实用教程第五版课后答案,Java重要知识点

Java 程序员 后端

Java项目视频百度云盘,java视频百度云盘,【一步教学,一步到位】

Java 程序员 后端

Java高级工程师每日面试题精选,最新大厂Java校招面试经验汇总

Java 程序员 后端

Java高级技术架构,linux操作系统教程海南师范大学,nginx入门书籍推荐

Java 程序员 后端

Java面试问题大全及答案大全下载,java高级教程百度云,已有千人收藏

Java 程序员 后端

Java项目视频,千锋java百度云,附赠课程+题库

Java 程序员 后端

Java高级技术经理面试题,西安尚学堂教育,已开源下载

Java 程序员 后端

Java高级知识体系,kalilinux新手教程,Java实习面试经验汇总

Java 程序员 后端

Redis计数在新浪微博的应用_语言 & 开发_田风军_InfoQ精选文章