Redis分布式系统之数据分区算法
1、什么是Redis分布式系统
Redis分布式系统,官方称为Redis Cluster, Redis集群(这个集群和前面的主从复制集群不同,这个集群可以理解为是多个主从复制集群所组成的集群),其实是Redis3.0开始推出得分布式解决方案。可以很好地解决不同Redis节点存放不同数据,并将用户亲求方便地路由到不同Redis得问题。(下面讲到的节点本质都是在Redis分布式系统中的一个主从复制集群)
2、数据分区算法
分布式数据库系统会根据不同得数据分区算法,将数据分散储存到不同得数据库服务器节点上,每个节点管理着整个数据集合中得一个子集。
常见得的数据分区规则有俩大类:顺序分区与哈希分区。
2.1、顺序分区
顺序分区规则可以将数据根据某种顺序平均分配到不同的节点。不同的顺序方式,产生了不同的分区算法。例如,轮询分区算法、时间片论转分区算法、数据块分区算法、业务主题分区算法等等。由于这些算法都比较简单,就不具体介绍了,可以自己百度去了解了解。
2.1.1、轮询分区算法
**每产生一个数据,就依次分配到不同的节点。**该算法适合于数据问题不确定的场景。分配结果是,在数据量非常庞大的情况下,**每个节点中的数据是很平均的。**但是数据生产者与数据节点是要一直保持连接的(也就是说,每个数据节点都一直与外界数据生产者保持着连接)。
2.1.2、时间片轮转分区算法
**在某个固定长度的时间片内,产生的数据都会很配到一个节点上。**时间片结束,再产生的数据就会被分配到下一个节点。这些节点会被依次轮转分配数据。该算法可能会出现节点数据分配不平均的情况(这个很好理解,因为每个时间片内产生的数可能是不同的)。但是,它有一个明显的优点就是数据生产者与节点间的连接只需要占用当前正在使用的这个,其它连接在使用完毕之后就立即被释放掉了。(也就是说,无论何时,整个Redis分布式系统只有任意一个节点被数据生产者连接)
2.1.3、数据块分区算法
在整体数据总量确定的情况下,根据各个节点的储存能力,可以将连接的某一整块数据分配的某一个节点。
2.1.4、业务主题分区算法
数据可以根据不同的业务主题,分配到不同的节点。
2.2、哈希分区
哈希分区的规则是充分利用数据的哈希值来完成分配,对数据哈希值的不同使用方式产生了不同的哈希分区算法。哈希分区算法相对较复杂,这里详细介绍几种常见的哈希分区算法。
2.2.1、节点取模分区算法
该算法的前提是,每个节点都已经分配好了一个唯一的序号,对于N个节点的分布式系统,其序号范围为【0,N-1】。然后选取数据本身或可以代表数据特征的数据的一部分作为key,计算hash(key)与节点数量N的模,该计算结果即为该数据的存储节点的序号。
该算法最大的优点是简单,但是也存在比较严重的问题。如果分布式系统扩容或者缩容,已经存储过的数据需要根据新的节点数量N进行数据迁移,否则用户根据key无法找到原来的数据。生产中扩容一般采用翻倍扩容方式,以减少扩容时数据迁移的比例。
2.2.2、一致性哈希分区算法
一致性hash算法通过一个叫做一致性hash环的数据结构实现。这个环的起点是0,终点是2的32次方 - 1, 并起点与终点重合。环中间的整数按逆序/顺时针分布,所以这个环的整数分布范围是【0,2的32次方 - 1】。
2.2.3、模拟槽分区算法
该算法首先虚拟出一个固定数量的整数集合,该集合中的每个整数称为一个 slot 槽。这个槽的数量一般是远远大于节点数量的。然后再将所有 slot 槽平均映射到各个节点之上。例如,Redis 分布式系统中共虚拟了 16384 个 slot 槽,其范围为[0, 16383]。假设共有 3 个节点,那么 slot 槽与节点间的映射关系如下图所示:
数据只与 slot 槽有关系,与节点没有直接关系。数据只通过其 key 的 hash(key)映射到slot 槽:slot = hash(key) % slotNums。这也是该算法的一个优点,解耦了数据与节点,客户端无需维护节点,只需维护与 slot 槽的关系即可。Redis 数据分区采用的就是该算法。其计算槽点的公式为:slot = CRC16(key) % 16384。CRC16()是一种带有校验功能的、具有良好分散功能的、特殊的 hash 算法函数。
其实 Redis中计算槽点的公式不是上面的那个,而是:slot = CRC16(key) &16383。
若要计算 a % b,如果 b 是 2 的整数次幂,那么 a % b = a & (b-1)。