分布式中hash取模算法中的问题

分布式中hash取模算法中的问题

常用的算法是对hash结果取余数 (hash() mod N):对机器编号从0到N-1,按照自定义的hash()算法,对每个请求的hash()值按N取模,得到余数i,然后将请求分发到编号为i的机器。

但这样的算法方法存在致命问题,如果某一台机器宕机,那么应该落在该机器的请求就无法得到正确的处理,这时需要将当掉的服务器从算法从去除,此时候会有(N-1)/N的服务器的缓存数据需要重新进行计算;”

为何是 (N-1)/N 呢?解释如下:

比如有 3 台机器,hash值 1-6 在这3台上的分布就是:
host 1: 1 4
host 2: 2 5
host 3: 3 6
如果挂掉一台,只剩两台,模数取 2 ,那么分布情况就变成:
host 1: 1 3 5
host 2: 2 4 6

可以看到,还在数据位置不变的只有2个: 1,2,位置发生改变的有4个,占共6个数据的比率是 4/6 = 2/3这样的话,受影响的数据太多了,势必太多的数据需要重新从 DB 加载到 cache 中,严重影响性能

【一致性hash 的办法】
上面提到的 hash 取模,模数取的比较小,一般是负载的数量,而 consistent hashing 的本质是将模数取的比较大,为 2的32次方减1,即一个最大的 32 位整数。然后,就可以从容的安排数据导向了,那个图还是挺直观的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
雪花算法是一种用于生成分布式系统唯一ID的算法,其workerid是其的一个组成部分。workerid是一个标识符,用于标识每个分布式系统的节点或进程。下面是一个简单的雪花算法workerid生成算法的实现: ```python import socket import threading class SnowflakeWorker(object): def __init__(self): self.worker_id = self.get_worker_id() self.last_timestamp = -1 self.sequence = 0 def get_worker_id(self): hostname = socket.gethostname() return abs(hash(hostname)) % (2 ** 10) def get_timestamp(self): return int(round(time.time() * 1000)) def get_id(self): timestamp = self.get_timestamp() if self.last_timestamp > timestamp: raise Exception("Clock moved backwards. Refusing to generate id for %d milliseconds" % (self.last_timestamp - timestamp)) if self.last_timestamp == timestamp: self.sequence = (self.sequence + 1) % 4096 if self.sequence == 0: timestamp = self.wait_next_millis(timestamp) else: self.sequence = 0 self.last_timestamp = timestamp return ((timestamp - 1609459200000) << 22) | (self.worker_id << 12) | self.sequence def wait_next_millis(self, last_timestamp): timestamp = self.get_timestamp() while timestamp <= last_timestamp: timestamp = self.get_timestamp() return timestamp worker = SnowflakeWorker() print(worker.get_id()) ``` 该算法使用了当前时间戳、节点的worker_id和一个自增的序列号来产生唯一ID。其,worker_id是通过对当前机器的主机名进行哈希后取模得到的,保证了不同节点之间的worker_id不同。同时,序列号用于解决同一毫秒内并发生成ID可能会发生冲突的问题。在生成ID时,如果当前时间戳小于上一次生成ID的时间戳,则说明时钟回拨了,需要等待时钟同步后再生成ID。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值