缘起:php
今天早晨收到报警,服务不干活了,赶忙起来看问题。。。redis
为了尽快让服务可用,尝试重启服务,发现服务起不来,报错数据库
redis connection failed!
看起来是redis挂了,可是发现redis的进程还在。进一步看服务的错误日志:缓存
redis.clients.jedis.exceptions.JedisDataException: MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the d
ata set are disabled. Please check Redis logs for details about the error.
redis持久化失败,服务配置了redis rdb持久化方式,为啥失败呢?内存和硬盘看了下,果真硬盘满了。清理硬盘ok了。安全
redis持久化策略(RDB/AOF)app
一、RDB快照(snapshots)性能
缺省状况状况下,Redis把数据快照存放在磁盘上的二进制文件中,文件名为dump.rdb。你能够配置Redis的持久化策略,例如数据集中每N秒钟有超过M次更新,就将数据写入磁盘;或者你能够手工调用命令SAVE或BGSAVE。spa
数据保存的目录:操作系统
工做原理设计
写时复制(copy-on-write/COW)技术:
写入时复制(Copy-on-write)是一个被使用在程式设计领域的最佳化策略。其基础的观念是,若是有多个呼叫者(callers)同时要求相同资源,他们会共同取得相同的指标指向相同的资源,直到某个呼叫者(caller)尝试修改资源时,系统才会真正复制一个副本(private copy)给该呼叫者,以免被修改的资源被直接察觉到,这过程对其余的呼叫只都是通透的(transparently)。此做法主要的优势是若是呼叫者并无修改该资源,就不会有副本(private copy)被创建。
二、APPEND ONLY MODE(AOF)
快照模式并不十分健壮,当系统中止,或者无心中Redis被kill掉,最后写入Redis的数据就会丢失。这对某些应用也许不是大问题,但对于要求高可靠性的应用来讲,Redis就不是一个合适的选择。
Append-only文件模式是另外一种选择。
你能够在配置文件中打开AOF模式:
选项:
一、appendfsync no
当设置appendfsync为no的时候,Redis不会主动调用fsync去将AOF日志内容同步到磁盘,因此这一切就彻底依赖于操做系统的调试了。对大多数Linux操做系统,是每30秒进行一次fsync,将缓冲区中的数据写到磁盘上。
二、appendfsync everysec
当设置appendfsync为everysec的时候,Redis会默认每隔一秒进行一次fsync调用,将缓冲区中的数据写到磁盘。可是当这一 次的fsync调用时长超过1秒时。Redis会采起延迟fsync的策略,再等一秒钟。也就是在两秒后再进行fsync,这一次的fsync就无论会执行多长时间都会进行。这时候因为在fsync时文件描述符会被阻塞,因此当前的写操做就会阻塞。
因此,结论就是:在绝大多数状况下,Redis会每隔一秒进行一次fsync。在最坏的状况下,两秒钟会进行一次fsync操做。
这一操做在大多数数据库系统中被称为group commit,就是组合屡次写操做的数据,一次性将日志写到磁盘。
三、appednfsync always
当设置appendfsync为always时,每一次写操做都会调用一次fsync,这时数据是最安全的,固然,因为每次都会执行fsync,因此其性能也会受到影响
建议采用 appendfsync everysec(缺省方式)
快照模式能够和AOF模式同时开启,互补影响
三、AOF重写
AOF文件是可识别的纯文本,它的内容就是一个个的Redis标准命令,
AOF日志也不是彻底按客户端的请求来生成日志的,好比命令 INCRBYFLOAT 在记AOF日志时就被记成一条SET记录,由于浮点数操做可能在不一样的系统上会不一样,因此为了不同一份日志在不一样的系统上生成不一样的数据集,因此这里只将操做后的结果经过SET来记录。
每一条写命令都生成一条日志,AOF文件会很大。
AOF重写是从新生成一份AOF文件,新的AOF文件中一条记录的操做只会有一次,而不像一份老文件那样,可能记录了对同一个值的屡次操做。其生成过程和RDB相似,也是fork一个进程,直接遍历数据,写入新的AOF临时文件。在写入新文件的过程当中,全部的写操做日志仍是会写到原来老的 AOF文件中,同时还会记录在内存缓冲区中。当重完操做完成后,会将全部缓冲区中的日志一次性写入到临时文件中。而后调用原子性的rename命令用新的 AOF文件取代老的AOF文件
命令:BGREWRITEAOF, 咱们应该常常调用这个命令来来重写
数据恢复:
写数据的流程: