redis夺命连环问11--集群模式工作原理能说一下么?数据倾斜咋整?

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 消息超时导致集群节点产生大量的心跳消息。

解决调整设置集群节点故障判定时间(cluster-node-timeout),避免过多的心跳消息挤占集群带宽,但也不能调太大哈。


在集群模式下,redis 的 key 是如何寻址的?分布式寻址(数据分布方案)都有哪些算法?

  • 1.节点取余分区方案
    使用特定的数据(Redis的健或用户ID),根据节点数量N使用公式计算哈希值:hash(key)%N,决定数据映射到某一节点。
    优点:简单,配合预分区的方式,提前根据数据量规划好分区数,能保证支撑未来一段时间的数据量。
    缺点:当节点数量变化时,数据节点映射关系需要重新计算导致数据的重新迁移。
    解决方案翻倍扩容可以使数据迁移从80%降到50%
    在这里插入图片描述
    在这里插入图片描述
  • 2.一致性哈希分区方案
  • 3.虚拟槽分区方案(Redis Cluster采用此方案)

上面这俩看旁边两题有解释了。。。


了解一致性 hash 算法吗?

一致性哈希分区方案
实现思路:为系统的每个节点分配一个token,范围在0 ~ 2^{32} ,这些token构成一个哈希环,数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该哈希值的token节点。
在这里插入图片描述
优点:加入和删除节点只影响哈希环中相邻的节点。
缺点

  • 加减节点会造成哈希环中部分数据无法命中。虽然没节点取余那么严重一般。
  • 不适合少量数据节点的分布式方案;

如何防止hash环偏斜呢?

虚拟节点
“虚拟节点”是“实际节点”(实际的物理服务器)在hash环上的复制品,一个实际节点可以对应多个虚拟节点。
在这里插入图片描述


Redis集群如何选择数据库?

Redis集群目前无法做数据库选择,默认在0数据库。

Redis集群最大节点个数是多少?

16384个

Redis集群会有写操作丢失吗?为什么?

Redis并不能保证数据的强一致性,这意味这在实际中集群在特定的条件下可能会丢失写操作。

为什么要做Redis分区?

分区可以让Redis管理更大的内存,Redis将可以使用所有机器的内存。如果没有分区,你最多只能使用一台机器的内存。分区使Redis的计算能力通过简单地增加计算机得到成倍提升,Redis的网络带宽也会随着计算机和网卡的增加而成倍增长。

你知道有哪些Redis分区实现方案?

  • 客户端分区:客户端决定去哪个节点写数据或者读数据。
  • 代理分区:客户端请求代理,代理决定去哪个节点写数据或者读数据。
  • 查询路由:客户端随机地请求任意一个redis实例,由Redis将请求转发给正确的Redis节点。
  • Redis Cluster实现了一种混合形式的查询路由,但并不是直接将请求从一个redis节点转发到另一个redis节点,而是在客户端的帮助下直接redirected到正确的redis节点。

Redis分区有什么缺点?

  • key批量操作支持有限。对于映射为不同slot值的key由于执行mset、mget等操作可能存在于多个节点上而不被支持。
  • key事务操作支持有限。多个key分布在不同节点上时无法使用事务功能。
  • key作为数据分区的最小粒度,不能将一个大的键值对象如hash、list等映射到不同的节点
  • 不支持多数据库空间。单机下Redis可以支持16个数据库,集群模式下只能使用一个数据库空间,即db0。
  • 复制结构只支持一层,从节点只能复制主节点,不支持嵌套树状复制结构。
  • 数据处理非常复杂,例如为了备份必须从不同的Redis实例和主机同时收集RDB / AOF文件。
  • 分区时动态扩容或缩容可能非常复杂。Redis集群在运行时增加或者删除Redis节点,能做到最大程度对用户透明地数据再平衡,但其他一些客户端分区或者代理分区方法则不支持这种特性。然而,有一种预分片的技术也可以较好的解决这个问题。

介绍下Redis Cluster

前言:Redis 的哨兵模式基本可以实现高可用,读写分离 ,但是每台 Redis 服务器都存储相同的数据很浪费内存,所以在 Redis3.0 上加入了 Cluster 集群模式实现分布式存储,对数据进行分片,每台 Redis 节点上存储不同的内容。
解决了Redis分布式方面的需求,比如,当遇到单机内存,并发和流量等瓶颈的时候,Redis Cluster能起到很好的负载均衡的目的。

