redis中的key设置了过期时间了还会在持久化到文件中吗


AOF 持久化和 RDB 持久化的最主要区别在於前者记录了数据的变更,而后者是保存了数据本身本篇主要讲的是AOF 持久化,了解 AOF 的数据组织方式和运作机制Redis 主要在 aof.c 中实现 AOF 的操作。

同样AOF 持久化也会涉及文件的读写,会用到数据结构 rio关于 rio 已经在上一个篇章已经讲述,在此不做展开

假设 redis 内存有「name:Jhon」的键值对,那麼进行 AOF 持久化后AOF 文件有如下内容:

$6 # 第一个参数长度为6 $1 # 第二参数长度为1 $3 # 第一个参数长度为4 $4 # 第二参数长度为4 $4 # 第三个参数长度为4

所以对上面的內容进行恢复,能得到熟悉的一条 Redis 命令:SELECT 8;SET name Jhon. 可以想象的是Redis 遍历内存数据集中的每个 key-value 对,依次写入磁盘中;Redis 启动的时候从 AOF 文件中读取数据,恢复数据

AOF 持久化运作机制

和 redis RDB 持久化运作机制不同,redis AOF 有后台执行和边服务边备份两种方式

1)AOF 后台执行的方式和 RDB 有类似的地方,fork 一个子進程主进程仍进行服务,子进程执行AOF 持久化数据被dump 到磁盘上。与 RDB 不同的是后台子进程持久化过程中,主进程会记录期间的所有数据變更(主进程还在服务)并存储在 server.aof_rewrite_buf_blocks 中;后台子进程结束后,Redis 更新缓存追加到 AOF 文件中是 RDB

来说说更新缓存这个东西。Redis 服务器产生数据变更嘚时候譬如 set name Jhon,不仅仅会修改内存数据集也会记录此更新(修改)操作,记录的方式就是上面所说的数据组织方式

更新缓存可以存储茬 server.aof_buf 中,你可以把它理解为一个小型临时中转站所有累积的更新缓存都会先放入这里,它会在特定时机写入文件或者插入到server.aof_-rewrite_buf_blocks 下链表(下面會详述);server.aof_buf 中的数据在 propagrate() 添加在涉及数据更新的地方都会调用propagrate() 以累积变更。更新缓存也可以存储在 server.aof_-rewrite_buf_blocks这是一个元素类型为 struct aofrwblock 的链表,你可以紦它理解为一个仓库当后台有AOF 子进程的时候,会将累积的更新缓存(在 server.aof_buf 中)插入到链表中而当 AOF 子进程结束,它会被整个写入到文件兩者是有关联的。

这里的意图即是不用每次出现数据变更的时候都触发一个写操作可以将写操作先缓存到内存中,待到合适的时机写入箌磁盘如此避免频繁的写操作。当然完全可以实现让数据变更及时更新到磁盘中。两种做法的好坏就是一种博弈了

下面是后台执行嘚主要代码:

// 已经有正在执行备份的子进程 // 脏数据,其实就是子进程所消耗的内存大小 // AOF 最近一次执行的起始时间 // 因为更新缓存都将写入文件要强制产生选择数据集的指令SELECT ,以防出现数据

如上子进程执行 AOF 持久化,父进程则会记录一些 AOF 的执行信息下面来看看 AOF 持久化具体是怎么做的?

// 如果设置了自动备份参数将进行设置 // 备份每一个数据集 // 获取数据集的迭代器 // 写入数据集中每一个数据项 // 如果已经过期,放弃存储 // 写入键值对应的写操作

2)边服务边备份的方式即 Redis 服务器会把所有的数据变更存储在 server.aof_buf 中,并在特定时机将更新缓存写入预设定的文件(server.aof_filename)特定时机有三种:

Redis 无非是不想服务器突然崩溃终止,导致过多的数据丢失Redis 默认是每隔固定时间进行一次边服务边备份,即隔固定時间将累积的变更的写入文件

下面是边服务边执行 AOF 持久化的主要代码:

// 无数据,无需同步到磁盘 // 创建线程任务主要调用fsync() // 如果没有设置強制同步的选项,可能不会立即进行同步 // 设置延迟冲洗时间选项 // 没有超过2s直接结束 // 否则,要强制写入磁盘 // 取消延迟冲洗时间设置 // 当server.aof_buf 足够尛, 重新利用空间防止频繁的内存分配。 // 相反当server.aof_buf 占据大量的空间,采取的策略是释放空间可见redis

上面两次提到了「更新缓存」,它即是 Redis 累积的数据变更

// 向AOF 和从机发布数据更新
 // AOF 策略需要打开,且设置AOF 传播标记将更新发布给本地文件
 // 设置了从机传播标记,将更新发布给从機
 // 将数据更新记录到AOF 缓存中
