1 Redis Cluster简单介绍
Redis Cluster就是Redis集群,为什么会有Redis Cluster呢?
首先说Redis就是远程字典服务,也就是我们常用的分布式缓存中间件,它的本质就是NoSQL数据库。我们都知道数据库是用来存储数据的,Redis还是在内存中的数据库,单台机器的内存是有限的,所以说Redis集群是为了扩展单节点Redis的存储能力。
Redis Cluster 是不保证Redis高可用的,保证Redis高可用的是主从复制加哨兵模式。
虽说Redis Cluster不能保证Redis的高可用,但是可以通过分区来提供一定程度的可用性。在生产环境中,当某个节点宕机或者不可达的情况下可以继续处理命令。
Redis Cluster的优势:
- 自动分割数据到不同的节点上。
- 整个集群的部分节点失败或者不可达的情况下能够继续处理命令。
2 Redis Cluster 哈希槽的应用
Redis Cluster并没有使用一致性hash,而是引入了 哈希槽的概念
Redis 集群有16384个哈希槽,每个key通过CRC16校验后对16384取模来决定放置哪个槽。集群的每个节点负责一部分hash槽,举个例子,比如当前集群有3个节点,那么节点 A 包含 0 到 5500号哈希槽,节点 B 包含5501 到 11000 号哈希槽,节点 C 包含11001 到 16384号哈希槽。
那么使用哈希槽有什么优势呢?
那就是扩缩容,我们使用哈希槽时,增加减少Redis节点就会很方便,如果我们想要新添加个节点D, 我们只需要从之前的节点分部分哈希槽到节点D上。 如果我想移除某个节点,只需要将该节点中的哈希槽移到另外两个节点上,然后将该节点从集群中移除即可.。
从一个节点将哈希槽移动到另一个节点并不会停止服务,所以无论添加或是删除节点都不会造成集群的不可用,这样就实现了动态扩缩容。
小知识:为什么Redis中哈希槽的个数是16384?
理论上CRC16算法可以得到2的16次方个数值,其数值范围在0-65535之间,取模运算key的时候,应该是crc16(key)%65535,但是却设计为crc16(key)%16384,原因是作者在设计的时候做了空间上的权衡,觉得节点最多不可能超过1000个,同时为了保证节点之间通信效率,所以采用了2^14。
3 一致性哈希是什么?
要想知道一致性哈希是什么,我们就得首先了解一下哈希,哈希就是哈希算法。
哈希算法最重要的特点就是:
- 相同的输入一定得到相同的输出;
- 不同的输入大概率得到不同的输出。
我们一般吧不同的输入得到相同输出,称为哈希碰撞。
小知识1: 哈希碰撞是否能够避免呢?
不能,哈希碰撞是一定会出现的,因为输出的字节长度是固定的,但输入的数据长度是不固定的,有无数种输入。哈希算法是把一个无限的输入集合映射到一个有限的输出集合,必然会产生碰撞。
小知识2:是否能够直接使用哈希确定key存放在哪个节点呢?
当有三台机器时我们使用hash(key) % 3
如果机器数不变是可以的,但是如果需要增加机器就完犊子了,假设加一台机器算法变为Hash(key) % 4,原本Hash(key)是4的是放在机器1的,现在变为了机器0,这样就会引起大量的缓存穿透,造成雪崩。
这也就是说,为什么我们在有了哈希算法,还得再搞出个一致性哈希算法的原因。
1997年,麻省理工学院的 Karger 等人提出了一致性哈希算法,为的就是解决分布式缓存的问题。
一致性hash是一个0到2的32次方的闭合环型结构,占用4个字节,拥有2的32次方个桶空间,每个桶空间可以存储很多数据。
一致性哈希是采用的是如下步骤:
- 对节点进行hash,通常使用其节点的ip或者是具有唯一标示的数据进行hash(ip),将其值分布在这个闭合圆上。
- 将存储的key进行hash(key),然后将其值要分布在这个闭合圆上。
- 从hash(key)在圆上映射的位置开始顺时针方向找到的一个节点即为存储key的节点。如果到圆上的0处都未找到节点,那么0位置后的顺时针方向的第一个节点就是key的存储节点。
添加节点,如果现在节点A和节点C中间增加一个节点D,那么在节点A和节点C之间的这些数据要存储的节点就会有所变化。删除节点就会把当前节点所有数据加到它的下一个节点上。这样会导致下一个节点使用率暴增,可能会导致挂掉,如果下一个节点挂掉,下下个节点将会承受更大的压力,最终导致集群雪崩。
4 哈希槽和一致性哈希对比
了解了一致性哈希,想必大家也就知道了Redis为什么会放弃掉一致性哈希而使用哈希槽了吧,下面我们在简单总结一下。
- 一致性哈希的节点分布基于圆环,无法很好的手动设置数据分布,比如有些节点的硬件差,希望少存一点数据,这种很难操作。而哈希槽可以很灵活的配置每个节点占用哈希槽的数量
- 一致性哈希的某个节点宕机或者掉线后,当该机器上原本缓存的数据被请求时,会从数据源重新获取数据,并将数据添加到失效机器后面的机器,这个过程被称为 "缓存抖动" ,而使用哈希槽的节点宕机,会导致一定范围内的槽不可用,只能通过主从复制加哨兵模式保证高可用。
- 真是基于一致性哈希的特点,当某台机器宕机时,极易引起雪崩,如上述介绍中删除节点。
- Redis Cluster的槽位空间是可以用户手动自定义分配的,类似于 windows 盘分区的概念,可以手动控制大小。
- 相对于哈希槽,一致性哈希算法更复杂
正是基于这些特点,Redis取舍后选择了哈希槽。