笔者带你剖析三种常见的分布式路由算法

  Redis、Memcache也好,MySQL也罢。当达到单点可处理的容量上线时,Sharding是一种解决痛点最直接的解决方案。假设对存储系统实施了Sharding,那么我们究竟应该如何选取合适的路由算法呢?本文列举三种最常见的分布式理由算法:硬Hash算法、一致性Hash算法,以及预分桶算法。

  1、硬Hash算法:

  即hash(routeKey) % dbSize,首先对路由Key进行Hash,然后对机器数量求余,这种分布式路由算法非常简单,同时也极其容易理解。

  我们可以看一下MySQL分库分表中间件Shark的路由算法:

  这种分布式路由算法尽管简单,但随着后续数据持续膨胀,一旦达到单表存储容量上线,我们仍然需要再次进行水平扩容,但这时的数据迁移成本就显得非常昂贵了。假设从32个库水平扩展到64个库(伸缩都如此),假设原routeKey是路由到第14个库上,现在却路由到了第45库上,采用硬Hash算法,严重依赖节点数量,基本上所有的数据都需要进行一次彻底的迁移,否则历史数据将无法成功命中

  2、一致性Hash算法:

  相较于硬Hash算法而言,一致性Hash尽管在实现和理解上更为复杂,但是带来的好处仍然是显而易见的。首先我们先简单对一致性Hash算法有个大致的了解。所谓一致性Hash,简单来说,就是首先抽象出一个0~232的圆,然后hash(机器)映射到圆的各个位置上,接着hash(routeKey)采用顺时针方式查找圆上最近的机器即可(如果超过232仍然找不到机器,则映射到第一台机器上),如如A所示。

  图A:一致性hash算法

  假设中途我们对机器进行相应的扩容,比如从4台扩容到5台,那么只有在圆上增加服务器的地点逆时针方向的第一台服务器上的routeKey相关数据库会受到影响,这和硬Hash不同,至少大部分历史数据还是可以正常命中的,影响面较小,如图B所示。

  图B:一致性hash算法扩容影响

  相对于硬Hash算法,尽管一致性Hash能够适当的降低迁移成本,提升历史数据的命中率,但是一致性Hash算法有个不容忽视的问题,那便是一致性哈希算法在机器节点太少时,容易因为节点分部不均匀从而造成数据倾斜,如图C所示:

  图C:数据倾斜

  上图中,由于节点分配不均匀,将会导致大量的数据都在node1节点上命中,如果在并发较高的场景下,node1将会因为负载压力被扩大至N倍导致宕机。为了解决这个问题,我们引入了虚拟节点机制,即对每一个机器节点计算多次(个)Hash,均匀分布到圆的各个位置上。具体做法可以在服务器ip或主机名的后面增加编号来实现(比如192.168.1.1-01,192.168.1.1-02,192.168.1.1-03,192.168.1.1-0n),实际上这么做的目的就是把一个实际节点映射圆上的到多个位置上,多个位置其实都是指向的同一个目标物理节点。

  那么在Java中实现一致性Hash也是非常简单的,这里我们会使用到SortedMap。如下所示:

  3、预分桶算法:

  预分桶算法介于硬Hash算法与一致性Hash算法之间,算是取得一个平衡(对于历史数据的迁移而言,硬Hash算法是全迁移,而一致性Hash算法则是部分迁移),尽管牺牲了一定的灵活性,但是相较而言,数据的管理成本将会变得更低因为硬Hash算法与强一致性Hash算法都是站在具体的数据维度上,而预分桶算法则是在数据被包裹的基础之上以slot为维度(尽管也是需要数据全部迁移,但只需要迁移上层的一段slot)。

  Redis3.x以上版本提供了cluster功能,实际上这却是一个服务端的sharding操作。一共划分了16384个slot,假设redis有3台集群,那么理论上这16384个slot将会均匀分布给这3个节点,每个redis节点负责存储一段区间内的数据,通过阅读Jedis客户端源码,我们不难发现,在做数据路由的时候,采用的做法是:

  只需要算出routeKey对应的slot是哪一个,即可知道对应的Redis节点是哪一个,并且16384个slot是一开始就固定的,不会因为节点的伸缩而变化,也就是说,某个key一开始路由到第2048slot上,那么它永远也只会路由到这个固定的slot上,当运维同学扩容节点时,把slot移走就行了,不需要关心那么多具体的数据应该怎么迁移。

 

 

 

 

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值