/首页
/开源
/关于
我所认知的redis(三)--- 哈希一致性与集群
发表@2018-09-13 09:15:21
更新@2023-01-21 22:47:40
##### 单点redis的性能和容量总是有个极限的。 ##### 假如你们有一台redis专门用来存储用户信息缓存,key都是user:uid这个规则,value是hash类型,那么当你们有5000万用户的时候,这台redis里就理论上就满员存储5000万个用户信息,从user:1... ...到user:500000。当业务发展,公司壮大,日活百万,即将上市的时候,你发现这台redis的QPS实在是不行了,达到极限了,业务会卡,而且机器内存已经很大很大了不太容易再继续升级了,拍了拍脑袋:这都快上市了,我自己都快身价过亿了,还买不起服务器?于是,你申请费用又加一台redis服务器,最终目的要实现: - 两台redis分别承担50%的请求 - 两台redis分别存储50%的数据 ##### 这个专业术语叫做数据分片。 ##### 能够将这些key值均匀打散的办法,你自己还是有一些想法的,你灵机一动:从1到250000在第一台redis服务器,从250001到500000在第二台redis服务器。果断开始改代码,改到三分之一,突然大脑回路又清晰了:妈蛋!用户是不断增长的,刚才只想到了已有的前500000用户,尴尬,代码一顿回滚。 ##### 吃顿饭功夫,你突然大脑灵光一闪,想起来小学数学老师教给自己的余数,没想到小学学到的知识现在终于用上了! ##### 将这个思路带入到redis中去,这样1号用户将会1 mod 2=1号redis服务器,2号用户将会2 mod 2=0号redis服务器上,3号用户将会3 mod 2=1号redis服务器上去...依次类推,即便是不断地在新增用户,这个算法依然可以妥妥地将用户以50%的比例平均分布到两台redis上去! ##### 代码一顿改,开发,测试,上线。 ##### 过了半个月,突然有人说有一些用户动态内容也要缓存到redis中,但是这些动态的id都不是数字的,都是字母数字混合的uuid,没法办法用做余数计算,好尴尬! ##### 得想个办法把任何数据类型转换成数字或者一个可标记的存储位置,而且各种不同数据类型在转换完毕后还得均匀。如果转换算法不好导致十万个uuid在转换完毕后大量集中在某个区域,其他区域很少,这就不均衡了,这种不均衡会导致redis中存储的数据量也会不均衡,这不公平。 ##### (tips:实际上取余就是最简单的哈希算法了,只不过你用了但你不知道。但是取余有个很大的问题,就是数据不均匀,及其容易产生冲突,两个不同的关键字很容易就被映射到同一个索引位置上)。 ##### 网上资料一顿搜,你发现了解决这个问题的办法:哈希。简单地说,哈希算法就是通过把给定的关键字key通过某种映射算法映射到数组的一个位置上,从而可加快访问速度。一个好的哈希算法可以将每个关键字都均匀的分布到哈希表(你依然可以用数组来想象)的任意一个位置上,同时极大程度避免并与其他已被映射过的关键字的位置不发生冲突。 ##### 世界是美好的,一些可爱的计算机界的大神们历经多年发明了一个叫做DJBX33A的hash算法,这个算法用如下寥寥几行php代码就可以实现: ```php