分片机制浅解

80 阅读3分钟

我正在参与掘金创作者训练营第5期,点击了解活动详情

分片机制是在实现扩容机制的一个手段,它源自于一个很朴素的想法:整合资源,类似于两块小硬盘组合,作为一块大硬盘,整体表现为一块打硬盘,而具体某一个数据则放置于某一块小硬盘也就是所谓的分片上。

但是它提供的好处却不只是容量的扩展,还能够提升系统的吞吐量,比如说在同时访问两个不同分片上的数据,一般来说是可以并行访问的。 这也意味着一些别的问题,不应该让数据过分集中在某个分片上,比如说在数据库使用中,如果以时间戳为索引,那么当前时刻总是因为数据量大,而导致数据倾斜现象严重。

另外这里的重点在于扩容的便捷性,如果没有这一条事情好办的多,方法就是老生常谈的两种,一是按范围,二是哈希取模,至于原因则是在于我们需要能够在插入

比如说经典的三个节点u, v, w,按照哈希分配位置,假设索引是最基础的自增类型,hash取最简单的直接对3取模。那么u的索引id可以使用0、3、6...同理v储存1、4...等

如果要变为四个节点,大部分位置都要迁移到一个合适的新的位置,基本上这些值经过hash计算都不再会相同。

基于范围的的话则是直接把可能的id值范围切成几块,比如把整个可用区间切成三段,每个节点各自占用一段,这样可以各自储存数据。这种方式的问题在于范围的划分并不是很好决定。

为此有一些优化过相对比较常用的分片算法如下:

哈希槽

这是redis当中使用的分片方式。具体来说是把逻辑上的储存位置和物理储存位置分开了。 它的思路是不管实际有多少节点,它对外表现出的是很多的槽,每个值得存取都是通过将数据hash之后取模以关联到相关的槽上。 而槽和节点的关系是通过一个数据结构保存的,它记录了每个槽对应的位置。槽对应节点修改则只需要将该槽的数据迁移即可。

一致性哈希

一致性哈希也可以说是把逻辑上的储存位置和物理上的储存位置分开了。它保存值的思路是把取一个映射范围足够大的hash函数,映射的结果可以认为是一个虚的节点,或者逻辑上的节点。而真正的节点也对应于范围中的某一个值,所有比他小的都被储存在它这个位置,因此实际上的寻找每个值保存的位置都可以使用二分搜索(寻找接近它的值)。


本文只从分片自身做了简单的解析,而分片有许多特性是无法保证的,这需要配合其他技术,但分片的作用仍然无需被质疑。