python 一致性哈希 分布式
hash_ring
# -*- coding: utf-8 -*-
"""
hash_ring
~~~~~~~~~~~~~~
Implements consistent hashing that can be used when
the number of server nodes can increase or decrease (like in memcached). Consistent hashing is a scheme that provides a hash table functionality
in a way that the adding or removing of one slot
does not significantly change the mapping of keys to slots. More information about consistent hashing can be read in these articles: "Web Caching with Consistent Hashing":
http://www8.org/w8-papers/2a-webserver/caching/paper2.html "Consistent hashing and random trees:
Distributed caching protocols for relieving hot spots on the World Wide Web (1997)":
http://citeseerx.ist.psu.edu/legacymapper?did=38148 Example of usage:: memcache_servers = ['192.168.0.246:11212',
'192.168.0.247:11212',
'192.168.0.249:11212'] ring = HashRing(memcache_servers)
server = ring.get_node('my_key') :copyright: 2008 by Amir Salihefendic.
:license: BSD
""" import math
import sys
from bisect import bisect if sys.version_info >= (2, 5):
import hashlib
md5_constructor = hashlib.md5
else:
import md5
md5_constructor = md5.new class HashRing(object): def __init__(self, nodes=None, weights=None):
"""`nodes` is a list of objects that have a proper __str__ representation.
`weights` is dictionary that sets weights to the nodes. The default
weight is that all nodes are equal.
"""
self.ring = dict()
self._sorted_keys = [] self.nodes = nodes if not weights:
weights = {}
self.weights = weights self._generate_circle() def _generate_circle(self):
"""Generates the circle.
"""
total_weight = 0
for node in self.nodes:
total_weight += self.weights.get(node, 1) for node in self.nodes:
weight = 1 if node in self.weights:
weight = self.weights.get(node) factor = math.floor((40*len(self.nodes)*weight) / total_weight); for j in range(0, int(factor)):
b_key = self._hash_digest( '%s-%s' % (node, j) ) for i in range(0, 3):
key = self._hash_val(b_key, lambda x: x+i*4)
self.ring[key] = node
self._sorted_keys.append(key) self._sorted_keys.sort() def get_node(self, string_key):
"""Given a string key a corresponding node in the hash ring is returned. If the hash ring is empty, `None` is returned.
"""
pos = self.get_node_pos(string_key)
if pos is None:
return None
return self.ring[ self._sorted_keys[pos] ] def get_node_pos(self, string_key):
"""Given a string key a corresponding node in the hash ring is returned
along with it's position in the ring. If the hash ring is empty, (`None`, `None`) is returned.
"""
if not self.ring:
return None key = self.gen_key(string_key) nodes = self._sorted_keys
pos = bisect(nodes, key) if pos == len(nodes):
return 0
else:
return pos def iterate_nodes(self, string_key, distinct=True):
"""Given a string key it returns the nodes as a generator that can hold the key. The generator iterates one time through the ring
starting at the correct position. if `distinct` is set, then the nodes returned will be unique,
i.e. no virtual copies will be returned.
"""
if not self.ring:
yield None, None returned_values = set()
def distinct_filter(value):
if str(value) not in returned_values:
returned_values.add(str(value))
return value pos = self.get_node_pos(string_key)
for key in self._sorted_keys[pos:]:
val = distinct_filter(self.ring[key])
if val:
yield val for i, key in enumerate(self._sorted_keys):
if i < pos:
val = distinct_filter(self.ring[key])
if val:
yield val def gen_key(self, key):
"""Given a string key it returns a long value,
this long value represents a place on the hash ring. md5 is currently used because it mixes well.
"""
b_key = self._hash_digest(key)
return self._hash_val(b_key, lambda x: x) def _hash_val(self, b_key, entry_fn):
return (( b_key[entry_fn(3)] << 24)
|(b_key[entry_fn(2)] << 16)
|(b_key[entry_fn(1)] << 8)
| b_key[entry_fn(0)] ) def _hash_digest(self, key):
m = md5_constructor()
m.update(bytes(key,encoding='utf-8'))
#return map(ord, m.digest())
return list(m.digest()) '''
memcache_servers = ['192.168.0.246:11212',
'192.168.0.247:11212',
'192.168.0.249:11212'] ring = HashRing(memcache_servers)
server = ring.get_node('my_key')
''' # 增加权重 memcache_servers = ['192.168.0.246:11212',
'192.168.0.247:11212',
'192.168.0.249:11212']
weights = {
'192.168.0.246:11212': 1,
'192.168.0.247:11212': 2,
'192.168.0.249:11212': 1
} ring = HashRing(memcache_servers, weights)
server = ring.get_node('my_key')
print(server)

