zoukankan      html  css  js  c++  java
  • 01--是时候让我们谈谈一致性hash了

     

    ---------------------

    假如你有图中三个盒子,我们有代号为 1,4,5,12 这四样东西 那根据代号作为主键,将东西放到盒子了,该如何放置?

    我们可以对代号取模 1 mod 3 = 1   4 mod 3 = 1    5 mod 3 = 2  12mod 3 = 0

    这样的话 大家就可以分配好到对应到盒子里

      1 #!/usr/bin/env python
      2 
      3 box0 = []
      4 box1 = []
      5 box2 = []
      6 box_home = {
      7             '0':[],
      8             '1':[],
      9             '2':[],
     10         }
     11 res = [1,4,5,12]
     12 
     13 for i in res:
     14     key = i % 3
     15     if key == 0:
     16         box_home[str(key)].append(i)
     17     elif key == 1:
     18         box_home[str(key)].append(i)
     19     elif key == 2:
     20         box_home[str(key)].append(i)
     21 
     22 for k,v in box_home.items():
     23     print k,v
    ~                      
    

      

    代码如上

    -------------------------------------------------------------

    但是如果现在加一个盒子 。

    就变成这样了

    那么现在就要取模为4了 之前箱子里面的东西都要重新计算重新,重新摆放。

    这在很多场景是不能够接受的,比如负载均衡,我不能因为重新加了一个节点,让所有用户的长链接都断开,重新链接。

    或许这种还能接受,那么如果是分布式存储呢?

    所以这个时候我们不能够这样做。这样子都服务就不是无状态都服务。

    这个时候就是一致性hash派上用场的时候了。

    我们可以在刚刚分配的时候预留很多空位置。

    圆形就是是空,矩形就是有箱子的。我们可以在一开始就留很多空白多地方 ,如图上

    我们一开始有三个节点,但是我们会分配5个位置,然后有数据就mod6,如果数据分配到到是没有节点到位置

    那么我就就把这个数据放到下一个有节点到位置,比如图上我们要分配到是 数据8 那么8mod6 = 2 此时位置2上没有节点。那么将这个数据到下一个有节点到位置

    也就是位置3。如果是mod到是最后一个那么就从头开始,也就是说,位置是环形的。

    如有新的节点加入,那么直接放到空的位置上,然后将之前的分配在这个位置上的数据转移上去即可,这样子就能避免重新分配。

    我们可以通过代码模拟分配情况

    #!/usr/bin/env python
    #coding:utf-8
    
    class Node():
        def __init__(self,data,next_node = None,node_type = 'body',is_online=0):
    
            self.data = data
            self.next_node = next_node
            self.is_online = is_online
            self.node_type = node_type
            self.self_data = []
            self.other_data = []
    
        def get_next_node(self):
            return self.next_node
        
        def set_next_node(self,next_node):
            self.next_node = next_node
            return True
    
        def set_node_status(self,num):
            self.is_onlie  = num
    
        def get_data(self):
            return self.data
    
    class boxs():
        def __init__(self,head=None):
            self.head_node = head
            self.size = 0
            self.ser_node = None
    
        def add_None(self,data,num):
            if self.head_node == None:
                self.head_node =Node(data,is_online=num)
                self.scr_node = self.head_node
                self.size +=1
            else:
                new_node = Node(data,is_online=num)
                self.scr_node.set_next_node(new_node)
                self.scr_node = new_node
                self.size +=1
            
        def print_list(self):
            curr = self.head_node
            while curr :
                print '-----------------------'
                print curr.data,'--->',curr.node_type,"---->",curr.is_online
                print "data:",curr.self_data
                print "other_data",curr.other_data
               
                if curr.node_type != 'body':
                    break
                else:
                    curr = curr.get_next_node()
    
        def set_ass_node(self,data,num):
            new_node = Node(data,node_type='tail',is_online=num)
            new_node.type = 'tail'
            self.scr_node.set_next_node(new_node) 
            new_node.set_next_node(self.head_node)
    
        def insert_data(self,key,dick_len):
            curr = self.head_node
            while curr:
                if key % dick_len == curr.data:
                    if curr.is_online == 1:
                        curr.self_data.append(key)
                    else:
                        while 1:
                            curr = curr.get_next_node()
                            if curr.is_online == 1:
                                curr.other_data.append(key)
                                break
                         
                    break
                else:
                    curr  = curr.get_next_node()
    
        def set_node_allot(self,key_dict,dick_len):
            for  key in key_dict:
                self.insert_data(key,dick_len)
    
    #设置节点种有盒子的节点            
    online_node = [1,3,5]
    
    #实例化链表
    mylist  = boxs()
    
    #添加节点,如果节点数属于online_node的节点 那么就设定他在线
    for i in range(7):
    
        now_status = 0
        if i in online_node:
            now_status =1
          
        if i <6:
            mylist.add_None(i,now_status)
        else:
         
            mylist.set_ass_node(6,now_status)
    #模拟数据
    key_dict = [2,3,5,6,12,22,23,33]
    
    #分配数据
    mylist.set_node_allot(key_dict,len(key_dict)-1)
    
    #打印分配情况
    mylist.print_list()
    

      

  • 相关阅读:
    使用Visual Studio 2012 开发 Html5 应用
    模块化与MVC
    跨站脚本攻击(Cross‐Site Scripting (XSS))
    C#程序开发中经常遇到的10条实用的代码
    运用DebugDiag诊断ASP.Net异常
    前端MVVM框架avalon
    TOGAF架构开发方法(ADM)之需求管理阶段
    C#4.0中var和dynamic的区别
    hive 不同用户 权限设置 出错处理
    Delphi中类的运行期TypeInfo信息结构说明
  • 原文地址:https://www.cnblogs.com/nerdlerss/p/8967647.html
Copyright © 2011-2022 走看看