redis夺命连环问11--集群模式工作原理能说一下么?集群模式下的key是如何寻址的?分布式寻址都有哪些算法?了解一致性hash算法吗?
作者:互联网
目录
- Redis集群模式的工作原理能说一下么?
- 盲目扩大集群规模,实例间的通信量也会增加,集群性能变慢,如何降低实例间的通信开销?
- 在集群模式下,redis 的 key 是如何寻址的?分布式寻址(数据分布方案)都有哪些算法?
- 了解一致性 hash 算法吗?
- Redis集群如何选择数据库?
- Redis集群最大节点个数是多少?
- Redis集群会有写操作丢失吗?为什么?
- 为什么要做Redis分区?
- 你知道有哪些Redis分区实现方案?
- Redis分区有什么缺点?
- 介绍下Redis Cluster
Redis集群模式的工作原理能说一下么?
首先谈数据分区规则
Redis Cluster数据分区采用哈希规则
再谈分区具体方案
Redis Cluster采用虚拟槽分区方案,
实现思路:Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽。
优点:
- 解耦数据和节点之间的关系,简化了节点扩容和收缩的难度;
- 节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据;
- 支持节点,槽,键之间的映射关系,用于数据路由、在线伸缩等场景。
(理解:hash slot让node的增加和移除很简单,增加一个master,就将其他master的hash slot移动部分过去,减少一个master,就将它的hash slot移动到其他master上去。每次增加或减少master节点都是对16384取模,而不是根据master数量,这样原本在老的master上的数据不会因master的新增或减少而找不到。并且增加或减少master时Redis cluster移动hash slot的成本是非常低的。)
缺点:也就是集群功能限制的地方:
- key批量操作支持有限。对于映射为不同slot值的key由于执行mset、mget等操作可能存在于多个节点上而不被支持。
- key事务操作支持有限。多个key分布在不同节点上时无法使用事务功能。
- key作为数据分区的最小粒度,不能将一个大的键值对象如hash、list等映射到不同的节点。
- 不支持多数据库空间。单机下Redis可以支持16个数据库,集群模式下只能使用一个数据库空间,即db0。
- 复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构。
最后谈实例通信机制
Redis Cluster 实例以 Gossip 协议进行通信的机制:
Gossip 协议:
- 一是,每个实例之间会按照一定的频率,从集群中随机挑选一些实例,把 PING 消息发送给挑选出来的实例,用来检测这些实例是否在线,并交换彼此的状态信息。PING 消息中封装了发送消息的实例自身的状态信息、部分其它实例的状态信息,以及 Slot 映射表。
- 二是,一个实例在接收到 PING 消息后,会给发送 PING 消息的实例,发送一个 PONG 消息。PONG 消息包含的内容和 PING 消息一样。
Gossip 协议可以保证在一段时间后,集群中的每一个实例都能获得其它所有实例的状态信息。
盲目扩大集群规模,实例间的通信量也会增加,集群性能变慢,如何降低实例间的通信开销?
病因:集群中大规模的实例间心跳消息会挤占集群处理正常请求的带宽。有些实例可能因为网络拥塞导致无法及时收到 PONG 消息,每个实例在运行时会周期性地检测是否有这种情况发生,一旦发生,就会立即给这些 PONG 消息超时的实例发送心跳消息。集群规模越大,网络拥塞的概率就越高,相应的,PONG 消息超时的发生概率就越高,这就会导致集群中有大量的心跳消息,影响集群服务正常请求。
解决:调整设置集群节点故障判定时间(cluster-node-timeout),避免过多的心跳消息挤占集群带宽,但也不能调太大哈。
在集群模式下,redis 的 key 是如何寻址的?分布式寻址(数据分布方案)都有哪些算法?
- 1.节点取余分区方案:
使用特定的数据(Redis的健或用户ID),根据节点数量N使用公式计算哈希值:hash(key)%N,决定数据映射到某一节点。
优点:简单,常用于数据库的分库分表规则,一般采用预分区的方式,提前根据数据量规划好分区数(eg划分为512或1024张表),保证可支撑未来一段时间的数据量,在根据负载情况将表迁移到其他数据库中。要求扩容时采用范培扩容,避免数据映射全部被打乱导致全量迁移的情况。
缺点:当节点数量变化时,即扩容或缩容节点时,数据节点映射关系需要重新计算,会导致数据的重新迁移。
解决方案:翻倍扩容可以使数据迁移从80%降到50%
- 2.一致性哈希分区方案
- 3.虚拟槽分区方案(Redis Cluster采用此方案)
上面这俩看旁边两题有解释了。。。
了解一致性 hash 算法吗?
一致性哈希分区方案
实现思路:为系统的每个节点分配一个token,范围一般在0 ~ 2^{32} ,这些toke构成一个哈希环,数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该哈希值的token节点。
优点:加入和删除节点只影响哈希环中相邻的节点。
缺点:
- 加减节点会造成哈希环中部分数据无法命中,所以应用于缓存场景是可以容忍的;
- 不适合少量数据节点的分布式方案;
- 普通一致性哈希分区在增减节点时需要增加一倍或减去一半节点才能保证数据和负载的均衡。
Redis集群如何选择数据库?
Redis集群目前无法做数据库选择,默认在0数据库。
Redis集群最大节点个数是多少?
16384个
Redis集群会有写操作丢失吗?为什么?
Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。
为什么要做Redis分区?
分区可以让Redis管理更大的内存,Redis将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。分区使Redis的计算能力通过简单地增加计算机得到成倍提升,Redis的网络带宽也会随着计算机和网卡的增加而成倍增长。
你知道有哪些Redis分区实现方案?
- 客户端分区就是在客户端就已经决定数据会被存储到哪个redis节点或者从哪个redis节点读取。大多数客户端已经实现了客户端分区。
- 代理分区 意味着客户端将请求发送给代理,然后代理决定去哪个节点写数据或者读数据。代理根据分区规则决定请求哪些Redis实例,然后根据Redis的响应结果返回给客户端。redis和memcached的一种代理实现就是Twemproxy
- 查询路由(Query routing) 的意思是客户端随机地请求任意一个redis实例,然后由Redis将请求转发给正确的Redis节点。Redis Cluster实现了一种混合形式的查询路由,但并不是直接将请求从一个redis节点转发到另一个redis节点,而是在客户端的帮助下直接redirected到正确的redis节点。
Redis分区有什么缺点?
- 涉及多个key的操作通常不会被支持。例如你不能对两个集合求交集,因为他们可能被存储到不同的Redis实例(实际上这种情况也有办法,但是不能直接使用交集指令)。
- 同时操作多个key,则不能使用Redis事务.
- 分区使用的粒度是key,不能使用一个非常长的排序key存储一个数据集(The partitioning granularity is the key, so it is not possible to shard a dataset with a single huge key like a very big sorted set)
- 当使用分区的时候,数据处理会非常复杂,例如为了备份你必须从不同的Redis实例和主机同时收集RDB / AOF文件。
- 分区时动态扩容或缩容可能非常复杂。Redis集群在运行时增加或者删除Redis节点,能做到最大程度对用户透明地数据再平衡,但其他一些客户端分区或者代理分区方法则不支持这种特性。然而,有一种预分片的技术也可以较好的解决这个问题。
介绍下Redis Cluster
前言:Redis 的哨兵模式基本已经可以实现高可用,读写分离 ,但是在这种模式下每台 Redis 服务器都存储相同的数据,很浪费内存,所以在 Redis3.0 上加入了 Cluster 集群模式,实现了 Redis 的分布式存储,对数据进行分片,也就是说每台 Redis 节点上存储不同的内容。
Redis Cluster是Redis分布式集群解决方案,主要解决Redis分布式方面的需求,比如,当遇到单机内存,并发和流量等瓶颈的时候,Redis Cluster能起到很好的负载均衡的目的。
Redis Cluster集群节点最小配置6个节点以上(3主3从),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。
Redis Cluster采用虚拟槽分区,所有的键根据哈希函数映射到0~16383个整数槽内,每个节点负责维护一部分槽以及槽所印映射的键值数据。
优点:
- 无中心架构;
- 数据按照slot存储分布在多个节点,节点间数据共享,可动态调整数据分布;
- 可扩展性:可线性扩展到1000多个节点,节点可动态添加或删除;
- 高可用性:部分节点不可用时,集群仍可用。通过增加Slave做standby数据副本,能够实现故障自动failover,节点之间通过gossip协议交换状态信息,用投票机制完成Slave到Master的角色提升;
- 降低运维成本,提高系统的扩展性和可用性。
缺点:
- Client实现复杂,驱动要求实现Smart Client,缓存slots mapping信息并及时更新,提高了开发难度,客户端的不成熟影响业务的稳定性。目前仅JedisCluster相对成熟,异常处理部分还不完善,比如常见的“max redirect exception”。
- 节点会因为某些原因发生阻塞(阻塞时间大于clutser-node-timeout),被判断下线,这种failover是没有必要的。
- 数据通过异步复制,不保证数据的强一致性。
- 多个业务使用同一套集群时,无法根据统计区分冷热数据,资源隔离性较差,容易出现相互影响的情况。
- Slave在集群中充当“冷备”,不能缓解读压力,当然可以通过SDK的合理设计来提高Slave资源的利用率。
- Key批量操作限制,如使用mset、mget目前只支持具有相同slot值的Key执行批量操作。对于映射为不同slot值的Key由于Keys不支持跨slot查询,所以执行mset、mget、sunion等操作支持不友好。
- Key事务操作支持有限,只支持多key在同一节点上的事务操作,当多个Key分布于不同的节点上时无法使用事务功能。
- Key作为数据分区的最小粒度,不能将一个很大的键值对象如hash、list等映射到不同的节点。不支持多数据库空间,单机下的Redis可以支持到16个数据库,集群模式下只能使用1个数据库空间,即db 0。
- 复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构。
- 避免产生hot-key,导致主库节点成为系统的短板。
- 避免产生big-key,导致网卡撑爆、慢查询等。
- 重试时间应该大于cluster-node-time时间。
- Redis Cluster不建议使用pipeline和multi-keys操作,减少max redirect产生的场景。
标签:实例,分区,Redis,算法,寻址,集群,key,节点 来源: https://blog.csdn.net/weixin_45785536/article/details/122799977