大厂们的 redis 集群方案

摘要:
然后根据结果判断是否需要进一步访问目标节点;读取请求在访问src节点后直接返回;return访问的密钥已迁移(或不存在):读/写请求访问src节点并继续访问目标节点以处理阿里云AparaCache。独立版本已经开源(开源版本不包括插槽和其他实现)。这种基于时隙的迁移方案更快;槽的映射表保存在存储器中;scala组件向dst实例发送命令,通知它将接受插槽;

redis 集群方案主要有两类,一是使用类 codis 的架构,按组划分,实例之间互相独立;
另一套是基于官方的 redis cluster 的方案;下面分别聊聊这两种方案;

类 codis 架构

大厂们的 redis 集群方案第1张

这套架构的特点:

  • 分片算法:基于 slot hash桶;
  • 分片实例之间相互独立,每组 一个master 实例和多个slave;
  • 路由信息存放到第三方存储组件,如 zookeeper 或etcd
  • 旁路组件探活

使用这套方案的公司:
阿里云: ApsaraCache, RedisLabs、京东、百度等

codis

slots 方案:划分了 1024个slot, slots 信息在 proxy层感知; redis 进程中维护本实例上的所有key的一个slot map;

迁移过程中的读写冲突处理:
最小迁移单位为key;
访问逻辑都是先访问 src 节点,再根据结果判断是否需要进一步访问 target 节点;

  • 访问的 key 还未被迁移:读写请求访问 src 节点,处理后访问:
  • 访问的 key 正在迁移:读请求访问 src 节点后直接返回;写请求无法处理,返回 retry
  • 访问的 key 已被迁移(或不存在):读写请求访问 src 节点,收到 moved 回复,继续访问 target 节点处理

阿里云

AparaCache 的单机版已开源(开源版本中不包含slot等实现),集群方案细节未知;ApsaraCache

百度 BDRP 2.0

主要组件:
proxy,基于twemproxy 改造,实现了动态路由表;
redis内核: 基于2.x 实现的slots 方案;
metaserver:基于redis实现,包含的功能:拓扑信息的存储 & 探活;
最多支持1000个节点;

slot 方案:
redis 内核中对db划分,做了16384个db; 每个请求到来,首先做db选择;

数据迁移实现:
数据迁移的时候,最小迁移单位是slot,迁移中整个slot 处于阻塞状态,只支持读请求,不支持写请求;
对比 官方 redis cluster/ codis 的按key粒度进行迁移的方案:按key迁移对用户请求更为友好,但迁移速度较慢;这个按slot进行迁移的方案速度更快;

京东

主要组件:
proxy: 自主实现,基于 golang 开发;
redis内核:基于 redis 2.8
configServer(cfs)组件:配置信息存放;
scala组件:用于触发部署、新建、扩容等请求;
mysql:最终所有的元信息及配置的存储;
sentinal(golang实现):哨兵,用于监控proxy和redis实例,redis实例失败后触发切换;

slot 方案实现:
在内存中维护了slots的map映射表;

数据迁移:
基于 slots 粒度进行迁移;
scala组件向dst实例发送命令告知会接受某个slot;
dst 向 src 发送命令请求迁移,src开启一个线程来做数据的dump,将这个slot的数据整块dump发送到dst(未加锁,只读操作)
写请求会开辟一块缓冲区,所有的写请求除了写原有数据区域,同时双写到缓冲区中。
当一个slot迁移完成后,把这个缓冲区的数据都传到dst,当缓冲区为空时,更改本分片slot规则,不再拥有该slot,后续再请求这个slot的key返回moved;
上层proxy会保存两份路由表,当该slot 请求目标实例得到 move 结果后,更新拓扑;

跨机房:跨机房使用主从部署结构;没有多活,异地机房作为slave;

基于官方 redis cluster 的方案

大厂们的 redis 集群方案第2张

和上一套方案比,所有功能都集成在 redis cluster 中,路由分片、拓扑信息的存储、探活都在redis cluster中实现;各实例间通过 gossip 通信;这样的好处是简单,依赖的组件少,应对400个节点以内的场景没有问题(按单实例8w read qps来计算,能够支持 200 * 8 = 1600w 的读多写少的场景);但当需要支持更大的规模时,由于使用 gossip协议导致协议之间的通信消耗太大,redis cluster 不再合适;