增加删除机器时有可能数据找不到
python 一致性哈希 分布式的更多相关文章
- php实现一致性哈希算法
<?php//原理概念请看我的上一篇随笔(http://www.cnblogs.com/tujia/p/5416614.html)或直接百度 /** * 接口:hash(哈希插口).distri ...
- 7月目标 socket , 一致性哈希算法 ; mongodb分片; 分布式消息队列; 中间件的使用场景
分布式的基础:一致性哈希 路由算法的一致性hash http://www.jiacheo.org/blog/174 http://www.tuicool.com/articles/vQVbmai ...
- Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session框架
Tornado 自定义session,与一致性哈希 ,基于redis 构建分布式 session import tornado.ioloop import tornado.web from myhas ...
- 分布式_理论_08_Consistent Hash(一致性哈希算法)
一.前言 五.参考资料 1.分布式理论(八)—— Consistent Hash(一致性哈希算法)
- memcached分布式一致性哈希算法
<span style="font-family: FangSong_GB2312; background-color: rgb(255, 255, 255);">如果 ...
- .net的一致性哈希实现
最近在项目的微服务架构推进过程中,一个新的服务需要动态伸缩的弹性部署,所有容器化示例组成一个大的工作集群,以分布式处理的方式来完成一项工作,在集群中所有节点的任务分配过程中,由于集群工作节点需要动态增 ...
- 一致性哈希算法与Java实现
原文:http://blog.csdn.net/wuhuan_wp/article/details/7010071 一致性哈希算法是分布式系统中常用的算法.比如,一个分布式的存储系统,要将数据存储到具 ...
- 五分钟理解一致性哈希算法(consistent hashing)
转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT)实现算法 ...
- 每天进步一点点——五分钟理解一致性哈希算法(consistent hashing)
转载请说明出处:http://blog.csdn.net/cywosp/article/details/23397179 一致性哈希算法在1997年由麻省理工学院提出的一种分布式哈希(DHT) ...
随机推荐
- WebView的使用--Hybrid App
App页面是运行在WebView中的,一个App页面对应一个WebView,本例实现两个WebView之间的跳转. 实现过程(用到了MUI框架): 1.页面标识+跳转按钮(index.html.mai ...
- linux系统文件扩展名介绍
1.源码tar.tar.gz .tgz.zip.tar.bz 表示压缩文件,创建命令等 2.sh表示shell脚本文件,通过shell语言开发的程序. 3.pl 表示perl语言文件,通过perl语言 ...
- Net 面试随想
佳节已去,至今已半月有余,近来园中唱衰net的声音幽幽而起,net不成熟的大环境一直被作为诟病,net core的跨平台去年抄的火热,是否为net 崛起的最后一根稻草,结合我面试的情况,作为小白,嘟囔 ...
- python文件基本操作(读,写,追加)
一:只读(r) f=('d:\ python的联系文件'') 绝对路径和相对路径(绝对路径:能找到文件开始到结束路径,真实存在的路径,相对路径:在绝对路径一致的情况下新建一个文件) f=open( ...
- .net core实现redisClient
引言 最近工作上有需要使用redis,于是便心血来潮打算自己写一个C#客户端.经过几天的努力,目前该客户端已经基本成型,下面简单介绍一下. 通信协议 要想自行实现redisClient,则必须先要了解 ...
- python解决图的最短路径问题
在hihoCoder上遇到一个算法题目,描述如下: 对图结构有了解的不难发现,这是经典的求图的最短路径问题.以下是python代码: def findMin(row): minL = max(row) ...
- selenium 基础(一)
selenium安装 pip install selenium selenium操作浏览器原理 早期selenium 1.0 用的selenium RC, 后来selenum2集合了selenium1 ...
- 《Linux命令行与shell脚本编程大全》- 读书笔记2 - 更多的bash shell命令
更多的bash shell命令 想检测进程,需要熟悉ps命令的用法.ps命令好比工具中的瑞士军刀,它能输出运行在系统上的所有程序的许多信息.默认情况下,ps命令只会显示运行在当前控制台下的属于当前用户 ...
- C语言第九次博客作业--指针
一.PTA实验作业 题目1:两个4位正整数的后两位互换 1. 本题PTA提交列表 2. 设计思路 定义循环变量i,两个数组a[4],b[4] for i=0 to 3 a[i]*p取各个位 *p/=1 ...
- 简单使用git和github来管理代码----配置与使用
在以前没听说过github之前,自己写的代码很容易丢或者遗失,等到用时才知码到用时方恨丢,现在用了github,真的是替自己生省不少的事,闲话不多说,上教程. 1 在github上注册账号 https ...