在说redis中的哈希(准确来说是一致性哈希)问题之前,先来看一个问题:为什么在分布式集群中一致性哈希会得到大量应用?
在一个分布式系统中,要将数据存储到具体某个节点,或者将来自客户端的请求分配到某个服务器节点做负载均衡,如果采用普通的hash取模算法进行映射,即如key.hashCode()%N,key代表数据的key,N是服务器节点数,使用上能达到预期效果。
但是如果此时要下线一个服务器或者上线一个新的服务器,那么原来的映射将全部失效。如果是做分布式存储,则需要做数据迁移;如果是做分布式缓存,则原来的缓存失效,需要让新增或下线的节点生效就需要做rehash,数据较大会比较消耗时间(其实这点对HashMap了解的,很熟悉这一点,HashMap在动态扩容进行rehash,数据量过大时很消耗时间影响性能)。这时,一致性哈希就派上用场了。
下面通过几个问题逐步介绍redis2.X和redis3.X中的一些特性,来了解一致性哈希在redis中的应用,以及遇到的问题,不同版本是如何解决的。
1.假如有两台redis服务器,jedis客户端要存入数据到这两台服务器,它如何知道要存入哪台服务器?
这个就是开篇所说一般的做法:哈希取模。key.hashcode() % nums(key是redis中的key,nums是redis服务器数)最终结果范围:0到nums-1
2.此时新增一台redis服务器,数据能写入到新增的机器上吗?
不能。还是对原有redis服务器数进行取模。
那么如何解决这一问题呢?nums不定义为redis服务