Redis

  • 高性能分布式内存数据库
  • 非关系型数据库,数据存储在内存中
  • key-value形式
  • NoSql数据库之一

Redis数据结构

  • String
    • 单值单value
  • List
    • 单值多value
    • 有序可重复
  • Set
    • 单值多value
    • 无序不重复
  • Hash
    • value是一个键值对(类似于Map)
  • Zset(Sorted Set)

    • 有序不重复,可排序
    • 每个value有一个score

      一、事务机制

      1、事务

      事务的ACID
  • 原子性

    • 要么全部成功,要么全部失败
  • 一致性
    • 数据库的完整性
  • 隔离性
    • 多事务并发相互隔离
  • 持久性

    • 对数据的修改是永久的

      2、Redis事务

      Redis支持事务,但是支持事务的能力比较弱
  • Redis事务基于队列实现

    • 将事务操作的多个命令加入到一个队列,命令被序列化按顺序依次执行
      • 加入队列时,命令不执行,无法获取数据
      • 需要exec执行之后才可以获取数据
    • 一个队列中,一次性按顺序串行执行所有命令
  • 不保证一致性
    • 一条命令失败,其他命令会继续执行,不会回滚

Redis事务操作

  1. 开启事务

    1. multi
  2. 添加操作命令

    set name wyb
    ...
    
  3. 执行事务

    exec
    
  4. 取消事务

    discard
    

    3、事务处理机制

    事务原子性(要么都成功,要么都失败)
    Redis对命令执行出错处理的解决方式

  5. 语法错误

    • 编译阶段出错
    • 一个事务队列中,出现命令语法错误,执行事务exec之后,会返回错误信息,正确的命令也不执行
  6. 执行错误
    • 运行阶段出错
    • 命令语法无误,命令执行有误的错误命令不执行,正确命令可以执行

      二、持久化机制

      Redis存储数据存在问题
  • Redis数据存储在内存之中
    • 若服务器宕机,内存中数据容易丢失

解决方案

  • Redis持久化机制,将内存中数据存储到磁盘中
    • 便于Redis恢复数据,避免数据意外丢失

Redis持久化机制

  1. RDB快照
  2. AOF
  • 两者可以同时使用

    1、RDB快照

    RDB(Redis DataBase)

  • Redis默认的存储方式

  • 在指定的时间间隔内将内存中的数据集快照(压缩为二进制文件)写入磁盘
    • 二进制备份文件dump.rdb
  • 恢复数据时将快照文件直接读到内存里
    • 将备份文件dump.rdb移到Redis安装目录并启动服务

触发RDB快照(两种方式)

  1. 配置文件中配置触发

    save 秒 改变次数
    save m n
    
    • 在m秒内修改n次key,触发RDB快照
    • 关闭RDB
      • 取消该配置
  2. 手动触发

    save #同步执行
    或
    bgsave #异步子线程执行(Redis默认使用)
    
    • Redis客户端执行命令,手动触发RDB快照
    1. save
      • 同步执行
      • 只执行保存,其他命令全部阻塞,直至保存结束
      • 关闭RDB
        • save “”
    2. 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属性值
  1. always每修改同步
    • 每执行一条写命令,就写入AOF文件,并将AOF文件同步到磁盘
      • 宕机最多只丢失一个命令的数据
  2. everysec(默认)每秒同步
    • 每执行一条写命令,就写入AOF文件,并每隔一秒将AOF文件同步到磁盘
      • 宕机不超过两秒的数据
  3. no不同步
    • 每执行一条写命令,就写入AOF文件,不将AOF文件同步到磁盘
      • 操作系统完成数据同步

AOF执行过程

  1. 命令追加
    • 写命令保存到缓冲文件aof_buf的末尾
  2. 文件写入
    • 缓冲区文件内容写入到AOF文件
  3. 文件同步
    • 将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对比

  1. RDB默认开启,AOF需手动开启。
  2. RDB性能优于AOF。
  3. AOF安全性优于RDB。
  4. AOF优先级高于RDB。
  5. RDB存储某个时刻的数据快照,AOF存储写命令。
  6. RDB在配置触发状态会丢失最后一次快照以后更改的所有数据,AOF默认使用everysec,每秒保存一次,最多丢失两秒以内的数据。

Redis持久化机制选择方案

  1. 追求高性能,不关注数据安全性
    • 关闭RDB快照和AOF
    • Redis宕机,直接从数据源恢复数据
  2. 较高性能,数据安全性
    • 开启RDB快照
  3. 更关注数据安全性
    • 开启AOF
  4. 可同时开启RDB快照和AOF

    三、高可用-主从复制

    1、主从复制机制

    所有持久化数据保存在一台服务器上,为避免服务器宕机数据即丢失的问题,我们需要将数据同步到多台服务器上
    主从复制机制
  • 实现读写分离-主写从读
    • 主节点master负责写
    • 从节点slave负责读
  • 主节点关闭持久化,从节点开启持久化
    • 从节点宕机重启
      • 数据从主节点同步到从节点
    • 主节点宕机
      • 按照一定规则投票从从节点选出新主节点
      • 主节点重启后,变成新主节点的从节点,可完成数据同步

