笔记-关于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集群

  1. redis集群默认是读写都在master上处理
    与其他主从架构的读写分离不一样, 因为redis本身更推荐master的横向扩展
  2. 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 一致性哈希算法的原理

其实一致性哈希算法,重点就是一个均匀布满了槽位的哈希环。

redis集群和redission redis集群和持久化_redis

  1. 有一个哈希环,有2的32次方的槽位均匀分布在环上
  2. 将集群(或者分布式系统)中的机器的名称(或者ip地址)进行hash函数得到一个值,然后对2的32次方取模后,就会落在环上的槽位上
  3. 这样来了一个请求时,将请求的某个属性也进行hash函数,并对2的32次方取模,同样会对应一个槽位。
  4. 将这个请求分配给按顺时针寻找到的第一个节点处理
如果删除一个节点

删除节点,此时原本应该分配到该节点的请求,根据哈希环顺延到下一个节点。其他位置的不受影响,不会造成所有的映射关系失效的问题

如果新增一个节点

在新增一个节点后,哈希算法得出的新节点的哈希槽,则从这个节点位置开始,逆时针遇到的第一个节点的位置为止,这段原本应该由顺时针后面的一个节点处理,现在由新节点处理

redis集群和redission redis集群和持久化_持久化_02

受影响的数据仅仅是新服务器到其环空间中前一台服务器(即沿着逆时针方向行走遇到的第一台服务器)之间数据,其它数据也不会受到影响

1.2.3 数据分布不均

redis集群和redission redis集群和持久化_数据_03

当节点比较少的时候,可能会出现两个节点的哈希槽位置相近,这就导致两个节点接受的请求和数据不均

虚拟节点

为了解决这个问题,可以给每个节点计算多个哈希,比如在IP地址或者服务器名后面加序号,得到多个虚拟的哈希槽位

redis集群和redission redis集群和持久化_集群_04

二. 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次修改
触发持久化的方式:
  1. 上面描述的,指定间隔时间内,达到了指定的修改数量
  2. 手动调用命令save阻塞的,和bgsave(backgroundSave)子进程处理,不阻塞
  3. 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文件速度快

数据量大的话,因为是一条条命令执行,会影响数据恢复的效率

可以进行压缩,文件相对原数据小

文件大