在2016杭州云栖大会的“开源数据库之Redis专场”上,微博研发中心数据库技术负责人肖鹏带来了《微博的Redis定制之路》的精彩分享。分享中,他重点介绍了微博六年来使用Redis遇到的问题和积累的实践经验。

以下内容根据演讲PPT及现场分享整理。


微博属于国内较早一批Redis用户,微博目前由近千台Redis物理机,近万个Redis实例,日访问量达到万亿以上,从微博开始使用Redis到现在可以分为三个阶段:探索期、发育期、稳定期。最初上线试水Redis,是因为使用MySQL遇到问题,无法解决业务瓶颈。六年的时间内,微博在使用Redis过程中积累了大量的经验和技巧。

探索期:野蛮生长

微博最初使用Redis时,是采用Reids替换掉架构中的MC,形成Web+Redis+MySQL的架构。经过一段时间的使用,发现Redis的数据结构十分丰富,并且自带持久化功能。因此微博采取了一步大胆的尝试,将三层架构中的MySQL剥出,将Redis最为落地存储的数据库,将三层结构变为两层结构。

在初期使用Redis时遇到很多问题:首先性能上由于Redis原生是单线程的,在进行重操作,尤其是bgsave时会出现明显的卡顿,业务波动;其次故障恢复问题,宕机后恢复主从速度慢,经常出现带宽洪峰问题;此外,运维上也存在复杂度问题,版本升级频繁,主库切换常态化。

为了解决Bgsave带来的问题:一是可以从主线程中独立出来Bio thread,专门执行Bgsave等操作,避免干扰;二是在Redis中内置Cronsave功能,控制备份时间;三是放弃Bgaofrewrite。

在Redis替代MySQL存储落地的过程中,微博对Redis也进行很多定制化改造:

  • 修改了AOF机制,增加原本不存在的POS位;
  • 修改了Replication机制,实现基于AOF+POS位置的数据同步
  • 修改落地机制,改为RDB+AOF滚动机制,保障数据持久化存储。

在使用Redis过程,同样可以对其热升级,简化运维复杂度:主程序中为全局的数据结构,其他功能封装到Libredis.so中,对Libredis.so实现动态热加载,每次版本升级实现热升级,不必再进行主库切换,极大地降低运维复杂度和业务风险。

总结一下,在探索期:以业务和运维驱动为主对Redis进行定制化改造,参考MySQL的Binlog机制进行数据同步,使得主库和从库一致性得到保障。在此之后微博Redis的改造全部基于该版本。

发展期:争奇斗艳

从下图可以看出,随着时间的发展,微博在逐渐向Redis上转移业务,从13年到14年经历了巨大的服务和产品线的提升,进而带了一些特殊的需求。

微博中最为重要的是关系类存储,其量达到千亿级别,将其存储在Redis中,势必会导致日益增长的关系类存储容量问题同成本之间的矛盾(常用的Redis的型号是128G);第二点微博中琳琅满目的技术类场景需要专门的解决方案;第三是判断类的需求,利用Redis进行判断时不仅具有较大的时延还需要占据大量的内存。

针对上述需求,微博对Redis进行了定制化的改造。

针对千亿级别的关系类存储,为了减少成本,定位从Storage变为Cache;放弃了原生的Hash结构(比较占内存),定制Longset数据结构(固定长度开放寻址的Hash数组);当 Cache miss之后,Client批量为O(1),同时内存占用降为原来的1/10。

针对计数类需求,根据业务场景将KV改为定长KV;采用Double hash解决冲突。由于其用于计数场景,因此将Redis中其他数据结构从Redis cont版本中剥离,变成一个超级精简的Redis,通过预分配内存,降低指针开销。通过上述操作不仅降低了成本,同时内存占用率降为原来的1/4。

