跳转至

集群与分片⚓︎

问题导航
  1. 请简述一致性哈希的工作原理及虚拟节点的作用。
  2. 一致性哈希在发生节点扩容时,底层数据究竟是如何进行迁移的?
  3. 在分布式数据库持久化场景下进行数据迁移时,如何解决新旧数据的并发冲突与“幽灵复活”问题?

请简述一致性哈希的工作原理及虚拟节点的作用。⚓︎

工作原理: 构建 02^{32}-1 的哈希环。将服务器节点与数据键均哈希映射至环上。数据键沿环顺时针寻址,路由至遇到的第一个节点。扩容或缩容时,仅影响环上相邻节点的局部数据,避免了全量数据迁移。

  • 优点:增加或删除节点时,只会影响环上相邻的一小部分数据,大大减少了数据迁移量。早期的 Memcached 或使用 Twemproxy 代理的 Redis 经常用这种方案。
  • 缺点:节点较少时容易分布不均(需要引入虚拟节点来解决),且数据迁移的管理仍然比较复杂。

虚拟节点(Virtual Nodes): 解决物理节点较少时在哈希环上分布不均(数据倾斜)的问题。通过将一个物理节点映射为多个虚拟节点均匀散布在环上,平衡数据负载,并可实现权重的精细控制。


一致性哈希在发生节点扩容时,底层数据究竟是如何进行迁移的?⚓︎

依据应用场景对数据一致性的容忍度,工业界有两种截然不同的处理流派:

  • 纯缓存场景(如 Memcached - 惰性处理): 不进行主动数据迁移。新节点直接上线,遇到属于新区间但本地没有的 Key 时触发 Cache Miss,客户端回源底层数据库重新拉取并写入新节点。旧节点上的无效数据依靠 LRU 或 TTL 自然淘汰。

  • 持久化存储场景(如 Cassandra - 主动平滑搬迁): 新节点上线后先作为读写代理;老节点在后台开启低优先级线程,将对应区间的数据异步同步给新节点;同步完成后老节点安全删除本地数据,完成无损交接。


在分布式数据库持久化场景下进行数据迁移时,如何解决新旧数据的并发冲突与“幽灵复活”问题?⚓︎

分布式系统秉持“一切以时间线(版本)为准”的原则,构建了三道防线:

  • 最后写入者获胜(LWW, Last Write Wins):依赖时间戳或版本号。若新节点接收到的迁移数据(旧数据)时间戳小于本地已存在的新数据时间戳,则静默丢弃旧数据。
  • 墓碑机制(Tombstones):专门解决删除操作带来的“幽灵复活”。删除数据时并非直接物理擦除,而是写入一条带有时间戳的“死亡标记(墓碑)”。旧数据迁移过来时若遇到该墓碑,则直接丢弃。
  • 快照与增量日志(Snapshot + WAL):迁移分为两阶段。先传输底层数据快照,期间产生的并发修改记录在增量日志(WAL)中;快照传输完毕后再回放增量日志,极大地压缩了数据冲突的窗口期。
幽灵复活(Zombie Resurrection)问题

在分布式系统中,尤其是分布式数据库的迁移过程中,如果一个数据项被删除了,但由于网络延迟或迁移时序问题,旧数据又被迁移到了新节点上,这个数据就像“幽灵”一样复活了。这种情况会导致数据不一致和业务逻辑错误。

评论