数据分布:
分布式数据库首先需要解决的是,把整个数据集按照分区规则映射到多个节点的问题,常见的分区规则有哈希分区和顺序分区。
哈希分区:
- 离散度好
- 数据分布业务无关
- 无法顺序访问
顺序分区:
- 离散度倾斜
- 数据分布业务相关
- 可以顺序访问
Redis Cluster 采用的是哈希分区:
常见的哈希分区方案:
- 节点取余
优点是简单,缺点是当节点数量变化时,数据节点映射关系需要重新计算,会导致数据迁移问题。 - 一致性哈希
优点是节点变化无数据迁移问题,缺点是①加减节点会导致哈希环中部分数据无法命中,②节点太少时,不适用(可用虚拟节点解决),③需要增减一倍或一半节点才能保证数据的负载均衡问题 - 虚拟槽
特点:
①解耦数据和节点之间的关系,简化节点扩容和收缩难度
②节点自身维护槽的映射关系
③支持节点、槽、键之间的映射查询
Redis集群的限制:
节点通信
分布式存储需要提供维护节点元数据信息的机制。常见的方式:集中式和P2P式。
元数据:节点负责那些数据,是否出现故障等状态信息。
Redis采用Gossip协议(P2P)通信,过程如下:
- 集群中每个节点会单独开辟一个TCP通道,用于节点之间通信
- 每个节点在固定周期内通过指定规则选几个节点发送ping消息
- 接收到ping消息的节点用pong消息作为响应
节点选择:
定时任务默认每1秒执行10次,每秒随机找出最久没有通信的节点发送ping消息。
集群伸缩
集群伸缩=槽和数据在节点之间的移动
集群扩容:
- 准备新节点
- 接入集群
- 迁移槽和数据
集群收缩:
- 下线节点是否有负责的槽,①如果有,把槽迁移到其他节点
- 当下线节点不再负责槽或本身是从节点时,通知集群内其他节点忘记该节点,所有节点忘记以后,就关闭该节点。
请求路由
集群模式下,Redis接收任何键相关命令时,首先计算键对应的槽,再根据槽找出对应的节点,如果不是当前节点,回复MOVED重定向错误,通知客户端(注意是客户端处理重定向转发)请求正确的节点。
Smart客户端:
Smart客户端通过在内部维护slot—node的映射关系,提高重定向转发带来的IO效率问题。MOVED重定向负责协助Smart客户端更新slot—node的映射。
潜在问题:
- 当集群规模很大时,客户端会维护非常多的连接并消耗更多的内存。
- Too many Cluster redirections 错误,节点宕机或请求超时,会触发随机重试,重试次数耗尽就会出现这个错误。
- JedisConnectionException错误的几种情况:①Jedis连接节点发送socket错误②所有命令读写超时③JedisPool连接池获取jedis对象超时(2.8.1以后抛另外的异常)
4.cluster slots风暴问题:升级到2.8.2以上防止这个问题。
ASK重定向和MOVED重定向的区别:ASK说明集群正在进行slot数据迁移,客户端不知道什么时候迁移完成,只能临时的重定向,客户端不会更新slots缓存。MOVED会更新slots缓存。
故障转移
主观下线:当cluster-node-timeout时间内某节点无法与另一个节点顺利完成ping消息通信时,则将该节点标记为主观下线状态。
客观下线:集群内多个节点都认为该节点不可用。