Redis进阶

Redis持久化:

前面我们讲到mysql事务有四个比较核心的特性

  1. 原子性:保证多个操作打包成一个。
  2. 一致性:A给B100,A少一百,B必须多一百。
  3. 持久性:针对事务操作必须要持久生效,不管是重启还是什么数据是否还在,mysql把数据存储在硬盘上。
  4. 隔离性:脏读幻读不可重复读等等。

Redis是内存数据库,把数据存储在内存上,要想能够做到持久,就要把数据存在硬盘上面,为了速度快,数据得存在内存上,但是为了持久,数据还得存在硬盘上面。那么我们就将数据存在内存和硬盘上面。但是查询的时候就直接从内存中读取,硬盘的数据是为了重启后放在内存中的。

RDB(Redis Database)持久策略:

RDB是定期将数据写入内存中,都给先写入硬盘中,形成一个快照,也就是redis把内存中的数据,快速“拍个照”,存储在硬盘中,就能在重启的时候把数据回复过来。

  • 手动触发:程序员通过自己写代码来执行特定的命令,来触发快照的生成,save和bgsave(如下介绍)等等。
  • 自动触发:在配置文件中配置多久触发一次自动存储。

save:redis全力执行快照生成的操作,有可能阻塞redis。一般不建议使用。

bgsave:不会影响redis处理其他任务。既可以保证持久化顺利进行,也不会影响redis处理其他请求和命令。创建子进程,子进程完成持久化操作,持久化操作将数据写入RDB文件中,接着用新文件替换旧文件

  • 判定是否存在,如果已经存在其他进程运行了,bgsave就会直接返回,并不会继续执行。
  • 如果不存在的话就会通过fork的方式创建进程,fork创建新的进程简单粗暴,就是复制一份和父亲一模一样的进程,一旦复制完了就是两个独立的(一模一样)进程。也就是安排子进程进行复制操作。
  • 子进程进行写文件,父进程继续接受客户端请求。
  • 子进程完成持久化的过程,通知父进程,父进程更新一些统计信息,子进程销毁。

如果子进程和父进程的数据一样就不会触发拷贝,但是如果有变化就会触发写时拷贝自己原本的数据。 

redis生成的RDB文件是存放在redis的工作目录中的,也就是下面这个文件,redis会在工作的时候把输出的等等中间文件放到这里边。

在该目录下面查看文件,找到文件dump.rdb镜像文件。该文件是二进制的文件,以压缩的方式保存下来(节省空间)。

当执行RDB镜像操作时候,就会把要生成的文件先保存到一个临时文件中,当我们的快照生成完毕的时候,再删除之前的RDB文件,把新生成的文件名字修改成我们的dump.rdb。能够保证至始至终的RDB文件只有一个.

RDB文件并不是马上插入就会触发,是通过手动触发或者自动触发。

在redis的配置文件中阐述了自动触发保存的相关信息,虽然这里都可以随意修改数据,但是我们修改的时候要有一个基本原则,这里的RDB是一个比较高的成本,不能让这个操作比较频繁。        

问题:如果在两次快照(两次存档点)之间有大量的key插入删除和修改,但是在两次快照之间服务器突然挂了,就会出现数据丢失的情况!!!

 自动触发:

自动触发的场景有两种:

  1. 1.超时时间后自动触发保存。
  2. 2.通过shutdown命令关闭redis服务器就会触发自动保存。
  3. 进行主从复制的时候,主节点也会生成RDB快照,把RDB快照传给后面的从节点。 

实际上如果当redis异常关闭的时候,来不及生成RDB,就不会保存key存在RDB中。

使用linux的stat命令来观察var/lib/redis(在redis.conf中)文件下的修改rdb文件的incode编号来观察修改,如果再次执行bgsave的话,inode编号就会发送变化。 

如果是save命令就在当前进程中直接写入dump.RDB文件中写入数据,也就不存在文件替换等过程了。

自动生成RDB快照:

在配置文件中修改,修改自动生成RDB快照。

如果是save加上空字符串,那就是关闭快照 。

RDB文件改坏了:

 在etc/redis目录下打开/var/lib/redis查看vim dump.rdb。但是要把文件修改坏了并且保存的话,首选要知道redis进程的进程id。

再通过kill进程的方式,将进程的直接杀死。在这里虽然改坏了,但是看起来好像没什么问题,但是实际上有无问题得看实际情况。

文件格式检查工具:redis-check.rdb。

