0%

分布式存储基本原理

分布式存储基本原理

📦 本文已归档到:「blog

1. 分区规则

分布式数据库 首先要解决把 整个数据集 按照 分区规则 映射到 多个节点 的问题,即把 数据集 划分到 多个节点 上,每个节点负责 整体数据 的一个 子集

数据分布通常有 哈希分区顺序分区 两种方式,对比如下:

分区方式 特点 相关产品
哈希分区 离散程度好,数据分布与业务无关,无法顺序访问 Redis Cluster,Cassandra,Dynamo
顺序分区 离散程度易倾斜,数据分布与业务相关,可以顺序访问 BigTable,HBase,Hypertable

由于 Redis Cluster 采用 哈希分区规则,这里重点讨论 哈希分区。常见的 哈希分区 规则有几种,下面分别介绍:

1.1. 节点取余分区

使用特定的数据,如 Redis用户 ID,再根据 节点数量 N 使用公式:hash(key)% N 计算出 哈希值,用来决定数据 映射 到哪一个节点上。

  • 优点

这种方式的突出优点是 简单性,常用于 数据库分库分表规则。一般采用 预分区 的方式,提前根据 数据量 规划好 分区数,比如划分为 5121024 张表,保证可支撑未来一段时间的 数据容量,再根据 负载情况 迁移到其他 数据库 中。扩容时通常采用 翻倍扩容,避免 数据映射 全部被 打乱,导致 全量迁移 的情况。

  • 缺点

节点数量 变化时,如 扩容收缩 节点,数据节点 映射关系 需要重新计算,会导致数据的 重新迁移

1.2. 一致性哈希分区

一致性哈希 可以很好的解决 稳定性问题,可以将所有的 存储节点 排列在 首尾相接Hash 环上,每个 key 在计算 Hash 后会 顺时针 找到 临接存储节点 存放。而当有节点 加入退出 时,仅影响该节点在 Hash 环上 顺时针相邻后续节点

  • 优点

加入删除 节点只影响 哈希环顺时针方向相邻的节点,对其他节点无影响。

  • 缺点

加减节点 会造成 哈希环 中部分数据 无法命中。当使用 少量节点 时,节点变化 将大范围影响 哈希环数据映射,不适合 少量数据节点 的分布式方案。普通一致性哈希分区 在增减节点时需要 增加一倍减去一半 节点才能保证 数据负载的均衡

注意:因为 一致性哈希分区 的这些缺点,一些分布式系统采用 虚拟槽一致性哈希 进行改进,比如 Dynamo 系统。

1.3. 虚拟槽分区

虚拟槽分区 巧妙地使用了 哈希空间,使用 分散度良好哈希函数 把所有数据 映射 到一个 固定范围整数集合 中,整数定义为 slot)。这个范围一般 远远大于 节点数,比如 Redis Cluster 槽范围是 0 ~ 16383 是集群内 数据管理迁移基本单位。采用 大范围槽 的主要目的是为了方便 数据拆分集群扩展。每个节点会负责 一定数量的槽,如图所示:

当前集群有 `3` 个节点,每个节点平均大约负责 `5460` 个 **槽**。由于采用 **高质量** 的 **哈希算法**,每个槽所映射的数据通常比较 **均匀**,将数据平均划分到 `3` 个节点进行 **数据分区**。`Redis Cluster` 就是采用 **虚拟槽分区**。

集群中的每个节点负责一部分哈希槽,比如集群中有3个节点,则:

  • 节点A存储的哈希槽范围是:0 – 5460
  • 节点B存储的哈希槽范围是:5461 – 10922
  • 节点C存储的哈希槽范围是:10923 – 16383

这种结构很容易 添加 或者 删除 节点。如果 增加 一个节点 4,就需要从节点 1 ~ 3 获得部分 分配到节点 4 上。如果想 移除 节点 1,需要将节点 1 中的 移到节点 2 ~ 3 上,然后将 没有任何槽 的节点 1 从集群中 移除 即可。

由于从一个节点将 哈希槽 移动到另一个节点并不会 停止服务,所以无论 添加删除 或者 改变 某个节点的 哈希槽的数量 都不会造成 集群不可用 的状态.

2. 参考资料