数据部分
redis cluster采用哈希分区规则,具体为虚拟槽分区,使用分散度好的哈希函数分到一个大范围的整数,每个节点负责一定数量的槽。slot=CRC16(key)&16383
特点:解耦数据和节点之间的关系;节点自身维护槽的映射关系,不需要客户端和代理服务维护槽分区元数据;支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景;
限制:1)只支持相同槽的key执行批量读写
2)分布在多个节点上的key无法使用事务
3)不能将hash、list映射到不同的节点
4)只有db0
5)主从结构只有1层
搭建集群
1)准备节点
划分为conf、data、log三个目录,至少6个节点组成集群,配置开启集群模式,设置超时时间和集群内配置文件
2)节点握手
客户端使用meet命令让其他节点加入到集群中
3)分配槽
-h ip -p port cluster addslots {0...xxx}分配槽
每个分配了槽的节点需要具有从节点,从节点使用cluster replicate {nodeId}配置主节点
可使用使用redis-trib.rb搭建集群(相比来说自动化了主从节点和槽分配步骤)
节点通信
redis 集群采用P2P的Gossip协议,节点间不断更换信息。
消息通信模式包括:meet(通知新节点加入,1-1)、ping(高频交换信息,1-多)、pong(回应前两种,1对多)、fail(将某个节点下线信息广播)
通信节点选择:选择5个最近没通信的节点,如果太久没受到pong,则立刻向该节点发送;消息体开销和集群数量有关,并不是越多节点越好
集群伸缩
不影响对外服务的期刊下,可以为集群添加节点进行扩容也可以下线部分节点。
添加节点:原每个节点把一部分槽和数据迁移到新的节点
扩容集群
- 准备新节点
- meet加入集群(使用工具对新加入节点进行检查,包括已经加入其他集群或包含数据)
- 迁移槽和数据
- 槽迁移计划
- 迁移数据
1)分别准备让目标节点准备导入槽数据和源节点准备准备迁出槽数据
2)源节点循环执行命令,获取x个属于槽的键
3)获取上一步键的数据
- 循环获取键和键的数据
- 通知槽分配给目标节点(发送给所有主节点更新被迁移的槽指向新节点)
- 添加从节点
请求路由
- 如果请求槽是该节点,则直接返回,否则返回moved来重定向,通过客户端再次发起请求
redis io优化:使用{}包含的内容hash_tag,使具备相同的slot mget user:{10086}:friends user:{100086}:videos 上面两个键具有相同的槽 - 槽节点查找,有开销额外的io开销,采用smart客户端
smart客户端:在内部维护slot-node的映射,为每个节点创建连接池,执行键命令
执行键命令流程如下:
1)计算slot并根据slots缓存获取目标节点连接,发送命令
2)if 出现错误 使用随机连接重新执行键命令,重试次数-1
3)捕获重定向错误,更新slots缓存
4)重复1~3,直到成功,当次数<=0时抛出最大重定向异常
当连接失败时,可能1、socket错误;2、lua脚本或命令超时;3、连接池获取对象超时
当故障转移时,会发生集群槽风暴,现象:抛出最大重定向异常;节点操作异常导致频繁更新槽缓存;频繁更新本地槽缓存
以前是Jedis+JedisPool组合。随着Spring Boot2.x的到来,支持的组件越来越丰富,也越来越成熟,其中对Redis的支持不仅仅是丰富了它的API,更是替换掉底层Jedis的依赖,取而代之换成了Lettuce高级Redis客户端,用于多线程安全同步,异步和响应使用。Lettuce和Jedis的都是连接Redis Server的客户端程序。Jedis在实现上是直连redis server,多线程环境下非线程安全,除非使用连接池JedisPool,为每个Jedis实例增加物理连接。Lettuce基于Netty的连接实例(StatefulRedisConnection),可以在多个线程间并发访问,且线程安全,满足多线程环境下的并发访问,同时它是可伸缩的设计,一个连接实例不够的情况也可以按需增加连接实例。
故障转移
类似于redis 哨兵的主客观下线(只有主节点来发现故障和决策)
故障恢复:1.从节点资格检查2.准备选举时间(从节点根据偏移量来作为优先级)3.发起选举(更新配置纪元、广播选举小心)4、投票选举,其他主节点来投票5、替换主节点
集群运维
集群完整性:设置cluster-require-full-coverage为no,使得未指标节点的槽不会影响其他节点。
带宽消耗:消息发送频率(cluster-node-timeout)、消息数据量、节点规模、
1)满足业务的情况下避免大集群。根据业务拆分使用多套集群
2)适当降低消息发送频率
3)避免集中部署
发布订阅广播问题:集群内会对publish数据在所有节点广播一次,使用哨兵结构用于广播功能。
数据倾斜:1、节点和槽分配严重不均2、槽对应键数量差异过大3、集合对象包含大量元素4、内存相关配置不一致
2、请求倾斜:1、合理设置键,大集合对象作拆分或用hmget规避全读取2、不要使用热键作为hash_tag,避免映射到同一槽3)对于一致性要求不高的场景,客户端使用本地缓存
集群读写分离
1、配置为只读 2、读写分离成本较高,更适合直接拓展主节点数量(特殊场景:降低网络延迟,故障转移时长过大,给从节点保证读操作可用)
手动故障转移场景:1、主节点迁移2、强制故障转移
数据迁移
单机=》集群 使用工具
标签:10,redis,集群,使用,数据,节点,客户端 From: https://www.cnblogs.com/bluebubbleyhbgsj/p/18306261