RDB文件的特点:

  1. RDB是一个紧凑的文件,适合全量备份的场景,比如每六个小时执行bgsave的场景,并且把RDB文件复制到远程机器或者文件系统中。
  2. Redis加载RDB回复数据的方式远远快于AOF的方式。(使用二进制进行组织数据)。
  3. RDB方式数据没办法做到实时持久化,因为每次bgsave运行都要执行fork创建子进程,属于重量级操作,频繁执行成本过高。
  4. Rdb文件用二进制的格式保存,Redis版本更替有多个版本,兼容性可能有风险。新老版本的RDB文件可能不同。

AOF(Append only file)持久策略:

RDB最大的问题就是不能实时持久化保存数据,两次快照期间,实时的数据可能随着重启而丢失。

原理:

类似于mysql的binlog,并不是存储数据,而是存储了该操作,存储在文件中,将操作内容存储在文件中,当redis重新启动的时候,就会读取AOF中的内容用来恢复数据。启动AOF,RDB就不生效了,AOF一般是关闭状态!!!!!!!

要将该命令改为yes,就能生效,就可以启动AOF了。

此时将AOF的操作保存在"appendonly.aof"文件之下,也存在/var/lib/redis的文件下(redis.conf下)。AOF是一个文本文件,每次进行操作都会被记录到文本文件中。

AOF是否会影响性能:

引入AOF后又要写内存也要写硬盘,并没有因为这样影响到redis处理请求的速度。

  1. AOF机制并非是直接把线程数据写入硬盘,而是在内存缓冲区中,积累一波后,写入硬盘。大大降低了写入硬盘的次数。
  2. 硬盘顺序读写相对随机读写的速度快,AOF每次是把数据写到文件的末尾,属于顺序写入。

如果在缓冲区中的数据,没来得及写入硬盘,就会丢失,就会导致数据不可靠!

刷新频率实际上是可以程序员自己设置的,刷新频率比较高,性能影响大,同时数据可靠性就比较高。

默认的策略是everysec每秒进行刷新,最多也就损失一秒的数据,可以在etc/redis下的redis.conf文件查看刷新策略。

AOF的文件大小会影响到redis下一次的启动时间,reids重新启动的时候要读取AOF文件的内容,而且有一些AOF文件是冗余的。比如分别多次插入数据,但是可以一次性插入成功,却分了很多次,就会造成冗余。

Redis的重写机制:

上述我们讲了redis会因为一些原因,记录冗余的AOF数据,所以我们的redis就有重写机制,可以去除掉这些冗余的数据,保留最后的结果,做到给AOF瘦身的这样的效果。

手动触发重写机制:

在redis中直接调用bgrewriteaof命令,就可以触发重写机制了。

自动触发重写机制:

AUTO-AOF-REWIRITE-MIN-SIZE:触发重写的AOF最小文件大小,默认大小是64MB。

AUTO-AOF-REWRITE-PERCENTAGE:表示需要重写时文件相对上一次增长的比例,比如原本AOF文件是1G,下次触发重写的时候就是1.5G的时候触发重写机制。

重写流程:

重写时候并不关心原本AOF文件中有啥,而是内存中的内存状态,同样的重写的时候,也会创建出子进程,子进程会读取内存中的数据,并且生成新的AOF文件,对他进行重写,也就是观察最新的内存数据,然后重写到AOF文件中。内存中的结果就已经是,用户把AOF重写后的状态。

此处写进程的方式就是很类似于RDB文件的镜像快照,不过RDB是二进制,这里是文本文件。在这里fork之前的的修改是存储在旧的AOF文件中,而fork之后则是存储在新的AOF文件中。子进程这边AOF写完后,会通知父进程,父进程会把aof-write-buf中的数据(fork之后的数据)也写入新的AOF文件中。但是这时候还在写旧的AOF文件。

如果在执行重写操作的时候,又来一个重写命令,此时不会执行命令,就直接返回了。如果在bgrewriteaof的时候正在生,成rdb快照,就会等待rdb快照生产完毕,再进行aof重写。

旧的AOF和新的AOF文件:

旧的AOF文件不能不写,如果考虑到极端情况,主机断电了,就会导致新的AOF文件不完整,旧的已经丢失了,导致文件不完整。旧的AOF文件在更替的过程中仍然会进行写入,防止主机断电导致新的没有及时更替,新的文件通过子进程和auto-rewrite-buf进行写入,子进程是在fork之前进行写入,而aof-rewrite-buf是在fork之后将数据写入新的aof文件中。

这里多次设置了key值,然而key3的值实际上最后只有555,其实最后只要设置555就可以了。

此时通过手动触发bgrewriteaof的方法,就能够重写AOF文件,变成RDB(在/var/lib/redis下边)。

混合持久化:

redis引入了混合持久化的特点,结合了RDB和AOF的特点,按照AOF的方式每个请求/操作,都记录到文件中,但是触发AOF重写的操作,就会将当前内容转化为二进制(也就是RDB文件),后续再进行操作,就追加到文件后面ÿ

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值