分布式缓存中一致性hash

第一种:传统的数据分布方法,将key的hash值对机器数取模

这个算法的实现非常简单,计算hash(key)/n,n为机器数,得到的值就是该key需要路由到的服务器编号了。

优点:实现简单
缺点:在服务器数量发生变化的时候,缓存会大量失效。

第二种:一致性hash

试想下如果使用传统取模算法。如果有一个key要存到缓存中,根据hash(key)/n (n表示有n台缓存服务器),可以计算出缓存所在的服务器id。这个时候有一台服务器挂掉了,剩下n-1台服务器。这时候,同样一个key,根据hash(key)/(n-1) ,这个时候就命中不了缓存了,基本所有的缓存都会失效,这个情况在线上可能是灾难性的。 一致性hash可以解决部分问题。
通常可以考虑[0,(2^32-1)]为hash值的取值范围。我们可以把取值范围想象成一个闭环,2^32-1 和 0 相连接。如下图所示。
这个时候假设我们有4个缓存服务器节点。(node1~node4) 首先计算这四个值的hash值,并且这四个点占据了闭环的四个位置,如上图所示,这个时候需要根据key来路由缓存服务器,首先计算hash(key)值(这个hash算法需要保证hash(key)的值落在在区间[0,2^32-1]中)。然后我们可以想象这个hash(key)值位于闭环的其中一个点,然后用这个hash(key)依次加一,直到命中其中一个node为止,命中的node就是key需要路由的服务器,如上图,需要找到key2的缓存值所在的服务器,首先计算hash(key2),落在如图的闭环中,然后顺时针找到离这个hash值最近的node,可以看到是node1。key2对应的缓存值就存在node1中。
如果这个时候如果增加了节点node5如下图:

看下缓存失效的情况,如上图,只有hash(key)落在node4~node5之间的key才会有影响,在未增加node5之前落在这个范围的key最终路由到node1,增加node5之后路由到node5了,缓存失效了。除此之外,落在其他范围的hash值就不受影响。如上图,增加node5之后key6原来会路由到node1的,现在路由到node5。而key1不受影响,还是路由到node1。
同理,如果少掉一个节点,还是上图为例,假如这个时候node5失效了,node5失效之前落在node4~node5之间的hash值,会路由到node5,失效之后会路由到node1,也就是原本落在node4~node5之间的hash值失效了。由此可见一致性hash能在节点变动的时候减少缓存失效的比例。
还有一种情况,当cache的数量很少的或者缓存服务器很少的时候,会导致缓存分布不均衡。如下图所示:

当只有很少节点的时候,例如上图的两个,这个时候就会分配得很不均衡。上图中node1明显承受了较多的压力。这个时候引入一个叫虚拟节点的概念,原理就是增加更多的虚拟节点,让每个节点承受的压力尽量均衡。这些增加的节点并不是真正新增的服务器节点,而是由原来的节点”复制“出来的。例如下图,”复制“了两个新节点,node3,node4。实际上,落到node3,node4的key最终访问的服务器是node2,node1.

这样就可以把压力尽量分配到各个机器上。另外需要维护一张表格,用来记录虚拟节点指向的真正节点。
优点:相比简单的对机器数取模算法,当节点变动的时候只有相对较少的key失效,实现也相对简单。不需要进行数据迁移,每个服务器是独立的。
缺点:还是会有部分的key失效,如果访问量非常大的时候,如果访问到失效的key的时候,就会直接访问到数据源上面去了,可能会导致数据源直接压挂。

Categories: Java

发表评论 取消回复

分布式缓存中一致性hash_第1张图片

电子邮件地址不会被公开。

Name
Email
Website
What's on your mind?

近期文章
  • Maven deploy部署jar到远程私服仓库
  • java动态代理实现与原理
  • git 常用命令
  • java中观察者模式Observable和Observer
  • Netty解决TCP粘包和拆包问题的四种方案
近期评论
  • 马化腾发表在《Nginx的一些基本功能》
  • geyang发表在《世界,您好!》
  • 一位WordPress评论者发表在《世界,您好!》
分类目录
  • Big Data (5)
  • Java (27)
  • MicroServices (13)
    • GateWay (2)
    • REST (2)
  • Plus (38)
  • Spring (9)
    • Spring Boot (5)
    • Spring Data (4)
  • 中间件/框架 (5)
    • Kafka (3)
  • 数据库 (11)
    • Hbase (5)
    • MongoDb (2)
    • Mysql (3)
标签
apiDoc Drools dubbo fiddler Grafana hbase Hystrix IDEA java JDK jpa jvisualvm jvm kafka linux MongoDB MQTT Mysql Netty nginx OpenJDK Prometheus REST RocketMQ RPC Servlet Sleuth SOA spring boot spring data zookeeper Zuul 域名 微服务 数据结构 日志 爬虫 缓存 股票 设计模式 读书 运维 队列 集合 音乐
联系我

你可能感兴趣的:(分布式缓存中一致性hash)