redis混合持久化

redis混合持久化机制 部署 redis开启混合持久化_数据

redis4.0开始加入了混合持久化功能。在redis5中,混合持久化功能默认是开启的。简单来说,就是将rdb文件内容和增量的aof日志文件存在一起。这里的aof文件是增量的文件。redis重启的时候,可以先加载rdb的内容,然后加载增量的aof文件,这样的话重启的效率就大幅提升了。

redis的高可用

redis的高可用主要分为三种: 主从同步,哨兵模式和集群模式

redis混合持久化机制 部署 redis开启混合持久化_缓存_02

主从复制:就是主节点的数据单向的同步到从节点上,这是全量同步的

作用:数据冗余,故障恢复,负载均衡,读写分离,高可用基石(主从+哨兵模式)

主从同步大致过程

redis混合持久化机制 部署 redis开启混合持久化_redis混合持久化机制 部署_03

  1. 保存主节点(master)信息 这一步只是保存主节点信息,保存主节点的ip和port。
  2. 主从建立连接 从节点(slave)发现新的主节点后,会尝试和主节点建立网络连接。
  3. 发送ping命令 连接建立成功后从节点发送ping请求进行首次通信,主要是检测主从之间网络套接字是否可用、主节点当前是否可接受处理命令。
  4. 权限验证 如果主节点要求密码验证,从节点必须正确的密码才能通过验证。
  5. 同步数据集 主从复制连接正常通信后,主节点会把持有的数据全部发送给从节点。
  6. 命令持续复制 接下来主节点会持续地把写命令发送给从节点,保证主从数据一致性。

主从复制存在的问题

  • 如果主节点出现故障,不能自动转到从节点上,需要手动去调整从节点为主节点,并主从建立关系,比较麻烦
  • 主节点写能力受到单机的限制
  • 主节点存储受到单机的限制

redis哨兵模式

为了解决主从故障转移的问题,引入了哨兵模式。当主节点发生故障的时候,哨兵模式主动把从节点切换到主节点即可

redis混合持久化机制 部署 redis开启混合持久化_数据_04

哨兵模式:哨兵节点和数据节点。哨兵节点不存储数据,只是监控redis节点,数据节点才存储数据。当主节点发生故障的时候,主动发送通知到其他从节点,同时选出(raft算法)主节点并建立主从关系即可。这样主从+哨兵模式,就实现了故障自动切换的问题。哨兵模式的原理就是有个心跳检测,来监听各个redis的节点的健康状态。

redis集群

redis集群解决了高可用和分布式的问题,各个redis的节点的数据不是一样的,数据分布存储的。

redis混合持久化机制 部署 redis开启混合持久化_redis_05

  • 数据分区:集群是将数据分散到各个redis的节点上,这样的话可以解决redis单节点读写和存储平顶问题,大大提高了响应速度
  • 高可用: redis集群可以解决故障自动转移,当任一一个节点发生故障的时候,集群任然可以提供服务

集群故障转移过程

故障发现Redis集群内节点通过ping/pong消息实现节点通信,集群中每个节点都会定期向其他节点发送ping消息,接收节点回复pong 消息作为响应。如果在cluster-node-timeout时间内通信一直失败,则发送节 点会认为接收节点存在故障,把接收节点标记为主观下线(pfail)状态。

当某个节点判断另一个节点主观下线后,相应的节点状态会跟随消息在集群内传播。通过Gossip消息传播,集群内节点不断收集到故障节点的下线报告。当 半数以上持有槽的主节点都标记某个节点是主观下线时。触发客观下线流程。

redis集群收缩

redis在不影响线上使用的情况下,在redis集群中添加(删除)节点来完成集群扩容

缓存

使用redis的过程中,遇到最多的肯定是这个三个:缓存击穿,缓存穿透,缓存雪崩

缓存击穿:瞬时间热点的key失效了,导致大量访问穿过了redis,打到了db上。

解决办法:加锁更新,key失效去查询数据库,同时加锁防止其他用户访问这个key,写入成功之后,锁解除,还有就是key不要设置同样的过期时间,用定时任务定时去刷新key的过期时间进行延长

缓存穿透:查询一个数据库不存在的数据,导致所有的请求都访问到了db上,系统奔溃

解决办法: 自己的业务代码没有判断,恶意攻击。所以要解决这个问题:缓存空置或者默认值(占用存储空间),并设置过期时间(时间窗口内缓存数据和数据库数据不一致问题)。

采用布隆过滤器缓存空对象(维护麻烦,占用空格少)

缓存雪崩:某个时刻发生规模的宕机或者大key失效的时间,达到db上导致系统奔溃

解决办法:采用集群部署,多级缓存,增加不同的key不同的过期时间,热点key永不过期,降级处理,熔断

缓存和数据库数据一致性问题

缓存和数据库数据有时候会导致不一致,同步的间隔时间或者高并发的时候,就会出现该问题。

强一致性不可能实现,只是接近于实现数据库和缓存一致

解决办法是:删除缓存而不是更新缓存,先要进行数据库的更新,然后进行删除缓存操作。给缓存设置一个合理的过期时间,就算出现异常,迟早也会出现数据库和缓存一致的时候

热key处理

热key就是一个时间内出现大量请求访问的情况,比如明星离婚的事件,导致redis单节点突然ops过大,缓存压力加大。要处理热key的问题,就是要监控热key。从客户端来说,就是监控客户端查询key的次数,服务端来监控redis对某个key的执行次数。进而把热key打散到不同的redis节点上,还要加入二级缓存来处理,提前写入到服务器的内存中

缓存预热

就是提前把需要的缓存数据写到缓存中,避免高并发引起的缓存问题

  • 写个界面操作来完成需要的数据写入到缓存中F5刷新下
  • 如果数据固定不多的话,项目启动的时候自动加载到redis中
  • 定时任务刷新到缓存中即可

redis内存不足

  • 修改配置文件增加内存大小
  • 命令修改内存大小set maxmemory
  • 修改redis淘汰策略
  • 采用redis集群部署数据分片存储

大key问题

key的存储value很大,超过10kb

带来的问题:增加请求超时,删除耗时导致io阻塞,占用带宽和cpu,redis集群中数据倾斜

找到大key:bigkeys命令,全局扫描,redis-rdb-tools命令生成报表来分析大key

解决办法:删除大key:unlink命令删除,压缩大key的value值,序列号value,把value分片到不同的redis集群节点上,然后进行组合返回给客户端

redis事务

multi代表事务开始,exec代表事务结束,redis事务不支持回滚的

lua认识

工作中redis和lua用的最多的,秒杀和限流都是redis+lua。lua脚本简单易学,而且lua脚本在redis中执行是原子性的,不会有其他的命令进来,而且lua脚本可以复用减少网络开销。