【备份】对redis数据耐久化的一些主意ITeye - 超凡娱乐

【备份】对redis数据耐久化的一些主意ITeye

2019年02月20日11时57分05秒 | 作者: 辰铭 | 标签: 数据,快照,方法 | 浏览: 2707

原文地址:

数据耐久化浅显讲就是把数据保存到磁盘上,确保不会由于断电等要素丢掉数据。

redis需求经常将内存中的数据同步到磁盘来确保耐久化。redis支撑两种耐久化方法,一种是 Snapshotting(快照)也是默许方法,另一种是Append-only file(缩写aof)的方法。先介绍下这两种dump方法再讲讲自己遇到的一些现象和主意,前面的内容是从网上整理出来的。

Snapshotting
快照是默许的耐久化方法。这种方法是就是将内存中数据以快照的方法写入到二进制文件中,默许的文件名为dump.rdb。能够经过装备设置主动做快照耐久 化的方法。咱们能够装备redis在n秒内假如超越m个key被修正就主动做快照,下面是默许的快照保存装备

save 900 1  #900秒内假如超越1个key被修正,则主张快照保存
save 300 10 #300秒内容如超越10个key被修正,则主张快照保存
save 60 10000

下面介绍详细的快照保存进程

1.redis调用fork,现在有了子进程和父进程。

2. 父进程持续处理client恳求,子进程担任将内存内容写入到临时文件。由于os的写时仿制机制(copy on write)父子进程会同享相同的物理页面,当父进程处理写恳求时os会为父进程要修正的页面创立副本,而不是写同享的页面。所以子进程的地址空间内的数 据是fork时刻整个数据库的一个快照。

3.当子进程将快照写入临时文件结束后,用临时文件替换原本的快照文件,然后子进程退出。

client 也能够运用save或许bgsave指令告诉redis做一次快照耐久化。save操作是在主线程中保存快照的,由于redis是用一个主线程来处理一切 client的恳求,这种方法会堵塞一切client恳求。所以不引荐运用。另一点需求留意的是,每次快照耐久化都是将内存数据完好写入到磁盘一次,并不 是增量的只同步脏数据。假如数据量大的话,并且写操作比较多,必定会引起许多的磁盘io操作,或许会严重影响功能。

别的由于快照方法是在必定间隔时刻做一次的,所以假如redis意外down掉的话,就会丢掉最终一次快照后的一切修正。假如运用要求不能丢掉任何修正的话,能够选用aof耐久化方法。下面介绍

Append-only file

aof 比快照方法有更好的耐久化性,是由于在运用aof耐久化方法时,redis会将每一个收到的写指令都经过write函数追加到文件中(默许是 appendonly.aof)。当redis重启时会经过从头履行文件中保存的写指令来在内存中重建整个数据库的内容。当然由于os会在内核中缓存 write做的修正,所以或许不是当即写到磁盘上。这样aof方法的耐久化也仍是有或许会丢掉部分修正。不过咱们能够经过装备文件告诉redis咱们想要 经过fsync函数强制os写入到磁盘的机遇。有三种方法如下(默许是:每秒fsync一次)

appendonly yes              //启用aof耐久化方法
# appendfsync always      //每次收到写指令就当即强制写入磁盘,最慢的,可是确保彻底的耐久化,不引荐运用
appendfsync everysec     //每秒钟强制写入磁盘一次,在功能和耐久化方面做了很好的折中,引荐
# appendfsync no    //彻底依靠os,功能最好,耐久化没确保

aof 的方法也一起带来了另一个问题。耐久化文件会变的越来越大。例如咱们调用incr test指令100次,文件中有必要保存悉数的100条指令,其实有99条都是剩余的。由于要康复数据库的状况其实文件中保存一条set test 100就够了。为了紧缩aof的耐久化文件。redis供给了bgrewriteaof指令。收到此指令redis将运用与快照相似的方法将内存中的数据 以指令的方法保存到临时文件中,最终替换原本的文件。详细进程如下

