Redis学习笔记(2)
Redis学习笔记(2)

Redis学习笔记(2)

持久化

  • RDB持久化:能够在指定的时间间隔对数据进行快照存储。
  • AOF持久化:记录每次的操作,在重启服务器时,重新执行这些命令,来恢复原始数据。这样能确保所有数据都能够被持久化。

RDB持久化:

优点:

  • 恢复大数据量时,速度比AOF快一些
  • 根据不同时间,保存不同的版本。
  • 保存时,只需要fork一个子进程,然后全都由子进程来完成,能够最大化Redis的性能。

缺点:

  • 保存时间间隔长,可能丢失部分数据

RDB能够把当前的数据生成快照保存到硬盘,触发方式分为手动触发和自动触发。

  • 手动触发:
    • 手动触发对应save命令,会阻塞当前Redis服务器,知道RDB结束。对于内存较大的实例会造成长时间阻塞,线上环境不建议使用。
  • 自动触发:
    • 自动触发对应bgsave命令,Redis进程执行fork操作创建子进程,持久化过程由子进程来完成,阻塞只发生在fork阶段,一般时间很短。如果执行shutdown命令并且没有开启AOF功能,则会自动执行bgsave。

AOF持久化:

优点:

  • 拥有fsync策略(每秒保存或每次保存),保存的数据比RDB更加完整。

缺点:

  • 对于相同数据,AOF文件的体积比RDB的更大
  • 数据恢复时间比RDB更长。

开启AOF功能需要配置:appendonly yes

AOF文件名通过appendfilename配置设置,保存路径和RDB持久化方式一致。

命令会先存放到缓冲区aof_buf中。如果每次都直接追加到硬盘,那么效率完全决定于当前硬盘负载。并且Redis提供多种缓冲区同步硬盘的策略,能够在性能和安全性方面做出平衡。

AOF为了文件过大,拥有重写机制。将无效的语句省略。

AOF的重写分为手动触发和自动触发

  • 手动触发:直接调用bgrewriteaof命令。
  • 自动触发:根据auto-aof-rewrite-min-size和auto-aof-rewrite-percentage参数确定自动触发时机。

常见问题

缓存穿透:

指用户请求的数据在缓存中不存在即没有命中,同时数据库中也不存在,导致用户每次请求该数据都要去数据库中查询一遍,然后返回空。

解决方案:

  • 布隆过滤器(Bloom Filter 简称BF):专门用来检测集合中是否存在特定元素。
    • 优点:
      • 节省空间:不需要存储数据本身,只需要存储数据对于hash比特位
      • 时间复杂度低:插入和查找的时间复杂度都为O(K),K为哈希函数的个数
    • 缺点:
      • 存在假阳性:布隆过滤器判断存在,元素可能不在集合中,判断准确率取决于哈希函数的个数
      • 不能删除元素:如果一个元素被删除,但是不能从布隆过滤器中删除,就会造成假阳性。
  • 返回空对象:当缓存未命中,查询持久层也为空,那么返回一个空对象到缓存中,下次请求时直接返回空对象,为了存储过多空对象,通常设置一个过期时间。
    • 问题所在:
      • 如果有大量key穿透,缓存空对象会占用宝贵的内存空间。
      • 空对象的key设置了过期时间,在这段时间内,可能存在缓存和持久层数据不一致。

缓存击穿:

指一个key非常热点,不停地扛着大并发,当这个key失效的瞬间,持续的大并发就会穿破缓存,直接请求数据库,此时的数据库压力巨大呀!

解决方案:

  • 使用互斥锁:当缓存失效时,只让大并发中的一个线程去读取数据库,并且写回缓存,此时其他的请求都等待。
  • 热点数据永不过期:
    • 物理不过期:不给热点key设置过期时间。
    • 逻辑过期:把过期时间存放在value中,如果要过期了,那么就通过一个异步线程,进行缓存的重新构建。

缓存雪崩:

指缓存中数据大批量到过期时间,并且访问数据量巨大,请求直接落到数据库上,引起数据库压力过大。与缓存击穿不同的是,雪崩是多条数据过期。

解决方案:

  • 均匀过期:设置不同的过期时间,是失效的时间点尽量均匀。
  • 加互斥锁:同一时间只让一个线程构建缓存,其他线程阻塞排队。
  • 缓存永不过期:类似缓存击穿中的数据不过期。
  • 双层缓存策略:使用主备两层缓存:
    • 主缓存:有效期按照经验值设置,设置为主读取的缓存,主缓存失效后从数据库加载最新值。
    • 备份缓存:有效期长,获取锁失败时读取的缓存,主缓存更新时需要同步更新备份缓存。

热点预热:

指系统上线后,将相关的缓存数据直接加载到缓存系统,这样可以避免用户请求时,先查询数据库,再将数据写回到缓存中。

如果不进行预热,Redis初始为空,对于高并发的流量都会直接访问到数据库中。

操作方法:

  • 数据量不大的时候,工程启动时进行加载缓存动作。
  • 数据量大的时候,设置一个定时任务脚本,进行缓存的刷新。
  • 数据量超级大的时候,优先保证热点数据进行提前加载到缓存中。

缓存降级:

指缓存失效或则和缓存服务器挂掉的时候,不去访问数据库,而是直接返回默认数据或者访问服务的内存数据。

内存淘汰机制

Redis缓存内存不足时,淘汰旧数据处理新加入数据的策略。

淘汰分类:

  • noeviction:默认策略,对于写请求直接返回错误,不进行淘汰。
  • allkeys-lru:最近最少使用,从全体key中使用近似LRU算法进行淘汰
  • volatile-lru:最近最少使用,从设置了过期时间的key中使用近似LRU算法进行淘汰
  • allkeys-random:从所有key中随机淘汰。
  • volatile-random:从设置了过期时间的key中随机淘汰。
  • volatile-ttl:越早过期的越先淘汰。
  • allkeys-lfu:最少使用频率,再所有key中,使用近似LFU算法进行淘汰
  • volatile-lfu:最少使用频率,再设置了过期时间的key中,使用近似LFU算法进行淘汰

以上算法中的要加上“近似”两个字,是因为redis使用的淘汰算法是先随机出m个key,再从中按照算法淘汰掉一个key,m是可以设置的参数(maxmemory-samples)

Redis事务与关系型数据库中的事务对于原子性的概念是不同的

Redis发送错误时,不会停止执行并回滚数据。

Redis主从复制

指将一台Redis服务器的数据复制到其他Redis服务器,前者称为主节点,其余称为从节点。

作用:

  • 数据冗余:实现了数据热备份。
  • 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复。
  • 负载均衡:实现读写分离,主节点提供写服务,从节点提供读服务,分担服务压力。
  • 高可用基石:

实现原理:

  • 连接建立阶段:主从节点之间建立连接,为数据同步做准备。
    • 保存主节点信息:
    • 建立socket连接:
    • 发送ping命令:
    • 身份验证:
    • 发送从节点端口信息:
  • 数据同步阶段:进行从节点数据的初始化,向主节点发送psync命令,开始同步。
  • 命令传播节点:数据同步完成后,主节点进入命令传播阶段,将自己执行的写命令发送给从节点,从节点接收并执行,来保证主从节点数据的一致性。由于命令传播是异步问题,并且主节点发送不会验证从节点是否接收到,以及主从节点的网络问题,很容易造成主从节点数据不一致。
网址

网站:https://github.com/CoderLeixiaoshuai/java-eight-part/blob/master/docs/redis/%E7%9C%8B%E5%AE%8C%E8%BF%9920%E9%81%93Redis%E9%9D%A2%E8%AF%95%E9%A2%98%EF%BC%8C%E9%98%BF%E9%87%8C%E9%9D%A2%E8%AF%95%E5%8F%AF%E4%BB%A5%E7%BA%A6%E8%B5%B7%E6%9D%A5%E4%BA%86.md

Sentinel(哨兵模式)

当主节点发生故障,不能提供服务时,能够自动完成故障发生和故障转移,并通知客户端。

心跳机制:

  • Sentinel和Redis Node:哨兵模式创建的时候,会通过配置,讲Sentinel和Redis Master Node连接,Sentinel从主节点上获取所有从节点的信息。之后定时(10s)向主从节点发送info命令,获取所有拓扑结构和状态信息。
  • Sentinel和Sentinel:基于Redis的订阅发布功能,每个Sentinel节点会每秒一次向主节点,从节点以及其他Sentinel进程发送一个ping命令。

故障转移:

每个sentinel会定时进行心跳检查,如果发现主节点出现心跳检测超时,此时会认为该主节点已经不可用,被称为主观下线。随后向其他sentinel节点发送“sentinel ismaster-down-by-addr”命令,询问大家对主节点的判断,当人数超过quorum(法定人数)就会认为该主节点故障,执行客观下线。(通常认为quorum的值是sentinel节点总数/2+1)

判断客观下线之后,sentinel节点之间会再做一次选举工作,基于Raft算法选一个领导者来执行故障转移工作。步骤如下:

  • 在从节点中选一个作为主节点
  • 领导者节点对选出来的从节点执行“slaveof on one”命令使其成为主节点
  • 向剩余从节点发送命令,让他们从新的主节点上复制数据
  • 领导者将原来的主节点更新为从节点,并对其进行监控,回复后命令他去复制新主节点数据

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注