Redis进阶
RDB(Redis DataBase)
概念
在指定时间间隔内将内存中的数据集快照写入磁盘
流程
Redis 会单独创建(fork)一个子进程来进行持久化,会先将数据写入到一个临时文件,
待持久化过程结束,再用临时文件替换上次持久化好的文件,默认 dump.rdb
优缺点
优点:
整个过程中,主进程不进行任何 IO 操作,这就确保了极高的性能
如果对数据恢复的完整性不敏感,那么比 AOF 更加高效。
节省磁盘空间,恢复速度快
缺点:
- 最后一次持久化后的数据可能丢失
- 虽然使用了写时复制技术,但是如果数据庞大还是比较消耗性能
- Fork 的时候内存中的数据被克隆一份,大致 2 倍的膨胀性需要考虑
Fork
Fork 的作用是复制一个与当前进程一样的进程,所有的数据均一致,
但是是一个全新的进程,并作为原进程的子进程
写时复制技术
一般情况父进程和子进程共用一段物理内存
AOF(Append Only File)
概念
以日志的形式来记录每个写操作(增量保存),
将 Redis 执行过的所有写指令记录下来(读操作不记录),
只许追加文件但不可以改写文件,Redis 启动时会读取文件重构数据
流程
- 客户端的请求写命令会被 append 追加到 AOF 缓冲区内
- AOF 缓存区根据 AOF 持久化策略将操作 sync 同步到磁盘 AOF 文件
- AOF 文件大小超过重写策略或手动重写时,进行 rewrite 重写和压缩
- Redis 服务启动时,会重新加载 AOF 文件中的写操作恢复数据
设置
- AOF 默认不开启,需要在配置文件中将
appendonly
改为yes
- AOF 和 RDB 同时开启时,系统默认取 AOF 的数据(数据不会存在丢失)
- 异常通过
redis-check-aof --fix appendonly,aof
恢复文件,重启即可 - 同步频率设置 appendfsync:
- always:始终同步,每次 Redis 的写入都会立刻记入日志,完整性好但性能差
- everysec:每秒同步,如果宕机,本秒的数据可能丢失
- no:不主动进行同步,把同步时机交给操作系统
- Rewrite 压缩:避免 AOF 文件过大,采用重写机制,将内容压缩
- AOF 默认不开启,需要在配置文件中将
优缺点
优点:
- 备份机制更稳健,丢失数据概率更低
- 可读的日志文本,可以处理误操作
缺点:
- 占用更多的磁盘空间
- 恢复备份速度慢
- 每次读写都同步的话,存在一定的性能压力
- 存在个别 bug,造成恢复不能
对比
- 官方推荐两个都启用
- 如果对数据不敏感,可以单独使用 RDB
- 不建议单独使用 AOF,可能会出现 bug
- 如果只是做纯内存缓存,可以都不用
主从复制
概念
主机数据更新后根据配置和策略,自动同步到备机的 master/slaver 机制,
master 以写为主,slaver 以读为主,但是会存在复制延时的情况,
当系统繁忙或 slaver 机器数量增加的时候,延迟问题会更加严重
作用
- 读写分离,性能拓展
- 容灾快速恢复
搭建简单的一主两从
创建
/myRedis
文件夹,拷贝redis.Windows.conf
文件至目录下配置一主两从,创建三个配置文件
1
2
3redis6379.conf
redis6380.conf
redis6381.conf在每个配置文件中写入以下内容(替换 6379 即可)
1
2
3
4include redis.windows.conf
pidfile /var/run/redis_6379.pid
port 6379
dbfilename dump6379.rdb启动三个 Redis 服务
- 查看当前主机运行状况
- 在从机上执行
slaveof
主机 ip 端口号 SLAVEOF 127.0.0.1 6379
配置主从关系- 验证主从的基本性质,master 以写为主,slaver 以读为主
主从复制特点
- 一主二仆
- 薪火相传
- 反客为主
哨兵模式
反客为主的自动版,能够后台监控主机是否故障,根据投票数将从库转为主库
模拟案例
建立一个简易的一主二仆模式
在
/myRedis
目录下建立sentinel.conf
文件写入
sentinel monitor mymaster 127.0.0.1 6379 1
mymaster
为监控对象起的名称,1
为至少有多少个哨兵同意迁移的数量如果你使用
redis-sentinel
可执行文件,你可以使用下面的命令来运行Sentinel
:1
redis-sentinel /path/to/sentinel.conf
另外,你可以直接使用
redis-server
并以Sentinel
模式来启动:1
redis-server /path/to/sentinel.conf --sentinel
将主机关闭,查看结果即可
选择条件依次如下
- 选择优先级靠前的(redis.conf 中的 slave-priority 值越小优先级越高)
- 选择偏移量最大的(获得最全原主机数据的从服务)
- 选择 runid 最小地从服务(每个 Redis 启动后随机生成的 40 位 runid)
集群
概念
Redis 集群实现了对 Redis 的水平扩容,即启动 N 个 Redis 节点,
将整个数据库分布存储在这 N 个节点中,每个节点存储总数据的 1/N,
集群通过分区来提供一定程度的可用性,即使集群中有一部分节点失效或者无法进行通讯,
集群也可以继续处理命令请求
搭建简易集群
在目录下创建六份实例
redis.conf
在主从的基础上,添加以下内容(替换 6379 即可)
1
2
3cluster-enabled yes
cluster-config-file nodes-6379.conf
cluster-node-timeout 15000启动六个 Redis 服务,将节点合成一个集群
启动服务后,确保所有的
nodes-xxxx.conf
文件生成正常1
redis-cli --cluster create --cluster-replicas 1 127.0.0.1:6379 127.0.0.1:6380 127.0.0.1:6381 127.0.0.1:6389 127.0.0.1:6390 127.0.0.1:6391
通过任意节点进入集群
redis-cli.exe -p 6379
查看集群节点信息
cluster nodes
如何分配节点
--cluster-replicas 1
表示为集群中的每个主节点创建一个从节点分配原则尽量保证每个主数据库运行在不同的 IP 地址,每个主库和从库不在一个 IP 地址上
插槽 Hash Slot
一个集群包含
16384
个插槽,数据库中的每个键都属于其中一个,集群使用公式
CRC16(key) % 16384
来计算 key 属于哪个槽,而集群中的每个节点负责处理一部分插槽
故障恢复
如果主节点宕机,从节点根据超时时间自动升为主节点
主节点恢复后,主节点变成从机
如果所有某段插槽的主从节点都宕机,
集群根据
cluster-require-full-coverage
是否宕机
优缺点
优点:
- 实现扩容
- 分摊压力
- 无中心配置相对简单
缺点:
1. 多键操作是不支持的
2. 多键的 Redis 事务是不被支持的,lua 脚本不被支持
3. 出现较晚,目前整体迁移复杂度较大