微博目前拥有十亿多用户,每个用户都有粉丝数、关注数、博文数,十亿用户至少需要三十亿的计数,这是一个相当大的开销,这就需要对Redis进一步改造:通过Schema支持多列存计数,降低了内存占用,减少了网络开销;第二点,由于计数较小较快,完全使用内存会导致资源浪费,因此可以进行冷热数据分离,热数据放在内存里,冷数据放到SSD磁盘中;当为了便于读取冷数据,增加了LRU cache模块,保证冷数据的性能;此外,再改版之后Redis中还添加了异步IO线程访问磁盘,避免性能问题。

针对判断类需求,通过Bloomfilter,采用0110的方式很简单地进行判断,极大地降低了存储空间,同时也减少时延消耗,解决了微博上是否赞过等场景的高并发问题和成本问题。

稳定期:拾遗补缺

经过四年对Redis根据业务需求不断进行改造,目前微博对Redis的使用逐步到达稳定期,主要的工作是进行查缺补漏:

  • 服务化方面,随着业务的变大,集群规模也随之增大,拼写Hash规则已经变成负担,并且每次变更扩容都变得及其复杂;
  • 数据流动方面,多个存储的更新存在数据不一致的情况,并且业务双写也增加了程序的复杂性;
  • 数据迁移方面,原有的Redis的拆分和改造都需要DBA和RD共同参与以便保证数据的一致性以及尽量降低对业务的冲击。

针对上述需求,微博自研了中间件实现路由功能;在架构右侧引入Configer Service模块,统一配置管理;同时引入Slot设计,实现动态的Slot迁移,对业务无影响,此外还架构中基于Slot设计无缝扩容功能,实现线性扩容,由于架构中具有Slot Manger、Remote Proxy、Configer Service以及iTransfor中间件,架构可以融入HA等运维机制。

在微博实际关注场景中,例如我关注了你,之后需要加入你的粉丝列表;需要更新我的关注列表;还要增加两人的计数器,一个操作带来很多的入库操作。最开始采用的是程序多写的方式,但随着工程量的增加,这种操作会带来很多隐患。目前微博通过自研的DataBus,基于MySQL的row格式binlog日志实现消息的流转,保障了数据的一致性;下游兼容Redis、HBase等存储;此外,用户可自定义DataBus中的transforemer模块,支持对MySQL消息的自定义处理规则处理。

最近微博对Redis 进行了iTranstor操作。当Redis达到物理机极限时,需要对Redis进行拆分,微博自研了iTranstor,实现对单端口的Redis实现拆分;其中用户可自定义拆分规则(作为独立组件或称为Redis的一个功能),可以实现Rang或者Hash的拆分规则,实现上下游不同的Redis分支。

总结和未来

微博在使用Redis的过程中,秉承着业务驱动的模式,所有技术上的改造都是为了满足不同的业务需求;反过来技术的变革也推进了业务形态的变化,两者相互作用,呈螺旋上升的趋势。

目前,各大公司对Redis的使用已经处于相对平稳的状态。未来,Redis结合SSD等硬盘会成为下一次的爆发点吗?让我们拭目以待。

