Redis持久化

为了解决Redis服务器重启后数据丢失的问题,需要将Redis的数据持久化到硬盘上。
有两种持久化方式:AOF持久化、RDB持久化。

AOF 持久化

Append Only File
AOF持久化将服务器所有的写操作命令保存到单独的日志文件中,服务器重启时,通过加载日志文件并执行命令来回复数据。

AOF持久化配置

AOF持久化的实现

  1. 命令追加:Redis服务器并不是每执行一条写命令就将该命令写入AOF文件,避免频繁与硬盘交互浪费资源;而是先将命令追加到缓存区aof_buf中
  2. AOF文件写入和文件同步:
    根据appendfsync参数配置的不同策略,将缓存区aof_buf中的数据内容同步至硬盘中、zhbt

    AOF持久化策略

  3. 每当有新命令就追加

  4. 设置每秒执行一次
  5. 从不执行

    AOF文件重写

  6. 目的
    定期重写AOF文件,可以压缩文件大小,节省空间。

  7. 方式
    AOF文件重写,会生成新的AOF文件代替旧的,但是重写过程并不会对旧的文件进行读取或写入。而是直接读取当前数据库的状态,将相应命令写入新AOF文件。
  8. 触发方式
    AOF文件重写有手动触发和自动触发两种方式
  9. 后台重写
    调用aof_rewrite函数重写AOF文件时,会使线程被长时间阻塞。Redis服务器采用单线程处理命令请求,此时会使服务器阻塞。因此Redis将AOF文件重写放到一个子进程中执行

    AOF文件处理

    服务器启动时,会创建一个伪客户端,读取AOF文件的命令并发出命令执行,直到AOF中所有命令读取完毕

    优点与缺点

    优点:丢失数据少、完整性好

    RDB 持久化

    在指定时间间隔内,将内存中所有数据生成一份快照保存在硬盘中。

    触发机制

  10. 手动触发
    save命令手动触发

  11. 自动触发
    满足save规则时,可以自动触发
    save m n 命令:时间m内被修改的键的个数大于n时,会触发 BGSAVE 命令。
    BGSAVE在后台执行,Redis调用子进程来执行,与AOF文件后台重写类似。
  12. 执行flusl all命令后
  13. 退出redis时

查看dump.rdb文件
config get dir

优点

适合大规模数据恢复
对数据完整性要求不高

缺点

  • 操作需要一定时间间隔,两次快照会隔一段时间,最后一次的数据会丢失
  • 子进程执行时,会占用一定内存空间

    Redis缓存

    缓存穿透

    缓存中没有的数据,被大量访问。没有在缓存中查到数据,直接在数据库中查询。当这个数据被大量查询时,会影响系统。

解决方案

缓存空对象

Redis高级 - 图1
此方法问题:

  1. 缓存中会存储大量空键
  2. 缓存中的值和持久层数据不一致

    布隆过滤器

    缓存击穿

    热点数据失效。某个热点数据,短时间内接受大量访问,在热点key失效的一瞬间,会使持久层压力过大

解决方案:

设置热点数据永不过期

加互斥锁

分布式锁,保证每一个key同一时间只要一个线程访问,将并发压力转移到分布式锁上

缓存雪崩

某一时间内,大量缓存集中失效。或服务器断点或断网π

解决方案

Redis高可用

设置多台Redis服务器,搭建集群

限流降级

通过锁或者队列,限制访问数据库线程的数量

数据预热

正式部署前,把可能的访问预先访问一遍,让可能大量访问的数据下载到缓存中

Redis事务

开启事务
命令入队
执行命令
回滚

Lua脚本

管道技术 Pipline

合并操作批量处理,处理是多个互不相干的命令

Redis技巧

慢日志查询

耗时命令日志
当一条命令执行超过一定时间时,将它存入slowlog

  1. slowlog-log-slower-than
  2. 慢日志命令时间限制 (默认10000
  3. slowlog-max-len
  4. 慢日志命令存储条数最大值 (默然128

JAVA操作Redis

Java中使用Jedis操作Redis。
如果是云服务器,需要配置防火墙,添加服务器安全组。

性能优化

内存优化

  • 数据结构选择

    CPU优化

  • 不要有阻塞操作

  • 谨慎使用范围操作 keys*等
  • SlowLog慢操作查询

Redis是多线程还是单线程?

IO线程
redis 6版本以前,单线程
redis 6版本开始,多线程,引入NIO,多路复用模型(主要性能提升点)

内存数据处理线程
一直都是单线程(为什么单线程还这么快?)

Redis 数据处理是单线程的,为什么还这么快?

  1. 多线程不一定就快,多线程环境下需要切换CPU,切换CPU需要消耗大量资源
  2. redis单线程,不需要切换cpu
  3. 直接操作内存,所以很快。