当前位置: 首页 > news >正文

一致性哈希:让数据分布更均匀的神器

【720】一致性哈希:让数据分布更均匀的神器

你开了个快递站,最初只有3个员工。

分配包裹很简单:按编号除以3取余,0号员工、1号员工、2号员工。

后来员工离职了,只剩2个员工。你得重新分配所有包裹,工作量巨大。

再后来招聘新员工,你又得重新分配一遍。

这就像传统哈希的问题:扩容和缩容时,所有数据都要重新分配

一致性哈希就是来解决这个痛点的:节点变动时,只需要移动少量数据


一、一致性哈希的原理

环形空间

想象一个圆环,上面有2^32个位置(或者更多):

0 /\ 2^32/ \0 / \ / 环 \ /________\ 65536 4294967295

节点映射

把服务器节点映射到环上:

节点A:Hash("服务器A") = 1000000 节点B:Hash("服务器B") = 4000000 节点C:Hash("服务器C") = 7000000

数据映射

把数据Key也映射到环上:

数据X:Hash("数据X") = 3500000 数据Y:Hash("数据Y") = 6000000 数据Z:Hash("数据Z") = 9000000

顺时针查找

数据X顺时针走,遇到的第一个节点是节点B,所以数据X存在节点B上。


二、一致性哈希的优势

场景1:节点扩容

新增节点D,Hash(“服务器D”) = 5500000

原来:

  • 数据Y(6000000)在节点C
  • 数据Z(9000000)在节点C

现在:

  • 只有落在4000000~5500000之间的数据会移动到节点D
  • 其他数据不受影响!

场景2:节点缩容

节点B突然宕机,只有它上面的数据需要重新分配到节点C。

对比传统哈希

  • 传统:N个数据全部重新分配
  • 一致性哈希:只有部分数据重新分配

三、虚拟节点:解决数据倾斜

问题来了:如果三个节点分布不均匀怎么办?

节点A:1000000 节点B:4000000 节点C:4000001 ← 几乎在一起!

大部分数据都会落在节点C上,数据严重倾斜。

解决方案:虚拟节点

每个真实节点映射多个虚拟节点:

节点A-1:Hash("服务器A#1") = 1000000 节点A-2:Hash("服务器A#2") = 2000000 节点A-3:Hash("服务器A#3") = 3000000 节点B-1:Hash("服务器B#1") = 4000000 节点B-2:Hash("服务器B#2") = 5000000 节点B-3:Hash("服务器B#3") = 6000000 ...

这样节点在环上分布更均匀,数据也会更均衡。


四、实战应用

Redis集群

Redis Cluster使用一致性哈希(16384个槽位):

# 计算key应该落在哪个槽slot=crc16(key)%16384# 槽映射到节点node=slots[slot]

数据库分库分表

defget_shard(key):hash_key=hash(key)%(真实节点数*虚拟节点数)foriinrange(虚拟节点数):node_idx=(hash_key+i)%(真实节点数*虚拟节点数)if是真实节点(node_idx):return节点[node_idx]

CDN内容分发

用户请求图片时,通过一致性哈希选择最近的缓存节点。


五、代码实现

importhashlibclassConsistentHash:def__init__(self,nodes=None,virtual_nodes=150):self.virtual_nodes=virtual_nodes self.ring={}self.sorted_keys=[]ifnodes:fornodeinnodes:self.add_node(node)def_get_hash(self,key):"""计算哈希值"""returnint(hashlib.md5(str(key).encode()).hexdigest(),16)defadd_node(self,node):"""添加节点"""foriinrange(self.virtual_nodes):key=self._get_hash(f"{node}#vn{i}")self.ring[key]=node self.sorted_keys=sorted(self.ring.keys())defremove_node(self,node):"""移除节点"""foriinrange(self.virtual_nodes):key=self._get_hash(f"{node}#vn{i}")delself.ring[key]self.sorted_keys=sorted(self.ring.keys())defget_node(self,key):"""获取key对应的节点"""ifnotself.ring:returnNonehash_key=self._get_hash(key)forkinself.sorted_keys:ifk>=hash_key:returnself.ring[k]# 环的起点returnself.ring[self.sorted_keys[0]]

六、一句话总结

一致性哈希让系统扩缩容时,只需要移动少量数据,而不是全部重新分配。

配合虚拟节点,还能解决数据倾斜问题,是分布式系统的必备技能。

http://www.jsqmd.com/news/1300366/

相关文章:

  • PMP认证全攻略:报考、备考与职业发展
  • 莱姆石瓷砖怎么选?样式、性能与品牌参考
  • Steam游戏《妹居物语》接入deepseek API实现智能NPC对话
  • Transformer架构:自注意力机制与并行计算的革命
  • 岁 Java 仍在 “霸榜“:开发者凭什么还在为它熬夜?
  • ViTPose:基于Vision Transformer的人体姿态估计终极指南
  • 【2024Q2虚拟背景技术断层预警】:WebRTC 1.0与MediaPipe 0.10.12接口不兼容已致37家SaaS厂商紧急回滚(含热修复补丁)
  • 择校避坑!绍兴靠谱西点蛋糕咖啡培训全域招生,支持免费试学,杜绝隐形消费 - 烘焙行业测评
  • 阴阳师自动化脚本:基于SIFT图像识别的高效御魂副本助手
  • SOD原料活性40倍:优复美技术实力解析 - 趣闻早乐评
  • 跨境电商主要模式如何落地?从选模式到跑通全链路实操指南
  • 暗黑模式一键切换完整方案(CSS 变量 + 本地存储)
  • Flutter+鸿蒙跨平台工资条应用开发实践
  • Python实现PDF合并工具:从原理到实战,打造本地安全处理方案
  • 外呼系统行业已进入“合规+大模型”的深水区,谁会脱颖而出
  • 【AI视频绿幕抠像终极指南】:20年影像工程师亲授5大避坑法则与实时抠像优化公式
  • 2026年07月苏州激光切管机行业实力厂家与供应商综合解析 - 优企名品
  • aaa信用证书是由什么部门管理?aaa信用证书怎么申请?一篇讲透 - 叮咚办真方便
  • STM32-S273-对讲机频道可设+语音通话+一对多+状态显示+铃音提醒+按键设置+OLED屏+声光提醒-31(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_
  • 英雄联盟智能助手:如何用League Akari提升你的游戏效率与体验?
  • Unity版本控制终极指南:AssetModificationProcessor自动化实践
  • 3分钟搞定Windows和Office永久激活:KMS智能激活脚本完全指南
  • StreamCap终极指南:3步搞定跨平台直播自动录制
  • 解锁音乐自由:5分钟学会使用qmc-decoder转换QQ音乐加密文件
  • 如何用3分钟免费获取国家中小学智慧教育平台电子课本:教师必备的终极下载工具指南
  • Kimi图表背后的数据暗流:揭秘Transformer注意力权重如何扭曲柱状图感知(附开源校验脚本)
  • Bilibili-Old终极指南:如何快速恢复B站旧版页面与翻页评论区
  • CTF流量分析终极指南:5分钟掌握CTF-NetA网络流量分析神器
  • MuMu模拟器国际版
  • 2026 年 8 月淄博康跃非急救转运 同城跨省正规医疗护送,淄博病患出院转院专属服务 - 官方推广