1. redis调用fork ,现在有父子两个进程
2. 子进程依据内存中的数据库快照,往临时文件中写入重建数据库状况的指令
3.父进程持续处理client恳求,除了把写指令写入到原本的aof文件中。一起把收到的写指令缓存起来。这样就能确保假如子进程重写失利的话并不会出问题。
4.当子进程把快照内容写入已指令方法写到临时文件中后,子进程发信号告诉父进程。然后父进程把缓存的写指令也写入到临时文件。
5.现在父进程能够运用临时文件替换老的aof文件,偏重命名,后边收到的写指令也开端往新的aof文件中追加。

需求留意到是重写aof文件的操作,并没有读取旧的aof文件,而是将整个内存中的数据库内容用指令的方法重写了一个新的aof文件,这点和快照有点相似。

运维上的主意

其实快照和aof相同,都运用了Copy-on-write技能。屡次实验发现每次做数据dump的时分,内存都会扩展一倍(关于这个问题能够参阅我上一年写的,许多人用redis做为缓存,数据量小,dump耗时十分时刻短,所以不太简单发现),这个时分会有三种状况:

一:物理内存足以满意,这个时分dump十分快,功能最好

二:物理内存+虚拟内存能够满意,这个时分dump速度会比较慢,磁盘swap繁忙,效劳功能也会下降。所幸的是经过一段比较长的时分数据dump完成了,然后内存康复正常。这个状况体系稳定性差。

三: 物理内存+虚拟内存不能满意,这个时分dump一向死着,时刻久了机器挂掉。这个状况就是灾祸!

假如数据要做耐久化又想确保稳定性,主张留空一半的物理内存。假如觉得无法承受仍是有方法,下面讲:

快照和aof虽然都运用Copy-on-write,但有个不同点,快照你无法猜测redis什么时分做dump,aof能够经过bgrewriteaof指令操控dump的机遇。

依据这点我能够在一个效劳器上敞开多个redis节点(运用多CPU),运用aof的耐久化方法。

例如在24G内存的效劳器上敞开3个节点,每天用bgrewriteaof定时从头整理数据,每个节点dump的时刻都不相同,这样理论上每个节点能够耗费6G内存,总共运用18G内存,别的6G内存在单个节点dump时用到,内存一下多运用了6G! 当然节点开的越多内存的运用率也越高。假如带宽不是问题,节点数主张 = CPU数。

我的运用里为了确保高功能,数据没有做dump,也没有用aof。由于不做dump发作的毛病远远低于做dump的时分,即便数据丢掉了,主动修正脚本能够立刻数据康复。究竟对海量数据redis只能做数据分片,那么落到每个节点上的数据量也不会许多。

redis的虚拟内存主张也不要用,用redis原本就是为了到达反常的功能,虚拟内存、aof看起来都有些鸡肋。

现在还离不开redis,由于它的mget是现在一切db里功能最好的,曾经也考虑过用tokyocabinet hash方法做mget,功能不给力。直接用redis,基本上单个redis节点mget能够到达10W/s

之前说过redis做数据dump的时分内容会扩展一倍,后来我又做了些测验,发现有些当地说的不对。

top指令并不是反映实在的内存占用状况,在top里虽然fork出来的子进程占了和父进程相同的内存,可是作为dump的时分没有写操作,实际运用的是同一份内存的数据。当有写操作的时分内存才会实在的扩展(详细是不是实在的扩展一倍不确定,或许数据是依照页分片的),这才是真实的Copy-on-write。

根据这点在做数据耐久化会愈加灵敏。

版权声明
本文来源于网络,版权归原作者所有,其内容与观点不代表超凡娱乐立场。转载文章仅为传播更有价值的信息,如采编人员采编有误或者版权原因,请与我们联系,我们核实后立即修改或删除。

猜您喜欢的文章