Redis在微博内部分布在各个应用场景,比如像现在春晚必争的“红包飞”活动,还有像粉丝数、用户数、阅读数、转评赞、评论盖楼、广告推荐、负反馈、音乐榜单等等都有用到Redis。
作者:兰将州来源
一、Redis在微博的应用场景
Redis在微博内部分布在各个应用场景,比如像现在春晚必争的“红包飞”活动,还有像粉丝数、用户数、阅读数、转评赞、评论盖楼、广告推荐、负反馈、音乐榜单等等都有用到Redis。
1、业务&规模&挑战
线上的业务有前面提到的信息流、广告、用户关系等等,还有现在大家可能比较感兴趣的热搜,用户一般会去看发生了什么事情,还有引爆阅读量的话题,以及现在兵家必争之地的视频,微博大大小小的业务都有用到Redis。
线上规模方面,微博有100T+存储,1000+台物理机,10000+Redis实例。
关于面临的挑战,我们每天有万亿级的读写,线上的响应时间要求也比较高。
举一个简单的例子,我们部署资源是跨机房部署,但是有一些业务部门连跨机房部署存在的多余两毫秒的延迟都要投诉反馈(真的是臣妾做不到啊,如果单机房故障了呢?有些业务方真是异想天开)。响应时间基本上四个9是20毫秒。
成本的话因为我们线上有大量需求是上T的,所以成本压力其实也特别大。
2、技术选型
上图是微博数据库的技术选型,其实可以看到这里面不仅仅包含Redis等NoSQL,还有队列、存储,如果以后有机会的话可以给大家分享一下从0到1搭建微博的数据库,在内部分享的时候大概花了2-3个小时,时间有限,这次就只讲Redis这一部分。
3、优化
从2010年开始,我们就基于官方的2.0版本引进Redis,到现在已经有九个年头了,我们主要做了以下这些方面的改进:
- Redis编码格式,在特殊场景下可以节省30%的空间;
- 主从库方面有独立的复制线程;
- 我们定制化一些数据结构,比如:LongSet 数据结构,它是一个“固定长度开放寻址的 Hash 数组”,减少Redis dict 很多额外的指针开销;
- 在主从复制方面,独立复制线程 + 完全增量复制,这样的话,如果网络主从临时断了,只要从当前的pos点同步数据就行;
- 在持久化方面,我们是全量的RDB加增量的AOF复制;
- AOF写入/ 刷盘,主线程—>BIO,避免了因为写入导致的阻塞;
- 落地时间,不可控—>cronsave可控;
- 增加aofnumber,设置AOF数量,避免因为写入过快,磁盘写满;
- 高可用, Redis的HA我们并没有用官方的或者社区开源的,用的是我们自己开发的一套Redis HA,保障在故障的情况下,能快速进行切换。
微博有大量的技术场景,比如转评赞、阅读数等,对于一些用户来说,他们是很关心这些指标的。
如果我们用原生的Redis,会浪费大量的存储空间,因为它的产品特别特殊,它的key是一个用户的id,value是数字,我们自己内部最早改了一版叫RedisCounter,它相当于只维持了一个哈希表,节省了大量的Redis内存空间。
当然它有一个缺点就是当初是短平快地上线了,所以它只支持单个列和单个表,如果你要存转发,评论,赞3个计数的话需要部署三套资源,这样一来大家访问微博取这3个数的速度会变慢。
而且需要维护3套资源,为了应对这种场景,我们支持了多列和多表的方式,如果一个表写满了,可以继续写下一个表,写到最后一个表时,我们可以把前面的表滚到盘里面,但是这个时候是不可读的。
为了解决不可读的问题,我们想了一个办法,把表都放在磁盘里面,维护ddb的数据结构,在这样的落地方式下,就可以把最近的热数据放在内存里面,把冷数据或者历史数据放在磁盘里面。
之前统计了一下,在线上90%多的情况下,用户只访问几个月的数据,所以一些长尾数据可以靠从磁盘中读取数据来解决,也不影响用户体验。
微博还有一些存在性判断的行为,比如是否赞过、是否阅读过,这些全量的数据特别大,如果用Redis的话对内存