笔记-关于Redis集群和Redis持久化
- 一. redis集群
- 1.1 redis的哈希槽
- 1.1.1 集群中的哈希槽分配
- 1.1.2 集群的增删节点
- 1.2 一致性哈希
- 1.2.1 为什么要用一致性哈希
- 1.2.2 一致性哈希算法的原理
- 如果删除一个节点
- 如果新增一个节点
- 1.2.3 数据分布不均
- 二. redis持久化
- 2.1 RDB方式
- 触发持久化的方式:
- 2.2 AOF的方式
- 重写:
- 2.3 两者的对比
一. redis集群
- redis集群默认是读写都在master上处理
与其他主从架构的读写分离不一样, 因为redis本身更推荐master的横向扩展 - redis的master收到请求后, 计算哈希槽对应的节点, 如果是自己就自己处理, 如果不是则会让客户单重定向到目标master
1.1 redis的哈希槽
在redis集群中,怎么确定新增的数据添加到哪个实例中去呢?
这个时候就涉及到哈希槽的概念。
1.1.1 集群中的哈希槽分配
redis默认初始化了16384(2的14次方)个哈希槽。在新增一个key-value的时候,redis会计算key的哈希值(crc16),然后对16384取余数,得到这个key所对应的哈希槽,然后按照范围分配到相应的redis实例中。
1.1.2 集群的增删节点
redis没有采用一致性哈希, 而是手动配置哈希槽区间映射节点
因为哈希槽的存在,所以增删节点,只需要迁移部分数据就可以,如果分配规则是按照实例个数进行取模的话,增删节点都会导致实例个数变化,也就是所有数据的映射关系变化。
1.2 一致性哈希
在分布式系统做负载均衡,或者集群处理请求,一般是通过哈希求余数的算法来确定将请求交给哪个节点处理。
1.2.1 为什么要用一致性哈希
也就是 hash(key)% 实例个数
,但是这个算法伸缩性和拓展性很差。如果想要增加节点或删除节点,都会导致公式的实例个数变化,也就导致映射关系失效。
1.2.2 一致性哈希算法的原理
其实一致性哈希算法,重点就是一个均匀布满了槽位的哈希环。
- 有一个哈希环,有2的32次方的槽位均匀分布在环上
- 将集群(或者分布式系统)中的机器的名称(或者ip地址)进行hash函数得到一个值,然后对2的32次方取模后,就会落在环上的槽位上
- 这样来了一个请求时,将请求的某个属性也进行hash函数,并对2的32次方取模,同样会对应一个槽位。
- 将这个请求分配给按顺时针寻找到的第一个节点处理
如果删除一个节点
删除节点,此时原本应该分配到该节点的请求,根据哈希环顺延到下一个节点。其他位置的不受影响,不会造成所有的映射关系失效的问题
如果新增一个节点
在新增一个节点后,哈希算法得出的新节点的哈希槽,则从这个节点位置开始,逆时针遇到的第一个节点的位置为止,这段原本应该由顺时针后面的一个节点处理,现在由新节点处理
受影响的数据仅仅是新服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它数据也不会受到影响
1.2.3 数据分布不均
当节点比较少的时候,可能会出现两个节点的哈希槽位置相近,这就导致两个节点接受的请求和数据不均
虚拟节点
为了解决这个问题,可以给每个节点计算多个哈希,比如在IP地址或者服务器名后面加序号,得到多个虚拟的哈希槽位
二. redis持久化
redis的持久化有两种,RDB(redisDatabase,默认),和AOF(Append Only File)
2.1 RDB方式
RDB是默认的redis持久化的方式。在指定的间隔时间内,如果达到了指定的修改数量,则会把内存中的数据存到硬盘中
save <seconds> <changes>
# save ""
save 900 1
save 300 10
save 60 10000
满足下面的条件就触发:
- 900秒内有1次修改
- 300秒内有10次修改
- 60秒内有10000次修改
触发持久化的方式:
- 上面描述的,指定间隔时间内,达到了指定的修改数量
- 手动调用命令
save
阻塞的,和bgsave
(backgroundSave)子进程处理,不阻塞 -
shutdown
关闭的时候
2.2 AOF的方式
AOF是为了弥补RDB的不足而产生的,因为RDB不能保证数据的强一致性,AOF会采用日志的形式记录写操作,恢复数据的时候会重新执行一遍所有的写命令
# appendfsync always
appendfsync everysec
# appendfsync no
AOF可以设置属性ppendfsync
,always是实时同步,everysec是每秒同步。always实时同步会因为频繁的io导致效率降低,默认是everysec每秒同步
当AOF文件达到一定大小的时候,会触发**重写(rewrite)**的操作。
重写:
将当前内存中的最新数据,转成set命令写入新的aof临时文件。然后改名替换原文件
因为重写是最新的数据,所以比原来的aof文件,少了过期的数据,少了删除命令,同时对同类型操作的数据合并成一条命令,有效的减小了文件大小。
触发机制
当aof文件达到上一次rewrite文件的一倍大,且文件大于64M的时候
2.3 两者的对比
RDB | AOF |
数据一致性比较弱,实时性比较差,可能因为实例宕机丢失数据 | 数据一致性强,同步记录频繁 |
存储的是二进制文件 | 存储的是基于命令的文本文件 |
适合大量数据的备份和恢复,redis加载RDB文件速度快 | 数据量大的话,因为是一条条命令执行,会影响数据恢复的效率 |
可以进行压缩,文件相对原数据小 | 文件大 |