一致性hash(整理版)
简单解释:
简单解释一致性hash的原理:网上通篇都是用服务器做的举例,我这里也如此,主要是便于理解。
通常:有N个客户端请求服务器,假设有M台web服务器,通常为了均衡访问会进行N%M的取模,然后分配到不同的缓存服务器访问。问题是一旦缓存服务器增加或减少时缓存的命中率被打乱,因为取模发生了变化。例A的访问分配到了M1上,假设服务器增减则有可能会被分配到M3上(M3为举例),那么M1上的原有缓存失效,M3需要重新建立A访问的缓存。
一致性Hash:有N个客户端请求服务器,假设有M台web服务器,把其中一个请求做HASH,M台服务器也做HASH,采用Sortedmap的tailMap特性,检索顺时针最近的一台服务器作为缓存服务器;
例:其中一个请求HASHCODE=254,M台服务器HASH后分别为1、58、648...(数字为举例),那么通过Sortedmap的tailMap特性可以找到648以及后面的服务器,则把最近的648作为缓存服务器。当然 如果tailMap找到的为NULL,则从Sortedmap的第一条key作为缓存服务器(保证map是一个环装)
简单代码:
完整代码示意-摘自互联网的代码(整理后),可以参考。
- package com.yiibai;
- import java.util.*;
- public class TreeMapDemo {
- public static void main(String[] args) {
- // creating maps
- TreeMap<Integer, String> treemap = new TreeMap<Integer, String>();
- SortedMap<Integer, String> treemapincl = new TreeMap<Integer, String>();
- // populating tree map
- treemap.put(2, "two");
- treemap.put(1, "one");
- treemap.put(3, "three");
- treemap.put(6, "six");
- treemap.put(5, "five");
- System.out.println("Getting tail map");
- treemapincl=treemap.tailMap(3);
- System.out.println("Tail map values: "+treemapincl);
- }
- }
完整代码示意-摘自互联网的代码(整理后),可以参考。
- import java.util.ArrayList;
- import java.util.HashMap;
- import java.util.List;
- import java.util.Map;
- import java.util.Map.Entry;
- import java.util.SortedMap;
- import java.util.TreeMap;
- import org.apache.commons.codec.digest.DigestUtils;
- public class VNode {
- private SortedMap<Integer, String> serverNodeMap = null;
- private final static int VIRTUAL_NODE_NUMBER = 5;
- public void getServerNodeWithoutVirtualNode(List<String> servers)
- {
- serverNodeMap = new TreeMap<Integer, String>();
- for (String string : servers)
- {
- serverNodeMap.put(hash(string), string);
- }
- }
- public void getServerNodeWithVirtualNode(List<String> servers)
- {
- serverNodeMap = new TreeMap<Integer, String>();
- for (String string : servers)
- {
- for (int i = 0; i < VIRTUAL_NODE_NUMBER; i++)
- {
- String virtualNodeName = string + ":" + i;
- serverNodeMap.put(hash(virtualNodeName), string);
- }
- }
- }
- public String getServerName(String data)
- {
- int dataHash = hash(data);
- SortedMap<Integer, String> subMap = serverNodeMap.tailMap(dataHash);
- int serverHash = 0;
- if (subMap == null || subMap.size() == 0)
- {
- serverHash = serverNodeMap.firstKey();
- }
- else
- {
- serverHash = subMap.firstKey();
- }
- String serverName = serverNodeMap.get(serverHash);
- return serverName;
- }
- /**
- * hash计算,这里使用md5后取hashcode,这个md5需要依赖apache的codec包
- * @param str
- * @return
- */
- public int hash(String str)
- {
- //System.out.println(str+"的hashcode="+DigestUtils.md5Hex(str).hashCode());
- return DigestUtils.md5Hex(str).hashCode();
- }
- public static void main(String[] args)
- {
- List<String> servers = new ArrayList<String>();
- servers.add("192.168.1.1");
- servers.add("192.168.1.2");
- servers.add("192.168.1.3");
- servers.add("192.168.1.4");
- servers.add("192.168.1.5");
- servers.add("192.168.1.6");
- List<String> datas = new ArrayList<String>();
- datas.add("A");
- datas.add("B");
- datas.add("C");
- datas.add("D");
- datas.add("E");
- datas.add("F");
- datas.add("G");
- datas.add("H");
- datas.add("I");
- VNode consistentHash = new VNode();
- System.out.println("没有虚拟节点的情况:");
- consistentHash.getServerNodeWithoutVirtualNode(servers);
- consistentHash.printDataAndServerNode(servers, datas, consistentHash);
- System.out.println("有虚拟节点的情况:");
- consistentHash.getServerNodeWithVirtualNode(servers);
- consistentHash.printDataAndServerNode(servers, datas, consistentHash);
- servers.add("192.168.1.7");
- System.out.println("增加第一个一个节点后:");
- System.out.println("没有虚拟节点的情况:");
- consistentHash.getServerNodeWithoutVirtualNode(servers);
- consistentHash.printDataAndServerNode(servers, datas, consistentHash);
- System.out.println("有虚拟节点的情况:");
- consistentHash.getServerNodeWithVirtualNode(servers);
- consistentHash.printDataAndServerNode(servers, datas, consistentHash);
- servers.remove(0);
- System.out.println("移除第一个一个节点后:");
- System.out.println("没有虚拟节点的情况:");
- consistentHash.getServerNodeWithoutVirtualNode(servers);
- consistentHash.printDataAndServerNode(servers, datas, consistentHash);
- System.out.println("有虚拟节点的情况:");
- consistentHash.getServerNodeWithVirtualNode(servers);
- consistentHash.printDataAndServerNode(servers, datas, consistentHash);
- }
- public void printDataAndServerNode(List<String> servers, List<String> datas,VNode consistentHash)
- {
- Map<String, String> result = new HashMap<String, String>();
- for (String data : datas)
- {
- String serverName = consistentHash.getServerName(data);
- if (!result.containsKey(serverName))
- {
- result.put(serverName, data);
- }
- else
- {
- result.put(serverName, result.get(serverName) + "," + data);
- }
- }
- for (Entry<String, String> entry : result.entrySet())
- {
- System.out.println(entry.getKey()+":"+entry.getValue());
- }
- }
- }
一致性hash(整理版)的更多相关文章
- 转载自lanceyan: 一致性hash和solr千万级数据分布式搜索引擎中的应用
一致性hash和solr千万级数据分布式搜索引擎中的应用 互联网创业中大部分人都是草根创业,这个时候没有强劲的服务器,也没有钱去买很昂贵的海量数据库.在这样严峻的条件下,一批又一批的创业者从创业中获得 ...
- 一致性 hash 算法( consistent hashing )a
一致性 hash 算法( consistent hashing ) 张亮 consistent hashing 算法早在 1997 年就在论文 Consistent hashing and rando ...
- 一致性Hash算法在Redis分布式中的使用
由于redis是单点,但是项目中不可避免的会使用多台Redis缓存服务器,那么怎么把缓存的Key均匀的映射到多台Redis服务器上,且随着缓存服务器的增加或减少时做到最小化的减少缓存Key的命中率呢? ...
- 一致性hash和solr千万级数据分布式搜索引擎中的应用
互联网创业中大部分人都是草根创业,这个时候没有强劲的服务器,也没有钱去买很昂贵的海量数据库.在这样严峻的条件下,一批又一批的创业者从创业中 获得成功,这个和当前的开源技术.海量数据架构有着必不可分的关 ...
- python -- 一致性Hash
python有一个python模块--hash_ring,即python中的一致性hash,使用起来也挺简单. 可以参考下官方例子:https://pypi.python.org/pypi/hash_ ...
- 一致性 Hash 学习与实现
普通的 Hash 解决的是什么问题? 下图是一个普通的余数法构造的哈希表. 一般在编程中使用哈希表,某个 bucket 突然就没了的概率比较小,常见的是因为负载因子太大需要增加 bucket,然后 r ...
- memcached 一致性hash原理
memcache 是一个分布式的缓存系统,但是本身没有提供集群功能,在大型应用的情况下容易成为瓶颈.但是客户端这个时候可以自由扩展,分两阶段实现.第一阶段:key 要先根据一定的算法映射到一台memc ...
- 一致性 hash 算法(转)
add by zhj:介绍了什么是一致性hash,以及实现一致性hash的一种算法. 原文:http://my.oschina.net/u/195065/blog/193614 目录[-] 一致性 h ...
- 一致性Hash算法(KetamaHash)的c#实现
Consistent Hashing最大限度地抑制了hash键的重新分布.另外要取得比较好的负载均衡的效果,往往在服务器数量比较少的时候需要增加虚拟节点来保证服务器能均匀的分布在圆环上.因为使用一般的 ...
随机推荐
- JUC知识点总结图
转载http://www.jsondream.com/2017/06/12/about-JUC.html
- 爬虫之mongodb数据库
一 mongodb的介绍 1.易用性:mongodb是一款强大.灵活并且易扩展的数据库.他面向于文档的数据库,而不是关系性数据库.不采用关系型主要是为了获得更好的扩展性.还有一个好处就是面向文档的数据 ...
- js保存,获取,删除cookie的操作
[转]来自:http://blog.csdn.net/itmyhome1990/article/details/7363816 JSP表单页面 <form action="login& ...
- hdu6444 2018中国大学生程序设计竞赛 - 网络选拔赛 1007 Neko's loop
Neko's loop Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total S ...
- c# 得到list符合某条件的索引值,排序
请教,在List集合中怎么得到元素的索引值,参考:http://www.myexception.cn/c-sharp/385022.html 这个可以用来读取窗口的多个textbox控件中内容: -- ...
- 关于内存类型 UDIMM、RDIMM、LRDIMM 的学习结论(转)
随着内存技术不断发展,服务器上内存的容量.密度和速度也越来越高.目前在市场上出现的内存条最高密度可以做到每条内存条 4 个 Rank,容量达到 32GB/条,最高速度达到 1.6GHz.高密度高频率也 ...
- poj 1094 Sorting It All Out 拓补排序
Description An ascending sorted sequence of distinct values is one in which some form of a less-than ...
- 线程之threading
多任务:操作系统同时运行多个任务 线程:一个程序运行起来之后一定有一个执行代码的东西,该东西即为线程 线程是操作系统调度执行的最小单位 * 并发:指的是任务数多余cpu核数,通过操作系统的各种任务 ...
- Ubuntu安装spyder并添加快捷方式
Ubuntu安装spyder并添加快捷方式 之前通过 sudo apt install spyder sudo apt install spyder3 安装spyder,但是这样有个坏处,编译器只能用 ...
- 20145232 韩文浩 《Java程序设计》第10周学习总结
13.1 网络概述 13.1.1计算机网络概述 网络编程的实质:两个(或多个)设备(例如计算机)之间的数据传输. 计算机网络的定义:通过一定的物理设备将处于不同位置的计算机连接起来组成的网络,这个网络 ...