The consistent hashing algorithm is a distributed hashing algorithm, mainly to solve the hot spot problem in the Internet.
Calculation Formula
- Hash (server IP address)% 2^32
- Map the value of the object hash to the nearest server clockwise
Java implementation
PackageCom.bounter.mybatis.util;Importjava.util.LinkedList;Importjava.util.List;ImportJava.util.SortedMap;ImportJava.util.TreeMap;Importorg.springframework.util.StringUtils;/*** Consistent hash algorithm implementation * For library sub-table primary key ID mapping, distributed Cache key Mapping *@authorSimon **/ Public classConsistenthash {//list of servers to add hash rings toPrivate StaticString[] Servers = {"192.168.0.0:111", "192.168.0.1:111", "192.168.0.2:111", "192.168.0.3:111","192.168.0.4:111" };//Real Node list, considering the server on-line, offline scenario, that is, add, delete the scene will be more frequent, where the use of LinkedList will be betterPrivate StaticList<string> realnodes =NewLinkedlist<string>();//virtual node, key represents the hash value of the virtual node, value represents the name of the virtual nodePrivate StaticSortedmap<integer, string> virtualnodes =NewTreemap<integer, string>();//number of virtual nodes, written here dead, for demonstration needs, a true node corresponds to 5 virtual nodesPrivate Static Final intVirtual_nodes = 5;Static {//first add the original server to the list of real nodes . for(inti = 0; i < servers.length; i++) Realnodes.add (Servers[i]);//adding virtual nodes, traversing LinkedList using the Foreach loop will be more efficient for(String str:realnodes) { for(inti = 0; i < virtual_nodes; i++) {String virtualnodename= str + "&&VN" +string.valueof (i);inthash =Gethash (virtualnodename); Virtualnodes.put (hash, virtualnodename); }}//use the Fnv1_32_hash algorithm to calculate the hash value of the server, which does not use rewrite Hashcode method, the final effect is no differentPrivate Static intGethash (String str) {Final intp = 16777619;inthash = (int) 2166136261L; for(inti = 0; I < str.length (); i++) Hash= (hash ^ str.charat (i)) *P;hash+ = Hash << 13; hash^= Hash >> 7; hash+ = Hash << 3; hash^= Hash >> 17; hash+ = Hash << 5;//if the calculated value is negative, take its absoluteif(Hash < 0) Hash=Math.Abs (hash);returnHash;}//get the node that should be routed toPrivate Staticstring Getserver (String key) {//get the hash value of the keyinthash =Gethash (key);//get all maps that are larger than the hash valueSortedmap<integer, string> SubMap =Virtualnodes.tailmap (hash); String Virtualnode;if(Submap.isempty ()) {//if there is no greater hash value than the key, start with the first nodeInteger i =Virtualnodes.firstkey ();//returns the corresponding serverVirtualnode =Virtualnodes.get (i);} Else {//The first key is the node nearest to node clockwise.Integer i =Submap.firstkey ();//returns the corresponding serverVirtualnode =Submap.get (i);}//virtualnode Virtual node name to intercept .if(!Stringutils.isempty (Virtualnode)) {returnVirtualnode.substring (0, Virtualnode.indexof ("&&"));}return NULL;} Public Static voidMain (string[] args) {String key= "877073895583547392"; System.out.println ("[" + key + "] hash value" + gethash (Key) + ", is routed to the node [" + Getserver (Key) + "]");}}
Distributed consistent hashing algorithm