找回密码
 立即注册
首页 业界区 业界 海量数据如何“安家”?一文读懂哈希、范围和一致性哈希 ...

海量数据如何“安家”?一文读懂哈希、范围和一致性哈希三大分片策略

田雅宁 昨天 11:38
将单机问题转化为分布式解决方案时,首要任务是对问题进行分解,使得集群中的每台机器负责处理原问题的一个子集。无论是计算任务还是存储任务,其操作对象都是数据。因此,如何将海量数据有效地分解并分配到集群的不同节点上,即数据分布(也常称为数据分片,Data Partitioning/Sharding),是构建分布式系统的基础。
哈希分布
哈希分布(Hash-based Partition)是通过哈希函数(如MD5、SHA-1或简单取模)将数据的键(Key)映射到固定范围的哈希值,再根据哈希值将数据分配到不同的节点。
哈希分布(Hash-based Partition)通过一个确定的哈希函数(如MurmurHash、CRC32,或者简单的取模运算;MD5、SHA-1等加密哈希也可用于需要强随机性的场景,但通常计算开销较大)作用于数据的某个键(Key),将键映射到一个固定范围的哈希值。然后,根据哈希值(例如,hash(key) % num_nodes)将数据分配到对应的节点。
良好的哈希函数可以将数据尽可能均匀地散列到各个节点,避免数据倾斜,从而实现负载均衡。然而,当集群中的节点数量发生变化(增减节点)时,如果采用简单的取模方式(% num_nodes),绝大多数数据的哈希映射关系都会改变,导致大规模的数据迁移(如节点从10个扩容到11个,约90%的数据需要迁移)。
1.png

数据范围分布
数据范围分布(Range-based Partition)根据数据的键值(如时间戳、自增ID、字母顺序等具有序关系的属性)将其划分为连续的区间,每个节点负责存储一个或多个这样的数据区间。例如,一个订单表可以按月份范围(2023-01 至 2023-03,2023-04 至 2023-06等)划分,并将不同月份的数据存储在不同节点上。
由于数据在物理上按键顺序存储,范围查询(如查询某个时间段内的所有订单)非常高效,数据局部性好。然而,如果某些键值范围的数据量远大于其他范围,或者访问频率远高于其他范围(例如,当前月份的订单总是被频繁访问),则可能导致对应节点的负载过高,形成热点。
2.png

一致性哈希分布
一致性哈希(Consistent Hashing Partition)是为了解决传统哈希分布在节点数量动态变化时导致大规模数据迁移问题而提出的优化算法。它将所有节点和数据的键都通过同一个哈希函数映射到一个逻辑上的环形哈希空间(例如 0 到 232−1)。数据键被分配给在环上沿顺时针方向寻找到的第一个节点。
Ketama Hash 是经典实现之一。Rendezvous Hashing、Jump Consistent Hash、Maglev Hash 等也是在不同场景下具有特定优势的一致性哈希变种。
Ketama Hash又称割环法。在Ketama Hash中,将节点通过哈希方式,映射到一个范围是[0,2^32]的环上,同理,把数据也通过哈希方式映射到环上,然后按顺时针方向查找第一个哈希值大于等于数据的哈希值的节点,该节点即为数据所分配到的节点。而更好点的做法,可以为每个物理节点分配若干个虚拟节点,然后把虚拟节点映射到哈希环,分配给每个物理节点虚拟节点数量对应每个物理节点的权重。
如下图所示,数据K1映射到了节点2,数据K2映射到节点3。
3.png

1)扩容:对于割环法的扩容,只需在环上增加一组扩容节点生成的虚拟节点;
2)缩容:同样的,缩容时只需拿掉缩容节点对应的所有虚拟节点;
3)故障容灾:割环法的故障容灾与缩容情况一样,节点故障时只需将故障节点对应的所有虚拟节点从环上去掉。
4.png

如上图所示,当节点2故障时,将节点2对应的2个虚拟节点去掉,而原本映射到节点2的对象K1和K2分别映射到了节点1和节点4。
未完待续
很高兴与你相遇!如果你喜欢本文内容,记得关注哦!!!

来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册