主从复制步骤

  1. 从节点Slave服务器启动,主动连接主节点Master,并发送SYNC命令,请求初始化同步
  2. 主节点Master收到SYNC后,执行bgsave命令生成RDB文件,并缓存该时间段内的写命令
  3. 主节点Master完成RDB文件后,将其发送给所有从节点Slave服务器
  4. 从节点Slave服务器接收到RDB文件后,删除内存中旧的缓存数据,并装载RDB文件
  5. 主节点Master在发送完RDB后,即刻向所有从节点Slave服务器发送缓存中的写命令

主从复制作用

  • 读写分离-主写从读
    • 提高服务器的读写负载能力
  • 负载均衡
    • 基于主从结构,配合读写分离,由slave分担master负载
      • 根据需求的变化,改变slave的数量,通过多个从节点分担数据读取负载
    • 大大提高Redis服务器并发量与数据吞吐量
  • 故障恢复
    • 当主节点master出现问题时,由从节点slave提供服务,实现快速的故障恢复
  • 数据冗余
    • 实现数据热备份,是持久化之外的一种数据冗余方式
  • 高可用基石

    • 基于主从复制,构建哨兵模式与集群,实现Redis的高可用方案

      2、哨兵模式Sentinel

      Redis以哨兵模式启动,哨兵监听主库状态
      哨兵模式是一个分布式系统
  • 监控主服务器master的和从服务器slave状态

    • 如果主库master出现故障,会从从库slave中挑选一个作为新主库(主库修复)
      • 当主库master恢复,会作为新主库的从库
  • 哨兵需要搭建集群监控主库
    • 哨兵之间相互建立连接
    • 哨兵集群中的多个哨兵判断主库master故障,才能判定主库master故障,之后进行主库修复
    • 仲裁
      • 哨兵半数+1
      • 对主库master故障的判断从主观改变为客观
        • 主库master会从主观下线转变为客观下线

哨兵模式存在问题

  • 主节点master的写能力和存储能力受限

    四、高可扩-Redis Cluster分片群集

    分片集群

  • 解决单机Redis容量有限的问题

  • 将数据按一定的规则分配到多台机器,提高并发量

分片集群Redis Cluster方案

  • 采用哈希槽处理数据和实例之间的映射关系
    • 一个分片集群有16384个哈希槽,提供给主节点master分配
    • 映射关系的分配规则
      • 根据键值对的key计算取模找对应的哈希槽位置
  • 创建分片集群,Redis自动把哈希槽平均分配给集群实例
    • 数据根据映射关系的分配规则存储到对应的哈希槽中,即对应的集群实例中

分片集群优点

  • 存储海量数据
  • 实现高可用
    • 高可用架构总结
      • 主从模式:读写分离,负载均衡,一个Master可以有多个Slaves
      • 哨兵sentinel:监控,自动转移,哨兵发现主服务器挂了后,就会从slave中重新选举一个主服务器
  • 实现高可扩

    • 分片集群: 为了解决单机Redis容量有限的问题,将数据按一定的规则分配到多台机器,内存/QPS不受限于单机,提高并发量。

      五、key过期删除策略

      key过期删除
  • 给key设置过期时间,但并非立即删除

过期删除策略

  • 定时删除(不推荐)
    • 创建定时器,key到了过期时间,定时器立即删除key
    • 对CPU不友好,降低系统性能
  • 惰性删除
    • 获取key时,判断key是否存在,存在则进而判断key是否过期,过期则删除
    • 对内存不友好,浪费内存空间
  • 定期删除

    • 默认每秒删除10次
    • 每次从过期key的集合中随机删除20个key
      • 判断删除的20个过期key是否占比过期总数的25%
    • redis.conf中hz参数代表每秒删除次数
      • 不要超过100

        六、内存淘汰策略

        内存淘汰策略
  • 内存问题

    • 数据大量存储到Redis中,过期的key一致未被使用占用内存
  • 内存淘汰策略解决内存不够用时,淘汰内存的方案

最大内存参数配置

  • 默认设置/设置为0,表示无限
  • redis.conf中配置最大内存参数配置maxmemory
    • 一般设置为内存的四分之三

内存淘汰策略-三大类八种

  • 对设置过期时间数据淘汰volatile
    • volatile-xxx
      • lru删除最近最久未被使用的key
        • 以时间为基准
      • lfu删除最近最少未被使用的key
        • 以频次为基准
      • ttl删除即将过期的key
      • random随机删除
  • 对所有数据淘汰allkeys
    • allkeys-xxx
      • lru
      • lfu
      • random
  • 不淘汰noevction
    • 不删除,返回错误信息