使用这套方案的有:AWS, 百度贴吧

官方 redis cluster

数据迁移过程:
基于 key粒度的数据迁移;
迁移过程的读写冲突处理:
从A 迁移到 B;

  • 访问的 key 所属slot 不在节点 A 上时,返回 MOVED 转向,client 再次请求B;
  • 访问的 key 所属 slot 在节点 A 上,但 key 不在 A上, 返回 ASK 转向,client再次请求B;
  • 访问的 key 所属slot 在A上,且key在 A上,直接处理;(同步迁移场景:该 key正在迁移,则阻塞)

AWS ElasticCache

ElasticCache 支持主从和集群版、支持读写分离;
集群版用的是开源的Redis Cluster,未做深度定制;

百度贴吧的ksarch-saas:

基于redis cluster + twemproxy 实现;后被 BDRP 吞并;
twemproxy 实现了 smart client 功能;使用 redis cluster后还加一层 proxy的好处:

  1. 对client友好,不需要client都升级为smart client;(否则,所有语言client 都需要支持一遍)
  2. 加一层proxy可以做更多平台策略;比如在proxy可做 大key、热key的监控、慢查询的请求监控、以及接入控制、请求过滤等;

即将发布的 redis 5.0 中有个 feature,作者计划给 redis cluster加一个proxy。

ksarch-saas 对 twemproxy的改造已开源:
https://github.com/ksarch-saas/r3proxy

免责声明:文章转载自《大厂们的 redis 集群方案》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇Java中生成唯一ID的方法文件夹上传组件webupload插件下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

七天开发进度(六)(微信小程序版(一))

1. 今天主要根据网上教程学习了微信小程序的代码结构,和代码编写-Tabbar配置, 学习了app.js的App和Page方法, 认识了view组件,button组件,input组件,但是还没怎么应用,还有如何进行首页的开发等等。 这是观看视频时这三种组件的演示 view演示  input演示 button演示 这是简单实现的一个页面,还不完善,明天...

vue element-ui 使用 el-scrollbar监听滚动条滚动事件,处理el-tabs滚动到顶部header吸顶效果

摘要:elememt-ui中使用el-scrollbar时监听scroll事件,处理el-tabs滚动到顶部时header部分吸顶效果 前言 网上关于el-scrollbar滚动事件监听的案例比较少,好不容易找到解决方法,记录一下,启发之处在这里,稍有改动 在vue中使用elememt-ui时,如果页面比较长需要滚动,我们想要优化浏览器侧边默认的滚动条该怎...

OC语言·笔记二

1. 属性(Property)和实例变量(instance variable) 1.1 当定义一个属性时,本质上是在干什么(编译器在帮我们干什么): 1) 生成实例变量用来保存属性的值 2) 生成访问器(setter和getter方法)用于修改和访问属性的值 1.2 实际开发中知道的事: 1) 只读属性:只能读取值,不能修改值。这种属性只生成getter方...

Java Swing 使用 java.awt 包中的 Desktop 类

介绍: 这个 Desktop 类是用于与各种桌面功能进行交互的。比如用一个 URL 来调用系统默认浏览器打开,具体看文档吧。 官方API 文档: https://docs.oracle.com/en/java/javase/14/docs/api/java.desktop/java/awt/Desktop.html 问:怎么用呢? 答: 下面是一个调用系统...

装配Bean

创建应用对象之间协作关系的行为通常被称为装配(wiring),这是依赖注入(DI)的本质。当描述bean如何进行装配时,Spring具有非常大的灵活性,它提供了三种主要的装配机制: 在XML中进行显式配置; 在Java中进行显式配置; 隐式的bean发现机制和自动装配 前两种都是属于显式的配置,最后一种是就是所谓的自动装配了。其实选择哪一种方案没有什么...

Nginx反向代理缓冲区优化

内容目录 proxy_buffering proxy_buffer_size proxy_buffers proxy_busy_buffers_size proxy_max_temp_file_size和proxy_temp_file_write_size 关于缓冲, 主要是合理设置缓冲区大小, 尽量避免缓冲到硬盘时的情况 如果一台代理服务器上面配置了...