
文章插图
4、计数器-Counter Service
最初是可以采取Memcached,但它有个问题,如果计数超过它内容容量时,会导致一些计数的剔除,宕机或重启后计数就没有了 。另外可能有很多计数它为零,那这个时候怎么存,要不要存,存的话就占很多内存 。微博每天上十亿的计数,光存0都要占大量的内存,如果不存又会导致穿透到DB里去,对服务的可溶性会存在影响 。
2010年之后我们又采用Redis访问,随着数据量越来越大之后,发现Redis内存有效负荷还是比较低的,它一条KV大概需要至少65个字节,但实际上我们一个计数需要8个字节,然后Value大概4个字节,所以有效只有12个字节,还有四十多个字节都是被浪费掉的 。这还只是单个KV,如果在一条Key有多个计数的情况下,它就浪费得更多了 。比如说四个计数,一个Key 8个字节,四个计数每个计数是4个字节,16个字节大概需要26个字节就行了,但是用Redis存大概需要200多个字节 。
后来我们通过自己研发的Counter Service,内存降至Redis的五分之一到十五分之一以下,而且进行冷热分离,热数据存在内存里,冷数据如果重新变热,就把它放到LRU里去 。落地RDB、AOF,实现全增量复制,通过这种方式,热数据单机可以存百亿级,冷数据可以存千亿级 。

文章插图
整个存储架构大概是上图这样,上面是内存,下面是SSD,在内存里是预先把它分成N个Table,每个Table根据ID的指针序列,划出一定范围 。任何一个ID过来先找到它所在的Table,如果有直接对它增增减减,有新的计数过来,发现内存不够的时候,就会把一个小的Table Dump到SSD里去,留着新的位置放在最上面供新的ID来使用 。
有些人疑问说,如果在某个范围内,我的ID本来设的计数是4个字节,但是微博特别热,超过了4个字节,变成很大的一个计数怎么处理?对于超过限制的,我们把它放在Aux dict进行存放,对于落在SSD里的Table,我们有专门的IndAux进行访问,通过RDB方式进行复制 。
5、其他数据类型-存在性判断

文章插图
除了计数,微博还有一些业务,一些存在性判断 。比如一条微博展现的,有没有点赞、阅读、推荐,如果这个用户已经读过这个微博了,就不要再显示给他 。这种有一个很大的特点,它检查是否存在,每条记录非常小,比如Value1个bit就可以了,但总数据量巨大 。比如微博每天新发表微博1亿左右,读的可能有上百亿、上千亿这种总的数据需要判断 。怎么来存储是个很大的问题,而且这里面很多存在性就是0 。还是前面说的,0要不要存?如果存了,每天就存上千亿的记录;如果不存,那大量的请求最终会穿透Cache层到DB层,任何DB都没办法抗住那么大的流量 。

文章插图
我们也进行了一些选型,首先直接考虑能不能用Redis 。单条KV 65个字节,一个KV可以8个字节的话,Value只有1个bit,这样算下来每日新增内存有效率是非常低的 。第二种我们新开发的Counter Service,单条KV Value1个bit,我就存1个byt,总共9个byt就可以了 。这样每日新增内存900G,存的话可能就只能存最新若干天的,存个三天差不多快3个T了,压力也挺大,但比Redis已经好很多 。

文章插图
我们最终方案是自己开发Phantom,先采用把共享内存分段分配,最终使用的内存只用120G就可以 。算法很简单,对每个Key可以进行N次哈希,如果哈希的某一个位它是1,那么进行3次哈希,三个数字把它设为1 。把X2也进行三次哈希,后面来判断X1是否存在的时候,从进行三次哈希来看,如果都为1就认为它是存在的,如果某一个哈希X3,它的位算出来是0,那就百分百肯定是不存在的 。

文章插图
它的实现架构比较简单,把共享内存预先拆分到不同Table里,在里面进行开方式计算,然后读写,落地的话采用AOF+RDB的方式进行处理 。整个过程因为放在共享内存里面,进程要升级重启数据也不会丢失 。对外访问的时候,建Redis协议,它直接扩展新的协议就可以访问我们这个服务了 。
6、小结
推荐阅读
- 嘴唇干裂脱皮并不全是缺水 来看看应对方法
- 儿童秋季腹泻高发 宝妈准备好如何应对了吗?
- 抖音郭聪明的作品怎么没有了 郭聪明微博
- 新网站一个月没有收录怎么应对
- 日饮三杯茶有7大好处
- 社会化营销效率再升级 微博营销平台
- 服务器被黑给我上了一课,由0到1轻松应对各式攻击!
- 遭公司劝退如何应对?看看人家怎么做的 劝退的情形和应对方式
- 冬季过敏性鼻炎高发 5招学会应对
- 秋老虎来了小心这10种病 按4个穴位轻松应对
