保护私人版权,尊重他人版权。转载请注明出处并附带页面链接
背景
某一天,随着业务的发展,MYSQL负载越来越高,nginx和php已经忍不住疯狂吐槽了,阻塞了大量进程,MYSQL也都一天24小时的在处理查询、插入、更新操作;没过几天,数据库老头就罢工了
单机redis
于是,操作系统老大引入了redis小生,将MYSQL数据库和redis分别放到不同的机器上,业务查询访问MSYQL数据库前先访问redis判断是否能命中缓存,如果能够的话那么就直接从redis出获取,如果没有命中redis缓存再去MYSQL获取数据,并将数据缓存redis中,方便下次访问。。。。哎呀实在编不下去了。
业务访问redis的过程如下:
1 | 应用程序 1 |
随着业务量的增大业务结构就会变成下面这样:
1 | redis 1 |
如果你仔细想想就会发现当应用程序将key1写到redis1后再次获取的时候一般不知道到底是那台机器获取,那么这时候就需要有一个规则让应用程序知道key1存在那个redis机器了。
PS:什么是hash算法
所谓hash,一般是一个整数,通过某种算法,可以把一个字符串”压缩” 成一个整数,这个数称为hash,当然,无论如何,一个32位整数是无法对应回一个字符串的,但在程序中,两个字符串计算出的hash值相等的可能非常小
余数算法
余数算法,顾名思义—用到余数的算法,哈哈!举个栗子:现在有3台redis服务器提供给一个应用使用,那么第一次写入(key1,value1),第二次写入(key2,value2)会有什么不一样呢?
1 | 现在有 redis-0服务器 redis-1服务器 redis-2服务器 |
但是余数算法的缺陷也是显而易见的,当再增加一个机器redis-3的时候,那么机器总数达到4台,取余的时候如下:
1 | (key1,value1) (key2,value3) |
对比上面两种情况,就可以看到原来写进/读取的是redis-1 ,现在已经变成redis-0;原来是redis-0机器的数据需要在redis-2读取/写入;也就是说,当我们增加机器的时候会有很多的redis key缓存失效,命中率降低,而这并不是我们希望的。。。那么还有更好的方法吗?
一致性hash算法
为了解决增加机器后,大量缓存丢失的问题,我们引入一致性hash算法,那么什么是一致性hash算法呢,他又能不能够百分百保证增删缓存服务器时缓存失效的问题呢?我们下面来看看吧:
我们画一个圆,这个圆由2^32个点构成,我们将多个redis服务器的ip或者是hostname,hash后分布在这个圆上,当然有可能不是很均匀,那么我们可以用虚拟机的方式让机器的hash均匀分布在圆上。
那么下面我们举个例子:
1 | 例如: |
拓展阅读:点此文章地址
hash槽(hash slot)
- hash 槽一共分为16348个槽,例如缓存服务器一共有三台(r1\r2\r3);那么[0,5499]槽会分布在r1,那么[5500,10999]槽会分布在r2,那么[11000,16383]槽会分布在r3。
- 那么我们现在再来试试加一个机器r4是怎么处理,按照hash槽的方式,我们将会在这个三台机器同时取出一部分到r4机器,那么就是取出[4096,5499],[9596,10999],[15096,16383],并且在新增机器的同时会将这些hash槽里面的数据迁移到新的机器,这样数据就不会丢失了。
- hash槽 “安排” redis key的方式如下:增加机器后:
1
2
3
4
5
6
7
8(key1,value1) (key1,value1) (key3,value3)
↓ ↓ ↓
CRC16(key1)%16384=5000 CRC16(key1)%16384=7000 CRC16(key1)%16384=12000
↓ ↓ ↓
0-------------------5499------------------10999--------------------16383
↓ ↓ ↓
r1 r2 r31
key1 查询-> 将会到入r4机器,同时原来数据将会迁移到r4
故障转移
其实上面说到的hash槽的方式,也就是现在redis cluster 集群的实现方式,那么既然hash槽的方式在增加机器的时候支持迁移数据,那么是不是在其中的一个服务器宕机的时候,数据服务也能够正常访问呢,答案是肯定的。完善的redis cluster 集群还会有主备,如下图:
主服务节点应该是 node A 、node B 、node C
1 | node A |
例如:当 node B 节点挂了之后,就会有某种算法将slave中的其中一个(node B1 或 node B2)选举为matser。这样就做到了故障转移了。
总结
这篇小文章写起来也是有点随意了,因为这几个月一直都在看码农翻身这本书,然后看到了关于redis的一个发展史,所以就想把这个分享给小伙伴看,然后就写了,但写下来发现提炼能力还需要提升,算是抛砖引玉吧。