一致性hash算法在分库分表中的应用

一、背景

普通hash取模弊端明显,扩容需要对所有数据重新hash,数据迁移量很大。

二、原理

创建1<<32个节点,形成hash环,hash值对1<<32取模后,顺时针映射到真实节点。

三、优缺点

3.1 优点:

可以动态扩容,增加一个真实节点,只对顺时针下一个真实节点产生影响,迁移率小。

3.2 缺点:

  • hash倾斜,导致数据分布不均。
  • 真实节点很多的话,扩容要计算hash环上迁移虚拟节点的工作量增大。

四、对缺点的补充

分库与分表的算法分开,独立扩容。

  • m为库的数量,hash%(1<<32) / ((1<<32)/m),作为分库算法,表数量不变去成倍的扩容库,只需迁移整张表,不需要重新hash。
  • n为表的数量,hash % n,作为分表算法,扩容库并不需要重新hash,成倍的扩容表,只需要在本库迁移,不需要换库。

五、部分代码

5.1 分库分表算法:

        long hash = Hashing.murmur3_128().hashString(orderNo, StandardCharsets.UTF_8).asLong();
        if(hash<=0) hash = hash & Long.MAX_VALUE;
        long value = hash % 4294967296L;

        // 分库,64库
        long databaseIndex = value / (4294967296L/32);

        // 分表,每库分32张表
        long tableIndex = hash % 32;
        System.out.println(value + "  " + databaseIndex + "-" + tableIndex);

5.2 数据测试

  • 扩容库,左图32库32表,右图64库32表


    image.png
  • 扩容表,左图32库32表,右图32库64表


    image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容