• 事务:
    • redis是部分支持事务,对于语法错误编译能检查错误的 支持事务回滚,而在执行过程中出现错误的(语法本身没有错误) 不支持事务 ,任然能执行成功
    • 开启事务:命令:multi 创建一个事务的队列,会将执行的语句放入到队列中 ,作为一个整体执行
    • 执行命令:exec
    • 放弃命令:discard
  • 持久化机制: redis是将基于内存存储的 ,redis一旦宕机会丢失数据,redis提供了2中数据的持久化
    • RDB(rerdis database):是redis默认的持久化机制:基于快照的思想, 当符合一定的条件时,会将数据写入磁盘 ,保存dump.rdb文件中(二进制形式),
      • 触发条件: ```xml

save “” # 不使用RDB存储 不能主从

记忆

save 3600 1 #表示1小时内至少1个键被更改则进行快照。 save 300 100 #表示5分钟(300秒)内至少100个键被更改则进行快照。 save 60 10000 #表示1分钟内至少10000个键被更改则进行快照。 ```

  1. - 或者手动执行命令:save(同步执行),会阻塞redis的服务进程,直到把数据写入.rdb文件
  2. - bgsave(异步的方式):fork一个和主线程一致的子线程, 不会阻塞redis的服务进程,操作rdb文件的时候任然可以执行命令
  • 执行过程:reids服务进程判断,当前是否有子线程在执行save 和bgsave.
  • 如果有,则执行返回,不做任何处理
  • 如果没有,则以阻塞式创建子线程,在创建子线程期间,不执行命令
  • 创建完后,就可以继续执行命令,子线程将数据按二进制的形式写入rdb文件
  • 优缺点:
    • 基于二进制形式存储,完成数据备份,占用磁盘的空间小,可以自定义触发条件
    • 无法保证数据的完整性,会丢失最后一次快照后的数据
    • bgsave每次都会阻塞检查子线程,影响性能
  • AOF (默认不开启)
    • AOF 记录的不是数据,而是执行命令,每次redis重启后 会读取aof文件,按顺序执行命令将数据恢复
    • 触发条件:3种
      • always 每一次写入都会记录,最多丢失一条 安全性最好,性能最低
      • everysec 默认使用的方式 每一秒写入一次都会将auf缓冲文件中的命令写入aof文件中 并同步到磁盘中,好方式兼顾了效率与安全,数据丢失最多不超过2秒
      • no 每次写入命令都会将aof_buf缓存中的命令写入文件aof中,但是不进行aof文件同步到磁盘,同步操作交给操作系统完成(每30秒一次),方式最快,但是最不安全
    • AOF重写优化:aof会将执行命令都记录下来 ,但是回导致文件过大,恢复数据时间过长,redis提供了aof的重写优化,redis会开启一个子线程创建一个aof替换现有的aof文件,新的aof文件去除冗余的命令,只存在恢复数据最小的命令集合
    • 除了让Redis自动执行重写外,也可以手动让其进行执行:bgrewriteaof
    • aof执行流程:
      • 客户端发送命令
      • rddis将收到的命令保存到缓冲区aof_buf的末尾,这个过程就是追加
      • redis将缓存区文件写入到aof文件中,这个过程是文件写入
      • reids根据策略将aof文件同步到磁盘
  • aof和rdb的对比:
    • 如果只关注性能 不关心数据安全 则2种都选择关闭
    • 如果关注数据安全的同时需要较高的性能,可选在rdb模式
    • 如果需要较高的数据安全性 ,则使用aof模式
      • 高可用-主从复制
  • 主节点写,从节点读 一个主节点可以有很多从节点,slave服务启动,主动连接master主节点,并发送sync命令,请求初始化同步,
  • master收到sync后,执行bgsave命令生成rdb文件,并存储该时间段内的命令
  • master完成rdb文件后,将其发送给所有的slave服务器,
  • slave服务器接收到rbd文件后,删除旧的数据缓存,并装载rdb文件
  • master在发送rdb文件后,即刻向所有的slave服务器发送缓存中的命令
    • 主从复制:
  • 读写分离:主写从读,提高服务的读写能力
  • 负载均衡:基于主从结构,配合读写分离,由slave分担master负载,并根据需求的变化,改变slave的数量:通过多个从节点分担数据负载,
  • 故障恢复:当master出现问题时:由slave提供服务,实现快速的故障恢复
  • 数据冗余;实现数据热备份,是持久化的之外的一种数据冗余
  • 高可用基石:基于主从复制,构建哨兵模式与集群,实现redis的高可用方案
    • 哨兵模式:
  • 在主从模式下,如果主节点发生故障,就不可以提供写服务了 且无法自动发现主库是否挂了 ,该选哪个从库作为主库,新的主库怎么把数据同步到从库和客户端
  • 哨兵机制是实现主从库自动的关键机制,他有效的解决了主从复制的故障转移
  • 哨兵是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票的方式选出主结构 并将所有的slave连接到新的master
  • 哨兵也需要集群
  • 哨兵实现原理:通过发送命令给多个节点,等待redis节点的回复,从而监控多个redis服务器 当看空到master宕机后,会自动选举一个slave切换成master,通知其他从服务器,修改配置文件切换主机
  • sentinel的三大任务

    • 监控:哨兵会不断的检查你的主服务和从服务是否运行正常
    • 提醒:当被监控的某个redis发生故障的时候,sentinel会通过api的方式向管理员和其他应用程序发送通知
    • 自动故障迁移:当一个主服务器不能正常工作时;seninel会开始一次自动故障迁移,他会将实现的主服务器的一个从服务器提升为master节点
    • 当客户端连接失效的主节点时,sentinel会向客服端发送新的主节点地址,使得新的主节点代替失效的主节点
  • 主观下线和客观下线:”

    • 如果哨兵发现主库或从库对 PING 命令的响应超时了,那么,哨兵就会先把它标记

              为“主观下线
      
    • 一个服务器没有在 down-after-milliseconds 选项所指定的时间内, 对向它发送 PING 命令的 Sentinel 返回一个有效回复(valid reply), 那么 Sentinel 就会将这个服务器标记为主观下线

    • 如果检查的是从库,哨兵把他标记为主观下线就可以了,因从库的下面整个集群不会产生太大的影响,
    • 如果检查的是主库,那么,哨兵的还不能简单的地吧他标记为主管下线了,因为可能会出现误判:因为网络的原因的导致连接延时,其实主库没有发生故障,可是一旦启动了主从替换,后续的选主和通知都会带来额外的开销
    • 客观下线:
      • 指的是多个sentinel实例在对同一个服务器做主观下线的判断,并且通过命令互相交流后,得出的服务下线的判断
      • 客观下线的条件只用于主服务器
    • 仲裁:
      • 在sentinel给定的时间内,从其他的sentinel哪里接收到了足够数量的主服务器下线报告,那么 sentinel就会将服务器的状态从主观下线改变为客观下线
      • 这个足够的数量就是配置文件中配置的值;一般是sentinel的半数加1
      • 当拥有的主观下线的数量到达sentinel monitor的值时 就会发起一次投票 进行fileover
  • redis 高可用 分片集群

    • 数据切片和实例对应的关系

      • 无中心化
      • 采用哈希槽(hash slot)来处理实例之间的映射关系
      • 一个切片集群一共用16384个哈希槽,只给master分配
      • 具体的映射过程
        • 每个key通过hash计算得出一个16bit的值 对16384做取余计算,得到0-16383的值; 觉得存储到那个分片上
        • 使用rerdis 分片集群 ,redis会自动把16384个hash槽分配到不同的master实例上 也可以手动指定
        • 注意 必须要把16384个hash槽分配完 否则无法正常工作
        • 集群中,哈希槽和实例的对应关系不是一成不变的
          • 实例的新增和删除都可以影响
          • 实例之间可以通过互相通信来获取最新的hash槽的分配信息,客户端无法感知
          • 重定向机制
          • 重定向机制
    • 如果实例上没有该键值对映射的哈希槽,就会返回 MOVED 命令

    • 客户端会更新本地缓存
      • 过期删除策略

  • 定时删除
    • 它会在设置键的过期时间的同时,创建一个定时器, 当键到了过期时间,定时器会立即对键进行删除。 这个策略能够保证过期键的尽快删除,快速释放内存空间。 (对cpu不友好)
  • 惰性删除;:
    • geikey设置过期时间, 到了过期时间不删除 在下次获取的时候 判断是否过期 过期了就删除 然后返回null(对内存不友好)
  • 定期删除:

    • 每隔一段时间删除
    • 默认每秒运行10次会对具有过期时间的key进行一次扫描,但是并不会扫描全部的key,因为这样会大大延长扫描时间,
    • 每次默认只会随机扫描20个key,同时删除这20个key中已经过期的key。
      • 内存淘汰策略
    • 当redis存入数据时;redis会检查的内存空间的大小,如果超过最大内存,就会触发淘汰策略
    • 对于这些策略各自的含义,我们还需要一点前置知识的铺垫,这里我们可以看到两个名称:lrulfu,他俩是什么意思呢?

      他们的学名叫做:数据驱逐策略。 其实所谓的驱逐就是将数据从内存中删除掉

    • lru:Least Recently Used,它是以时间为基准,删除最近最久未被使用的key。

    • lfu:Least Frequently Used,它是以频次为基准,删除最近最少未被使用的key。



image.png