记录一次由于硬盘写满形成的redis没法链接

缘起: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次更新,就将数据写入磁盘;或者你能够手工调用命令SAVEBGSAVEspa

数据保存的目录:操作系统

 

工做原理设计

  • Redis forks.
  • 子进程开始将数据写到临时RDB文件中。
  • 当子进程完成写RDB文件,用新文件替换老文件。
  • 这种方式可使Redis使用copy-on-write技术。

写时复制(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, 咱们应该常常调用这个命令来来重写

 

数据恢复:

  • 若是只配置AOF,重启时加载AOF文件恢复数据;
  • 若是同时 配置了RBD和AOF,启动是只加载AOF文件恢复数据;
  • 若是只配置RBD,启动是讲加载dump文件恢复数据。

 

写数据的流程:

    1. 客户端向服务端发送写操做(数据在客户端的内存中)。
    2. 数据库服务端接收到写请求的数据(数据在服务端的内存中)。
    3. 服务端调用write这个系统调用,将数据往磁盘上写(数据在系统内存的缓冲区中)。
    4. 操做系统将缓冲区中的数据转移到磁盘控制器上(数据在磁盘缓存中)。
    5. 磁盘控制器将数据写到磁盘的物理介质中(数据真正落到磁盘上)。
相关文章
相关标签/搜索