
文章目录先说结论普通 Hash 的问题一致性 HashHash 环虚拟节点解决数据倾斜回答技巧与点评加分回答面试官点评个人网站加了台缓存服务器结果大部分请求都打到了新服务器上——缓存几乎全废了。普通 Hash 算法在节点增减时会导致大量数据重新分配一致性 Hash 就是为了解决这个问题。面试官问这题他想听的是你能不能讲清普通 Hash 的问题、一致性 Hash 的原理、虚拟节点的作用先说结论维度说明解决什么问题节点增减时尽量少的数据迁移核心思路把节点和数据都映射到 Hash 环上顺时针找节点关键优势增减节点只影响相邻节点不影响全局数据倾斜问题节点少时分布不均 → 用虚拟节点解决典型应用Redis Cluster、Dubbo 一致性Hash负载均衡、Nginx|一句话记住一致性Hash就像圆形食堂——窗口增减时只影响旁边几个学生换窗口不会全校大换座位普通 Hash 的问题普通 Hash 用hash(key) % N计算节点3台服务器hash(key) % 3 → 0/1/2 增加1台变成4台hash(key) % 4 → 0/1/2/3 示例 keyA → hash(A)11 → 11%32(服务器2) → 11%43(服务器3) 变了 keyB → hash(B)7 → 7%31(服务器1) → 7%43(服务器3) 变了 keyC → hash(C)5 → 5%32(服务器2) → 5%41(服务器1) 变了增减节点时几乎所有数据的映射都会变——缓存命中率暴跌数据库瞬间被打爆。就像学校食堂——3 个窗口变 4 个窗口按学号%窗口数分配的话大部分学生都要换窗口整个食堂乱套。一致性 HashHash 环一致性 Hash 把整个 Hash 空间首尾相连形成一个环0 → 2³²-1 → 00 / \ NodeA NodeC (100) (300) | | NodeB (200) \ 2³²-1 映射规则数据顺时针找最近的节点 keyX → hash(X)150 → 顺时针 → NodeB(200) keyY → hash(Y)250 → 顺时针 → NodeC(300) keyZ → hash(Z)50) → 顺时针 → NodeA(100) 增加节点时新增 NodeD(250) 原来keyY(250) → NodeC(300) 现在keyY(250) → NodeD(250) 只影响 NodeC 的部分数据 其他数据不受影响删除节点时删除 NodeB(200) 原来keyX(150) → NodeB(200) 现在keyX(150) → NodeC(300) 只影响 NodeB 的数据 其他数据不受影响虚拟节点解决数据倾斜当节点少时Hash 环上的分布可能很不均匀没有虚拟节点 NodeA(100) 和 NodeC(300) 之间跨度大 → NodeC 负责的数据远多于 NodeA 解决方案每个真实节点映射多个虚拟节点 NodeA → NodeA#1(50), NodeA#2(100), NodeA#3(150) NodeB → NodeB#1(180), NodeB#2(200), NodeB#3(230) NodeC → NodeC#1(270), NodeC#2(300), NodeC#3(350)// 虚拟节点的实现简化TreeMapInteger,StringringnewTreeMap();for(Nodenode:nodes){for(inti0;iVIRTUAL_COUNT;i){// 每个节点150个虚拟节点inthashhash(node.name#i);ring.put(hash,node.name);}}// 查找顺时针找第一个StringfindNode(Stringkey){inthashhash(key);Map.EntryInteger,Stringentryring.ceilingEntry(hash);// 顺时针returnentry!null?entry.getValue():ring.firstEntry().getValue();}虚拟节点越多分布越均匀Dubbo 默认每个节点 160 个虚拟节点。一致性Hash全景 核心思想 ├── Hash环 —— 节点和数据都映射到环上 ├── 顺时针查找 —— 数据顺时针找最近节点 └── 增减节点 —— 只影响相邻数据 vs 普通Hash ├── 普通Hash —— 节点变化全量迁移 └── 一致性Hash —— 节点变化局部迁移 虚拟节点 ├── 解决 —— 节点少时分布不均 ├── 实现 —— 每节点映射多个虚拟节点 └── Dubbo默认 —— 160个虚拟节点 口诀Hash环上顺时针增减节点只相邻 普通Hash全量迁一致性Hash局部迁 虚拟节点均分布数据倾斜靠它解 缓存场景最常用节点增减不雪崩回答技巧与点评标准回答一致性 Hash 把节点和数据都映射到 0~2³² 的 Hash 环上数据顺时针找最近的节点。增减节点时只影响相邻节点的数据不像普通 Hashhash%N会导致全量数据迁移。节点少时会有数据倾斜问题通过虚拟节点解决——每个真实节点映射多个虚拟节点到环上虚拟节点越多分布越均匀。加分回答一致性 Hash 的边界问题当大量节点同时宕机时如机房故障这些节点的流量会全部涌向顺时针下一个节点可能造成雪崩。解决方案是给每个节点设置多个备份节点Redis Cluster 的一致性 HashRedis Cluster 没用一致性 Hash而是用 Hash Slot16384 个槽每个节点负责一部分槽。这种方案相比一致性 Hash 的优势是迁移时可以精确控制每个槽的转移跳跃一致性 HashGoogle 提出的一种不需要 Hash 环的一致性 Hash 算法时间复杂度 O(logN)空间复杂度 O(1)比传统一致性 Hash 更高效面试官点评这道题考的是你对分布式数据分布的理解。最忌讳的回答是只知道Hash 环——面试官想听的是为什么需要一致性 Hash普通 Hash 的问题和虚拟节点的必要性数据倾斜。能从问题出发讲清方案和优化就是高分回答。原文阅读内容有帮助点赞、收藏、关注三连评论区等你