Redis
- 高性能分布式内存数据库
- 非关系型数据库,数据存储在内存中
- key-value形式
- NoSql数据库之一
Redis数据结构
- String
- 单值单value
- List
- 单值多value
- 有序可重复
- Set
- 单值多value
- 无序不重复
- Hash
- value是一个键值对(类似于Map)
Zset(Sorted Set)
原子性
- 要么全部成功,要么全部失败
- 一致性
- 数据库的完整性
- 隔离性
- 多事务并发相互隔离
持久性
Redis事务基于队列实现
- 将事务操作的多个命令加入到一个队列,命令被序列化按顺序依次执行
- 加入队列时,命令不执行,无法获取数据
- 需要exec执行之后才可以获取数据
- 一个队列中,一次性按顺序串行执行所有命令
- 将事务操作的多个命令加入到一个队列,命令被序列化按顺序依次执行
- 不保证一致性
- 一条命令失败,其他命令会继续执行,不会回滚
Redis事务操作
开启事务
multi
添加操作命令
set name wyb ...
执行事务
exec
取消事务
discard
3、事务处理机制
事务原子性(要么都成功,要么都失败)
Redis对命令执行出错处理的解决方式语法错误
- 编译阶段出错
- 一个事务队列中,出现命令语法错误,执行事务exec之后,会返回错误信息,正确的命令也不执行
- 执行错误
- Redis数据存储在内存之中
- 若服务器宕机,内存中数据容易丢失
解决方案
- Redis持久化机制,将内存中数据存储到磁盘中
- 便于Redis恢复数据,避免数据意外丢失
Redis持久化机制
- RDB快照
- AOF
-
1、RDB快照
RDB(Redis DataBase)
Redis默认的存储方式
- 在指定的时间间隔内将内存中的数据集快照(压缩为二进制文件)写入磁盘
- 二进制备份文件dump.rdb
- 恢复数据时将快照文件直接读到内存里
- 将备份文件dump.rdb移到Redis安装目录并启动服务
触发RDB快照(两种方式)
配置文件中配置触发
save 秒 改变次数 save m n
- 在m秒内修改n次key,触发RDB快照
- 关闭RDB
- 取消该配置
手动触发
save #同步执行 或 bgsave #异步子线程执行(Redis默认使用)
- Redis客户端执行命令,手动触发RDB快照
- save
- 同步执行
- 只执行保存,其他命令全部阻塞,直至保存结束
- 关闭RDB
save “”
- bgsave(Redis默认使用)
- 异步执行
- fork分岔一个和主线程一致的子线程负责操作操作RDB文件
- 执行保存的同时,也可以执行其他命令
- 异步执行
RDB快照存在问题
- 二进制存储数据,会出现数据丢失问题
根据间隔时间备份数据,如果Redis宕机可能会导致最后一次快照数据丢失
2、AOF
AOF(AppendOnly File)
采用文件追加方式
- 以日志文件形式记录每一个写操作命令(不记录读操作命令)
- 记录到磁盘中的AOF文件
- appendonly.aof
- Redis重启后,读取日志文件中存储的记录,顺序执行全部写操作命令,完成数据恢复
配置AOF
配置文件中配置
appendonly yes #开启AOF
- 默认no
- 快捷方式
- /appendonly -> 查找appendonly字段
AOF文件同步到磁盘的策略
- 配置文件redis.conf文件的appendfsync属性值
always
每修改同步- 每执行一条写命令,就写入AOF文件,并将AOF文件同步到磁盘
- 宕机最多只丢失一个命令的数据
- 每执行一条写命令,就写入AOF文件,并将AOF文件同步到磁盘
everysec
(默认)每秒同步- 每执行一条写命令,就写入AOF文件,并每隔一秒将AOF文件同步到磁盘
- 宕机不超过两秒的数据
- 每执行一条写命令,就写入AOF文件,并每隔一秒将AOF文件同步到磁盘
no
不同步- 每执行一条写命令,就写入AOF文件,不将AOF文件同步到磁盘
- 操作系统完成数据同步
- 每执行一条写命令,就写入AOF文件,不将AOF文件同步到磁盘
AOF执行过程
- 命令追加
- 写命令保存到缓冲文件aof_buf的末尾
- 文件写入
- 缓冲区文件内容写入到AOF文件
- 文件同步
- 将AOF文件保存到磁盘
AOF重写优化
- 解决AOF文件存在问题
- 占用大量存储空间
- 数据还原耗时长
- 配置文件redis.conf配置触发重写
```当前aof文件大小超过上一次aof文件大小的百分之多少时进行重写。如果之前没有重写过,以
启动时aof文件大小为准 auto-aof-rewrite-percentage 100
限制允许重写最小aof文件大小,也就是文件大小小于64mb的时候,不需要进行优化
auto-aof-rewrite-min-size 64mb ```
3、RDB和AOF对比
RDB快照和AOF对比
- RDB默认开启,AOF需手动开启。
- RDB性能优于AOF。
- AOF安全性优于RDB。
- AOF优先级高于RDB。
- RDB存储某个时刻的数据快照,AOF存储写命令。
- RDB在配置触发状态会丢失最后一次快照以后更改的所有数据,AOF默认使用everysec,每秒保存一次,最多丢失两秒以内的数据。
Redis持久化机制选择方案
- 追求高性能,不关注数据安全性
- 关闭RDB快照和AOF
- Redis宕机,直接从数据源恢复数据
- 较高性能,数据安全性
- 开启RDB快照
- 更关注数据安全性
- 开启AOF
- 可同时开启RDB快照和AOF
三、高可用-主从复制
1、主从复制机制
所有持久化数据保存在一台服务器上,为避免服务器宕机数据即丢失的问题,我们需要将数据同步到多台服务器上
主从复制机制
- 实现读写分离-主写从读
- 主节点master负责写
- 从节点slave负责读
- 主节点关闭持久化,从节点开启持久化
- 从节点宕机重启
- 数据从主节点同步到从节点
- 主节点宕机
- 按照一定规则投票从从节点选出新主节点
- 主节点重启后,变成新主节点的从节点,可完成数据同步
- 从节点宕机重启
主从复制步骤
- 从节点Slave服务器启动,主动连接主节点Master,并发送SYNC命令,请求初始化同步
- 主节点Master收到SYNC后,执行bgsave命令生成RDB文件,并缓存该时间段内的写命令
- 主节点Master完成RDB文件后,将其发送给所有从节点Slave服务器
- 从节点Slave服务器接收到RDB文件后,删除内存中旧的缓存数据,并装载RDB文件
- 主节点Master在发送完RDB后,即刻向所有从节点Slave服务器发送缓存中的写命令
主从复制作用
- 读写分离-主写从读
- 提高服务器的读写负载能力
- 负载均衡
- 基于主从结构,配合读写分离,由slave分担master负载
- 根据需求的变化,改变slave的数量,通过多个从节点分担数据读取负载
- 大大提高Redis服务器并发量与数据吞吐量
- 基于主从结构,配合读写分离,由slave分担master负载
- 故障恢复
- 当主节点master出现问题时,由从节点slave提供服务,实现快速的故障恢复
- 数据冗余
- 实现数据热备份,是持久化之外的一种数据冗余方式
高可用基石
监控主服务器master的和从服务器slave状态
- 如果主库master出现故障,会从从库slave中挑选一个作为新主库(主库修复)
- 当主库master恢复,会作为新主库的从库
- 如果主库master出现故障,会从从库slave中挑选一个作为新主库(主库修复)
- 哨兵需要搭建集群监控主库
- 哨兵之间相互建立连接
- 哨兵集群中的多个哨兵判断主库master故障,才能判定主库master故障,之后进行主库修复
- 仲裁
- 哨兵半数+1
- 对主库master故障的判断从主观改变为客观
- 主库master会从主观下线转变为客观下线
哨兵模式存在问题
分片集群Redis Cluster方案
- 采用哈希槽处理数据和实例之间的映射关系
- 一个分片集群有16384个哈希槽,提供给主节点master分配
- 映射关系的分配规则
- 根据键值对的key计算取模找对应的哈希槽位置
- 创建分片集群,Redis自动把哈希槽平均分配给集群实例
- 数据根据映射关系的分配规则存储到对应的哈希槽中,即对应的集群实例中
分片集群优点
- 存储海量数据
- 实现高可用
- 高可用架构总结
- 主从模式:读写分离,负载均衡,一个Master可以有多个Slaves
- 哨兵sentinel:监控,自动转移,哨兵发现主服务器挂了后,就会从slave中重新选举一个主服务器
- 高可用架构总结
实现高可扩
给key设置过期时间,但并非立即删除
过期删除策略
- 定时删除(不推荐)
- 创建定时器,key到了过期时间,定时器立即删除key
- 对CPU不友好,降低系统性能
- 惰性删除
- 获取key时,判断key是否存在,存在则进而判断key是否过期,过期则删除
- 对内存不友好,浪费内存空间
定期删除
内存问题
- 数据大量存储到Redis中,过期的key一致未被使用占用内存
- 内存淘汰策略解决内存不够用时,淘汰内存的方案
最大内存参数配置
- 默认设置/设置为0,表示无限
- redis.conf中配置最大内存参数配置maxmemory
- 一般设置为内存的四分之三
内存淘汰策略-三大类八种
- 对设置过期时间数据淘汰volatile
volatile-xxx
lru
删除最近最久未被使用的key- 以时间为基准
lfu
删除最近最少未被使用的key- 以频次为基准
ttl
删除即将过期的keyrandom
随机删除
- 对所有数据淘汰allkeys
allkeys-xxx
lru
lfu
random
- 不淘汰
noevction
- 不删除,返回错误信息