你知道吗?我喜欢你六年了——微博Redis定制化之路相关推荐

  1. 心眼者 pat basic 练习六十九 微博转发抽奖

    心得: 这一题很坑人,本以为它是从起始的下标开始,从N个人就中奖,如果这些人当中有中过奖的,就想下找 但实际上是每发现一个人中奖,就向下数N个人,如果这个人中过奖了,就向下找直到找到没中过奖的,然后再 ...

  2. redis+php微博,redis+php实现微博(三)微博列表功能详解

    本文实例讲述了redis+php实现微博列表功能.分享给大家供大家参考,具体如下: 个人主页显示微博列表(自己及关注人的微博列表) /*获取最新的50微博信息列表,列出自己发布的微博及我关注用户的微博 ...

  3. Python数据可视化第六节(坐标轴的定制)

    6.1 坐标轴概述 在绘制图表的过程中,marplotlib会根据所终園表的类形洪定是否使用坐标系,或者显示哪种类型的坐标系.例如,饼图无坐标系,雷达劉需使用板坐标系,折线園雷使用直魚璺船系等.其中, ...

  4. 猿创征文|六年一日,我的焚膏继晷之路

    猿创征文|我在Python领域的焚膏继晷之路 一.自我介绍 二.我和师父的机缘 三.拜师 or 闹剧? 四.我在CSDN的收获 五.关于我的学习 六.我的憧憬 一.自我介绍 大家好,我是 热爱科技的刘 ...

  5. 新浪企业版微博的商业​化拓展

    从"凡客体"的火爆,到"转发抽奖"的持续高温,即使应用到商业,微博也逐渐显现出电子商务的巨大空间. 今年6月,新浪企业版微博上线,微博商业化的氛围更加浓厚,据行 ...

  6. Spark(六):SparkSQLAndDataFrames对结构化数据集与非结构化数据的处理

    为什么80%的码农都做不了架构师?>>>    一:简单了解SparkSQL. Spark SQL 是结构化的数据处理一个Spark模块.与基本的Spark RDD API不同,Sp ...

  7. docker安装redis提示没有日记写入权限_Docker 学习笔记(第六集:使用 Dockerfile 定制镜像)...

    ethan 读完需要 11分钟 速读仅需 4 分钟 / 使用 Dockerfile 定制镜像 / 什么是 Dockerfile 呢? Dockerfile 是一个文本文档,其中包含用户可以在命令行上调 ...

  8. SpringBoot(六):SpringBoot整合Redis

    From: https://blog.csdn.net/plei_yue/article/details/79362372 前言 在本篇文章中将SpringBoot整合Redis,使用的是RedisT ...

  9. 第一百三十六期:详细讲解 Redis 的两种安装部署方式

    Redis 是一款比较常用的 NoSQL 数据库,我们通常使用 Redis 来做缓存,这是一篇关于 Redis 安装的文章,所以不会涉及到 Redis 的高级特性和使用场景,Redis 能够兼容绝大部 ...

  10. Redis(六)Java连接Redis

    在java的体系下,有三个常用的Redis的客户端:jedis.Redisson和Lettuce. Redis的客户端: Jedis:其API提高了比较全面的Redis命令的支持,暴露了Redis比较 ...

最新文章

  1. Web前端css知识点概括
  2. python列表解析
  3. 【Android工具】最新测试谷歌play耗电情况,各种品牌安装谷歌play方法,GooglePlay...
  4. php修改html,关于html:用PHP设置innerHTML?
  5. 编程方法学13:字符串处理
  6. visual c++ build tools的安装与使用
  7. ZooKeeper的原理(转)
  8. matplotlib常用函数(更新中)
  9. Java讲课笔记31:JDBC入门
  10. 几种程序的反汇编代码入口特征
  11. 超详细的Redis入门教程
  12.  Windows socket之IO完成端口(IOCP)模型开发
  13. Spring Boot项目CSRF (跨站请求伪造)攻击演示与防御
  14. 在dw中 新建html快捷键,了解 Dreamweaver 中的默认键盘快捷键以及如何自定义键盘快捷键...
  15. Python字符串的‘ ’,“ ”,''' '''
  16. rimraf与windows的rmdir简单使用命令方法
  17. 基于树莓派3b+学习视觉slam
  18. Ubuntu18.04系统(优化工具+搜狗输入法+wine+微信+拨号上网)
  19. MAC双系统U盘安装方法
  20. 一百个最有用的网站地址

热门文章

  1. 【建议收藏】 11个适合程序员逛的在线社区
  2. 现在有哪些好用的程序员学习交流的网站或者app?
  3. appium自动化测试
  4. android app 检测是否开启了开发者模式
  5. 为什么很多开发都要转测试....详谈....
  6. python控制电脑休眠唤醒键_使用Python实现Wake On Lan远程开机功能
  7. 进阶篇|选购手游联运系统的注意事项有哪些?
  8. WinSock IO模型五: 完成端口
  9. 简单了解一下电商系统中的SPU、SKU、ID,它们都是什么意思,三者又有什么区别和联系呢?
  10. iOS-AppStore上线被拒的各种理由...