Redis是一个基于内存的键值类型的nosql数据库
在大数据领域,主要使用 单机结构和 分片集群
但是单点Redis会存在以下几种问题:
- 存储能力问题
- 并发能力问题
- 单点故障问题
- 数据恢复问题
根据以上几点,Redis给出了解决防范
- 存储能力问题 分片集群
- 并发能力问题 主从集群
- 单点故障问题 哨兵集群
- 数据恢复问题 持久化
数据恢复问题
1.1 Redis 持久化之RDB持久化
将redis内存中的数据,全都保存到磁盘当中
触发条件:
主动触发 :
-
save命令 主进程去保存数据,其他请求不接收,会堵塞
-
bgsave命令 子进程fork主进程,子进程会共享主进程的内存数据,不会堵塞
fork采用的是copy-on-write技术:
当主进程执行读操作时,访问共享内存;
当主进程执行写操作时,则会拷贝一份数据,执行写操作。 -
满足RDB条件触发
-
redis关机时执行
RDB条件:
Redis内部有触发RDB的机制,可以在redis.conf文件中找到,格式如下:
# 900秒内,如果至少有1个key被修改,则执行bgsave , 如果是save "" 则表示禁用RDB
save 900 1
save 300 10
save 60 10000
1.2 Redis 持久化之AOF 持久化
在两次RDB持久化之间,很可能出现数据丢失问题,因此在两次RDB持久化之间,增加了日志,存储持久化世界内的事务性操作,看是AOF持久化
将事务性操作 增删改操作写入日志当中
AOF默认是关闭的,需要修改redis.conf配置文件来开启AOF:
# 700行 是否开启AOF功能,默认是no
appendonly yes
# AOF文件的名称
appendfilename "appendonly.aof"
AOF的命令记录的频率也可以通过redis.conf文件来配:
- appendfsync always 每执行一次写命令,立即记录到AOF文件
- appendfsync everysec 每过1秒从缓冲区中把事务性操作写入日志中
-
appendfsync no 执行完命令AOF会存入缓冲区,由操作系统决定何时将缓冲内容写入磁盘
image.png
ADF与AOF对比
企业当中这两个配合使用
并发能力问题
主从架构实现读写分类,通常读的的压力比写的压力大,类似双十一都在疯狂浏览商品信息.
主从架构解决的是读的并发,没有解决写的高并发
单节点Redis的并发能力是有上限的,要进一步提高Redis的并发能力,就需要搭建主从集群,实现读写分离。
image.png
使用主从集群,一个master接收读写请求,多个slave接收读请求.实现读写分类,然后数据同步到其他机器
主从机器内的数据都是一样的,每个节点访问的数据都是一样的,类似于zk.
三个实例没有任何关系,配置主从:replicaof
或slaveof
(5.0以前)命令,有临时和永久两种模式
多台redis机器声明ip,指定主从
故障恢复问题
Redis提供哨兵(Sentinel)机制来实现主从集群的自动故障恢复
哨兵集群的功能:
- 监视: 监视每个节点是否正常, 哨兵集群会跟每个节点保持心跳,给每个节点发送ping命令,看是否接收到pong命令,
如果一个sentinel 接收不到会认为主观下线,
当半数sentinel接收不到pong响应,是客观下线 - 自动故障恢复:
1.如果master故障,sentinel会先指定一个备选的slave,让其执行slaveof no one命令使其成为主节点
2.给其他节点发送slaveof 现主节点ip ,让这些slave成为新master的从节点,开始从新master上同步数据
3.最后sentinel会把之前故障的主节点,标记为从节点,当其恢复后从新主节点同步数据 -
通知: 当集群发生故障转移时,sentinel会将最新信息推送给Redis的客户端
image.png
存储能力问题
redis提供了分片集群用于解决海量存储和高并发写的问题
分片集群,解决了高并发,容错,存储等问题.其他集群模式在公司可能回是过度模式.
原理:
- 集群内有多个master 节点,每个节点保持不同的数据
- 一个master又用于多个salve节点
- master之间通过ping监测彼此健康状态
- 客户端请求可以访问集群任意节点,最终都会被转发到正确节点
相当于多个 主从集群 组成一个大的集群
问题1: 多个master,客户端发送的请求是怎样分配给哪个master的?
redis会把数据映射到插槽上,共有0~16383共16384个插槽(hash slot)上,把插槽平均分给每个master个
根据每个key的值的通过crc 转换成整形 然后hash取余 ,根据余数分配到,拥有该卡槽的 master
image.png
问题2 如何将同一类数据固定的保存在同一个Redis实例?
数据key不是与节点绑定,而是与插槽绑定。redis会根据key的有效部分计算插槽值,分两种情况:
key中包含"{}",且“{}”中至少包含1个字符,“{}”中的部分是有效部分
key中不包含“{}”,整个key都是有效部分
key中有{}就只读{}内的内容.
key= {user1}123456
一类数据使用相同的有效部分,如key都以{typeId}为前缀
网友评论