随着请求量和数据量的增加,一台机器已经无法满足需求,我们就需要把数据和请求分散到多台机器。我们就需要引入分布式存储。分布式存储有以下特性:
- 增强可用性:如果数据库的某个节点出现故障,在其他节点的数据仍然可用;
- 维护方便:如果数据库的某个节点出现故障,需要修复数据,只修复该节点即可;
- 均衡I/O:可以把不同的请求映射到各节点以平衡I/O,改善整个系统性能;
- 改善查询性能:对分区对象的查询可以仅搜索自己关心的节点,提高检索速度。
分布式存储首先要解决把整个数据集按照分区规则映射到多个节点的问题,即把数据集划分到多个节点上,每个节点负责整体数据的一个子集。
常见分区算法
范围分区:
范围分区将数据基于范围映射到每一个分区,这个范围是你在创建分区时指定的分区键决定的。数据库中这种分区方式是最为常用的,并且分区键经常采用日期。
- 优点:同一范围内的范围查询不需要跨节点,提升查询速度
- 应用场景:mysql,oracle
节点取余分区:
一般是通过数据的某个特征计算哈希值,并将哈希值与集群中的服务器建立映射关系,从而将不同数据分布到不同服务器上。
hash(object) % N
- 优点:实现简单
- 缺点:当扩容或收缩节点时,需要迁移的数据量大。(翻倍扩容可以相对减少迁移量)
- 应用场景:
一致性哈希分区:
实现思路是为系统中每个节点分配一个token,范围一般在0~2^32,这些token构成一个哈希环。数据读写执行节点查找操作时,先根据key计算hash值,然后顺时针找到第一个大于等于该哈希值的token节点。如图
- 优点:这种方式相比节点取余最大的好处在于加入和删除节点只影响哈希环中相邻的节点,对其他节点无影响。
- 缺点:当使用少量节点时,节点变化将大范围影响哈希环中数据映射,因此这种方式不适合少量数据节点的分布式方案。
- 应用场景:mencache
虚拟槽分区:
在一致性hash分区的基础上加入了,虚拟槽(slot)的概念,通过 virtual slot 将哈希环分割成更小的粒度,小粒度的 slot 块被不同的 node 持有。
- 优点:每个node均匀的分配了slot,缩小增减节点影响的范围
- 缺点:需要存储node和slot的对应信息
- 应用场景:redis cluster,DDB
分布式数据库DDB:
DDB就使用了虚拟槽分区的概念,把hash表均匀的映射到数据节点,通过balanceId计算hash,对应hashtable找到对应的数据节点。