知乎Redis的演进之路:从单机到2000万QPS的挑战

本文深入探讨了知乎Redis系统的演进历程,从单机到集群,面临2000万QPS的挑战。文章详细介绍了Sentinel高可用方案、客户端分片、Twemproxy集群的使用和优化,以及如何解决Twemproxy的CPU计算能力限制。在评估官方Redis集群方案后,知乎选择了Twemproxy,以应对业务增长和稳定性需求。
摘要由CSDN通过智能技术生成

按:对于业务技术而言,技术是什么?深刻理解业务的本质,掌握技术底层原理、并合理应用。中间件就是其中支点,作为中间件一员的Redis产品,是如何演进的?与业务系统有何不同?

本文来自知乎陈鹏老师的精彩分享,作者是该系统的负责人,文章深入介绍了知乎Redis系统的方方面面,作为后端程序员值得仔细研究。

 

背景

知乎作为知名中文知识内容平台,每日处理的访问量巨大,如何更好的承载这样巨大的访问量,同时提供稳定低时延的服务保证,是知乎技术平台同学需要面对的一大挑战。

 

知乎存储平台团队基于开源Redis 组件打造的 Redis 平台管理系统,经过不断的研发迭代,目前已经形成了一整套完整自动化运维服务体系,提供一键部署集群,一键自动扩缩容, Redis 超细粒度监控,旁路流量分析等辅助功能。

 

目前,Redis 在知乎规模如下:

● 机器内存总量约70TB,实际使用内存约40TB;

● 平均每秒处理约1500万次请求,峰值每秒约2000万次请求;

● 每天处理约1万亿余次请求;

● 单集群每秒处理最高每秒约400万次请求;

● 集群实例与单机实例总共约800个;

● 实际运行约16000个Redis 实例;

● Redis 使用官方3.0.7版本,少部分实例采用4.0.11版本。

 

Redis at Zhihu

根据业务的需求,我们将实例区分为单机(Standalone)和集群(Cluster)两种类型,单机实例通常用于容量与性能要求不高的小型存储,而集群则用来应对对性能和容量要求较高的场景。

 

单机(Standalone)

对于单机实例,我们采用原生主从(Master-Slave)模式实现高可用,常规模式下对外仅暴露 Master 节点。由于使用原生 Redis,所以单机实例支持所有 Redis 指令。

 

对于单机实例,我们使用Redis 自带的哨兵(Sentinel)集群对实例进行状态监控与 Failover。Sentinel 是 Redis 自带的高可用组件,将 Redis 注册到由多个 Sentinel 组成的 Sentinel 集群后,Sentinel 会对 Redis 实例进行健康检查,当 Redis 发生故障后,Sentinel 会通过 Gossip 协议进行故障检测,确认宕机后会通过一个简化的 Raft 协议来提升 Slave 成为新的 Master。

 

通常情况我们仅使用1 个 Slave 节点进行冷备,如果有读写分离请求,可以建立多个Read only slave 来进行读写分离。

如图所示,通过向Sentinel 集群注册 Master 节点实现实例的高可用,当提交 Master 实例的连接信息后,Sentinel 会主动探测所有的 Slave 实例并建立连接,定期检查健康状态。客户端通过多种资源发现策略如简单的 DNS 发现 Master 节点,将来有计划迁移到如 Consul 或 etcd 等资源发现组件 。

 

当Master 节点发生宕机时,Sentinel 集群会提升 Slave 节点为新的 Master,同时在自身的 pubsub channel +switch-master 广播切换的消息,具体消息格式为:

 

switch-master <master name> <oldip> <oldport> <newip> <newport>

 

watcher 监听到消息后,会去主动更新资源发现策略,将客户端连接指向新的 Master 节点,完成 Failover,具体 Failover 切换过程详见 Redis 官方文档。

Redis Sentinel Documentation [1]

 

实际使用中需要注意以下几点:

● 只读Slave 节点可以按照需求设置 slave-priority 参数为0,防止故障切换时选择了只读节点而不是热备 Slave 节点;

● Sentinel 进行故障切换后会执行 CONFIG REWRITE 命令将SLAVEOF 配置落地,如果 Redis 配置中禁用了 CONFIG 命令,切换时会发生错误,可以通过修改 Sentinel 代码来替换 CONFIG 命令;

● Sentinel Group 监控的节点不宜过多,实测超过 500 个切换过程偶尔会进入 TILT 模式,导致Sentinel 工作不正常,推荐部署多个 Sentinel 集群并保证每个集群监控的实例数量小于 300 个;

● Master 节点应与 Slave 节点跨机器部署,有能力的使用方可以跨机架部署,不推荐跨机房部署 Redis 主从实例;

● Sentinel 切换功能主要依赖 down-after-milliseconds 和failover-timeout 两个参数,down-after-milliseconds 决定了Sentinel 判断 Redis 节点宕机的超时,知乎使用 30000 作为阈值。而 failover-timeout 则决定了两次切换之间的最短等待时间,如果对于切换成功率要求较高,可以适当缩短failover-timeout 到秒级保证切换成功,具体详见Redis 官方文档[2];

● 单机网络故障等同于机器宕机,但如果机房全网发生大规模故障会造成主从多次切换,此时资源发现服务可能更新不够及时,需要人工介入。

 

集群(Cluster)

当实例需要的容量超过20G 或要求的吞吐量超过 20万请求每秒时,我们会使用集群(Cluster)实例来承担流量。集群是通过中间件(客户端或中间代理等)将流量分散到多个 Redis 实例上的解决方案。

 

知乎的Redis 集群方案经历了两个阶段:客户端分片与 Twemproxy 代理

 

客户端分片(before 2015)

早期知乎使用redis-shard 进行客户端分片,redis-shard 库内部实现了 CRC32、MD5、SHA1三种哈希算法,支持绝大部分Redis 命令。使用者只需把 redis-shard 当成原生客户端使用即可,无需关注底层分片。

评论 6
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值