您好、欢迎来到现金彩票网!
当前位置:秒速时时彩开奖 > 算法 >

一致性 Hash 算法的实际应用

发布时间:2019-07-09 23:40 来源:未知 编辑:admin

  而这个选择的过程就是一个负载策略的过程;第一版本做的比较简单,默认只支持轮询的方式。

  因此我的规划是内置多种路由策略供使用者根据自己的场景选择,同时提供简单的 API 供用户自定义自己的路由策略。

  可见最终会按照key的大小进行排序,同时传入hashcode = 101时会按照顺时针找到hashcode = 1000这个节点进行返回。

  其中最核心的就是一个Node数组,用它来存放服务节点的hashcode以及value值。

  但是存放时是按照写入顺序存放的,遍历时自然不会有序;因此提供了一个 Sort 方法,可以把其中的数据按照 key 其实也就是hashcode进行排序。

  排序也比较简单,使用了Arrays这个数组工具进行排序,它其实是使用了一个TimSort的排序算法,效率还是比较高的。

  代码还是比较简单清晰的;遍历数组如果找到比当前 key 大的就返回,没有查到就取第一个。

  ps:这里并不包含具体的 hash 方法以及虚拟节点等功能(具体实现请看下文),这个可以由使用者来定,SortArrayMap 可作为一个底层的数据结构,提供有序 Map 的能力,使用场景也不局限于一致性 Hash 算法中。

  SortArrayMap虽说是实现了一致性 hash 的功能,但效率还不够高,主要体现在sort排序处。

  这里完全可以换一个思路,不用对数据进行排序;而是在写入的时候就排好顺序,只是这样会降低写入的效率。

  比如二叉查找树,这样的数据结构jdk里有现成的实现;比如TreeMap就是使用红黑树来实现的,默认情况下它会对 key 进行自然排序。

  ps:这里同样也没有 hash 方法以及虚拟节点(具体实现请看下文),因为 TreeMap 和 SortArrayMap 一样都是作为基础数据结构来使用的。

  为了方便大家选择哪一个数据结构,我用TreeMap和SortArrayMap分别写入了一百万条数据来对比。

  结果是快了将近一倍,所以还是推荐使用TreeMap来进行实现,毕竟它不需要额外的排序损耗。

  下面来看看在cim这个应用中是如何具体使用的,其中也包括上文提到的虚拟节点以及 hash 算法。

  在应用的时候考虑到就算是一致性 hash 算法都有多种实现,为了方便其使用者扩展自己的一致性 hash 算法因此我定义了一个抽象类;其中定义了一些模板方法,这样大家只需要在子类中进行不同的实现即可完成自己的算法。

  把虚拟节点的控制放到子类而没有放到抽象类中也是为了灵活性考虑,可能不同的实现对虚拟节点的数量要求也不一样,所以不如自定义的好。

  但是hash方法确是放到了抽象类中,子类不用重写;因为这是一个基本功能,只需要有一个公共算法可以保证他散列地足够均匀即可。

  这里的算法摘抄自 xxl_job,网上也有其他不同的实现,比如 FNV1_32_HASH 等;实现不同但是目的都一样。

  他只需要构建一个服务列表,然后把当前的客户端信息传入process方法中即可获得一个一致性 hash 算法的返回。

  而在使用时对于客户端来说只需求修改一个实现类,其他的啥都不用改就可以了。

  这样大家想自定义自己的算法时只需要继承AbstractConsistentHash重写相关方法即可,客户端代码无须改动。

  但其实对于cim来说真正的扩展性是对路由算法来说的,比如它需要支持轮询、hash、一致性hash、随机、LRU等。

  其中只有一个方法,也就是路由方法;入参分别是服务列表以及客户端信息即可。

  这里还有一个setHash的方法,入参是 AbstractConsistentHash;这就是用于客户端指定需要使用具体的那种数据结构。

  而对于之前就存在的轮询策略来说也是同样的实现RouteHandle接口。

  既然使用了注入,那其实这个策略切换的过程就在创建 RouteHandle bean 的时候完成的。

  希望看到这里的朋友能对这个算法有所理解,同时对一些设计模式在实际的使用也能有所帮助。

  相信在金三银四的面试过程中还是能让面试官眼前一亮的,毕竟根据我这段时间的面试过程来看听过这个名词的都在少数(可能也是和候选人都在 1~3 年这个层级有关)。

http://homeschoolwwh.com/suanfa/520.html
锟斤拷锟斤拷锟斤拷QQ微锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷锟斤拷微锟斤拷
关于我们|联系我们|版权声明|网站地图|
Copyright © 2002-2019 现金彩票 版权所有