// 如果已经有AOF 子进程运行redis 采取的策略是累积子进程AOF 备份的数据和
 // 创建新的节点,插到尾部

一副可以缓解视力疲勞的图片——AOF 持久化运作机制:

两种数据落地的方式就是 AOF 的两个主线。因此redis AOF 持久化机制有两条主线:后台执行和边服务边备份,抓住這两点就能理解 redis AOF 了

这里有一个疑问,两条主线都会涉及文件的写:后台执行会写一个AOF 文件边服务边备份也会写一个,以哪个为准

因此,确实会产生两个文件但是最后都会变成 server.aof_filename 文件。这里可能还有一个疑问既然有了后台持久化,为什么还要边服务边备份边服务边備份时间长了会产生数据冗余甚至备份过旧的数据,而后台持久化可以消除这些东西看,这里是 Redis 的双保险

AOF 的数据恢复过程设计很巧妙,它模拟一个 Redis 的服务过程Redis 首先虚拟一个客户端,读取 AOF 文件恢复 Redis 命令和参数;接着过程就和服务客户端一样执行命令相应的函数从而恢複数据,这样做的目的无非是提高代码的复用率这些过程主要在 loadAppendOnlyFile() 中实现。

// 加载AOF 文件恢复数据
 // 文件大小不能为0
 // 正在执行AOF 加载操作,于是暫时禁止AOF 的所有操作以免混淆
 // 每循环1000 次,在恢复数据的同时服务器也为客户端服务。
 // 可能aof 文件到了结尾
 // 必须以“*”开头格式不对,退出
 // 执行命令模拟服务客户端请求的过程,从而写入数据
 // 释放虚拟客户端空间
 // 记录最近AOF 操作的文件大小

如果对数据比较关心分秒必争,可以用 AOF 持久化而且AOF 文件很容易进行分析。

  • 除了string独有设置redis中key的过期时间间方法其他类型都需要依靠expire方法来设置时间

  • 如果没有设置时间,那缓存就是永不过期

  • 如果设置了redis中key的过期时间间之后又想让缓存永不过期,使用persist key

    • 若过期key很多删除这些key会占用很多的CPU时间,在CPU时间紧张的情况下CPU不能把所有的时间用来做要紧的事儿,还需要去花时间删除这些key

    • 萣时器的创建耗时若为每一个设置redis中key的过期时间间的key创建一个定时器(将会有大量的定时器产生),性能影响严重

    • 含义:在设置key的redis中key的過期时间间的同时为该key创建一个定时器,让定时器在key的redis中key的过期时间间来临时对key进行删除

    • 优点:保证内存被尽快释放

    • 含义:key过期的时候不删除,每次从数据库获取key的时候去检查是否过期若过期,则删除返回null。

    • 优点:删除操作只发生在从数据库取出key的时候发生而且呮删除当前key,所以对CPU时间的占用是比较少的而且此时的删除是已经到了非做不可的地步(如果此时还不删除的话,我们就会获取到了已經过期的key了)

    • 缺点:若大量的key在超出超时时间后很久一段时间内,都没有被获取过那么可能发生内存泄露(无用的垃圾占用了大量的內存)

    • 合理设置删除操作的执行时长(每次删除执行多长时间)和执行频率(每隔多长时间做一次删除)(这个要根据服务器运行情况来萣了)

    • 在内存友好方面,不如"定时删除"

    • 在CPU时间友好方面不如"惰性删除"

    • 通过限制删除操作的时长和频率,来减少删除操作对CPU时间的占用--处悝"定时删除"的缺点

    • 定期删除过期key--处理"惰性删除"的缺点

    • 含义:每隔一段时间执行一次删除过期key操作

  • 上边所说的数据库指的是内存数据库默認情况下每一台redis服务器有16个数据库(关于数据库的设置,看下边代码)默认使用0号数据库,所有的操作都是对0号数据库的操作

# 设置数据庫数量默认为16个库,默认使用DB 0可以使用"select 1"来选择一号数据库# 注意:由于默认使用0号数据库,那么我们所做的所有的缓存操作都存在0号数據库上# 当你在1号数据库上去查找的时候,就查不到之前set过得缓存# 若想将0号数据库上的缓存移动到1号数据库可以使用"move key 1"databases 16
  • memcached只是用了惰性删除,而redis同时使用了惰性删除与定期删除这也是二者的一个不同点(可以看做是redis优于memcached的一点)

  • 对于惰性删除而言,并不是只有获取key的时候才會检查key是否过期在某些设置key的方法上也会检查(/p/ddb3d4c1534d
    简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处

我要回帖

 

随机推荐