1.数据分布简介
(1).分布式数据库的数据分区
分布式数据库首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集。
(2).常见的分区规则
顺序分区
哈希分区(Redis Cluster采用的分区规则)
(3).常见分区规则的对比
分区方法 特点 代表产品
哈希分区 离散度好;数据分布业务无关;无法顺序访问 Redis Cluster;Cassandra;Dynamo
顺序分区 离散度易倾斜;数据分布业务相关;可顺序访问 Bigtable;HBase;Hypertable
2.节点取余分区
(1).计算公式
节点取余分区使用hash(key)%nodes(使用特定的数据,如Redis的键作为key和节点数量nodes)来计算哈希值,以决定数据映射到哪一个节点上。
(2).存在的问题
当节点数量变化时,如扩容或收缩节点,数据节点映射关系需要重新计算,会导致数据的重新迁移,其示意图如下所示。
(3).多倍扩容
(4).总结
客户端分片:哈希 + 取余
节点伸缩:数据节点关系变化,导致数据迁移
迁移数量和添加节点数量有关:建议翻倍扩容(一般不建议使用,因为这样会降低性能,增加底层数据源的访问压力)
3.一致性哈希分区
(1).什么是一致性哈希
每个节点分配一个token(范围在0~2的23次方),这些token构成一个哈希环。数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该哈希值的token节点。
(2).扩容
这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中相邻的节点,对其它节点无影响,其数据漂移示意图如下所示。
(3).存在的问题
加减节点会造成哈希环中部分数据无法命中,如之前n1-n2之间的4个数据,由于n5节点的加入,当应用读取n5-n2之间的数据时,Redis会先去n5获取,获取不到就只能去存储层去获取,然后回写到n2节点。当使用少量节点时,节点变化将大范围影响哈希环中数据映射,因此这种方式不适合少量数据节点的分布式方案。
(4).总结
客户端分片:哈希 + 顺时针
节点伸缩:只影响邻近节点,但还是有数据迁移
翻倍伸缩:保证最小迁移数据和负载均衡
4.虚拟槽哈希分区
(1).简介
槽是集群内数据管理和迁移的基本单位。
采用大范围槽的主要目的是为了方便数据拆分和集群扩展。
每个节点会负责一定数量的槽。
服务端管理节点、槽和数据之间的关系,如Redis Cluster。
(2).槽范围
槽范围是0~16383,假如现在集群有5个节点,那么每个节点平均大约负责3277个槽。
(3).虚拟槽分配
Redis Cluser采用虚拟槽分区,所有的键根据哈希函数映射到0~16383整数槽内,计算公式为slot=CRC16(key)&16383。每一个节点负责维护一部分槽以及槽所映射的键值数据。
(4).总结
解耦数据和节点之间的关系,简化了节点扩容和收缩难度。
节点自身维护槽的映射关系,不需要客户端或者代理服务维护槽分区元数据。
支持节点、槽、键之间的映射查询,用于数据路由、在线伸缩等场景。