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) ...
随机推荐
- n人围成一圈报数
题目:有n个人围成一圈,顺序排号.从第一个人开始报数(从1到3报数),凡报到3的人退出圈子,问最后留下的是原来的第几号的那位 思路:用一个数组存这n个人,里面的初始状态全设为1,表示都还在圈子里面. ...
- css图片的相关操作
css图片的相关操作 1.案例源码 <!DOCTYPE html><html lang="en"><head> <meta charset ...
- 基于puppet分布式集群管理公有云多租户的架构浅谈
基于puppet分布式集群管理公有云多租户的架构浅谈 一.架构介绍 在此架构中,每个租户的业务集群部署一台puppet-master作为自己所在业务集群的puppet的主服务器,在每个业务集群所拥 ...
- 【BZOJ3196】二逼平衡树(树状数组,线段树)
[BZOJ3196]二逼平衡树(树状数组,线段树) 题面 BZOJ题面 题解 如果不存在区间修改操作: 搞一个权值线段树 区间第K大--->直接在线段树上二分 某个数第几大--->查询一下 ...
- 【BZOJ1004】Cards(组合数学,Burnside引理)
[BZOJ1004]Cards(组合数学,Burnside引理) 题面 Description 小春现在很清闲,面对书桌上的N张牌,他决定给每张染色,目前小春只有3种颜色:红色,蓝色,绿色.他询问Su ...
- 对网易云音乐参数(params,encSecKey)的分析
我们如果对网易云音乐进行爬虫的话,我们会发现,提交的参数是(params,encSecKey),然而这两个参数是一串很长的东西 我们要对网易云进行爬虫,那么就一定要将这两个参数弄明白,然后才可以进行爬 ...
- 九度OJ题目1105:字符串的反码
tips:scanf,cin输入字符串遇到空格就停止,所以想输入一行字符并保留最后的"\0"还是用gets()函数比较好,九度OJ真操蛋,true?没有这个关键字,还是用1吧,还是 ...
- vue.js 视频播放
最近心学习vue.js开发,video开发播放! 使用第三方的封装:https://www.npmjs.com/package/vue-video-player: 1. npm install vue ...
- Java反射总结
一. 获取Class对象的3种方法: 1. Class.forName("");例如:Class.forName("java.lang.String"); 2. ...
- 关于classpath
classpath是用来设计JAVA类文件(.class)所在的路径 classpath的主要作用就是当你在一个shell窗口下执行命令时,可以从在classpath中设置的目录搜索,不用一层再一层的 ...