Redis Cluster集群节点最小配置6个节点以上(3主3从),其中主节点提供读写操作,从节点作为备用节点,不提供请求,只作为故障转移使用。

Redis Cluster采用虚拟槽分区,所有的键根据哈希函数映射到0~16383个整数槽内,每个节点负责维护一部分槽以及槽所印映射的键值数据。

优点

  • 无中心架构;
  • 数据按照slot存储分布在多个节点,节点间数据共享,可动态调整数据分布;
  • 可扩展性:可线性扩展到1000多个节点,节点可动态添加或删除;
  • 高可用性:部分节点不可用时,集群仍可用。通过增加Slave做standby数据副本,能够实现故障自动failover,节点之间通过gossip协议交换状态信息,用投票机制完成Slave到Master的角色提升;
  • 降低运维成本,提高系统的扩展性和可用性。

缺点

  • 数据通过异步复制,不保证数据的强一致性。
  • 多个业务使用同一套集群时,无法根据统计区分冷热数据,资源隔离性较差,容易出现相互影响的情况。
  • 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产生的场景。

如何应对数据倾斜?

数据倾斜有两类:

  • 数据量倾斜:在某些情况下,实例上的数据分布不均衡,某个实例上的数据特别多。

  • 数据访问倾斜:虽然每个集群实例上的数据量相差不大,但是某个实例上的数据是热点数据,被访问得非常频繁。

数据量倾斜的成因和应对方法
在这里插入图片描述
bigkey 导致倾斜
(bigkey 的 value 值很大(String 类型)或者保存了大量集合元素(集合类型)
bigkey 的操作一般都会造成实例 IO 线程阻塞,如果 bigkey 的访问量比较大,就会影响到这个实例上的其它请求被处理的速度。

解决

  • 在业务层生成数据时,要尽量避免把过多的数据保存在同一个键值对中。
  • 如果 bigkey 正好是集合类型,我们还有一个方法,就是把 bigkey 拆分成很多个小的集合类型数据,分散保存在不同的实例上。

Slot 分配不均衡导致倾斜
解决
运维规范,在分配之前,避免把过多的 Slot 分配到同一个实例。如果是已经分配好 Slot 的集群,我们可以先查看 Slot 和实例的具体分配关系,从而判断是否有过多的 Slot 集中到了同一个实例。如果有的话,就将部分 Slot 迁移到其它实例,从而避免数据倾斜。

Hash Tag 导致倾斜
Hash Tag 是指加在键值对 key 中的一对花括号{}。这对括号会把 key 的一部分括起来,客户端在计算 key 的 CRC16 值时,只对 Hash Tag 花括号中的 key 内容进行计算。

不同 key 的 Hash Tag 内容都是一样的,那么,这些 key 对应的数据会被映射到同一个 Slot 中,同时会被分配到同一个实例上。
(Hash Tag 一般用在什么场景呢?
在 Redis Cluster 和 Codis 中,支持事务操作和范围查询。因为 Redis Cluster 和 Codis 本身并不支持跨实例的事务操作和范围查询,当业务应用有这些需求时,就只能先把这些数据读取到业务层进行事务处理,或者是逐个查询每个实例,得到范围查询的结果。
使用 Hash Tag 把要执行事务操作或是范围查询的数据映射到同一个实例上,这样就能很轻松地实现事务或范围查询了。)

解决
不使用 Hash Tag 进行数据切片。事务和范围查询放在客户端来执行。

数据访问倾斜
发生数据访问倾斜的根本原因,就是实例上存在热点数据

在这里插入图片描述
解决

  • 热点数据以服务读操作为主,在这种情况下,我们可以采用热点数据多副本的方法来应对。

具体做法:把热点数据复制多份,在每一个数据副本的 key 中增加一个随机前缀,让它和其它副本数据不会被映射到同一个 Slot 中。这样一来,热点数据既有多个副本可以同时服务请求,同时,这些副本数据的 key 又不一样,会被映射到不同的 Slot 中。在给这些 Slot 分配实例时,我们也要注意把它们分配到不同的实例上,那么,热点数据的访问压力就被分散到不同的实例上了。

  • 热点数据是有读有写的话,就不适合采用多副本方法了,因为要保证多副本间的数据一致性,会带来额外的开销。对于有读有写的热点数据,就要给实例本身增加资源了。

总结
在这里插入图片描述

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值