MISCONF Redis is configured to save RDB snapshots, but is currently not able to persist on disk. Commands that may modify the data set are disabled. Please check Redis logs for details about the error.
redis被配置成保存数据库快照模式,但它现在不能持久化到磁盘,用来修改集合数据的命令不能用。请查看Redis日志的详细错误信息。
Redis中是把数据保存到内存中的,但是它也会定期的把数据写会到硬盘中。
Redis保存数据有两种方式:
1.快照模式(Snapshot)RDB
它支持两种快照模式:
a)定时快照,既按一定时间将内存中的数据保存到磁盘上。
b)定量快照,既按数据变化一定次数后将数据保存到磁盘上。、
2.写模式(Append Only File)AOF
这种模式下Redis会把所有次改数据的命令,保存到一个只能追加的ASAP文件中,
当Redis重启时,会把这个文件中的命令全部执行一遍。
是保存到一个文件中,在redis.conf可行配置
dbfilename dump.rdb
1)当有相关操作时,redis父进程调用fork(),创建子进程。
2)父进程继续处理client请求,子进程负责将内存内容写入到临时文件。由于os的写时复制机制
(copy on write)父子进程会共享相同的物理页面,当父进程处理写请求时os会为父进程要修改
的页面创建副本,而不是写共享的页面。所以子进程的地址空间中的数据是fork()时刻整个数据库
的一个快照。
3)当子进程将快照写入临时文件完毕后,用临时文件替换原有的快照文件,然后子进程退出。
Redis的client也可以使用"save"或者"bgsave"命令通知redis做一次快照持久化。save操作是在
主线程中保存快照的,
由于redis是用一个主线程(即单进程)来处理所有client的请求,这种方式将会阻塞所有client请求,
不推荐使用。
值得注意:每次保存 RDB 的时候,Redis都要fork()出一个子进程,并由子进程来进行实际的持久化工作。
Redis在持久化数据时,不能够保存到磁盘。导致redis抛出异常
解决方案:
1)config set stop-writes-on-bgsave-error no,这种方法不建议,只是让程序忽略这个异常,
能够继续执行下去,数据不能持久化
redis 127.0.0.1:6376> config set stop-writes-on-bgsave-error no
2)加大存储空间
当内存不足时,会发生OOM killer(OOM=out-of-memory)。它会选择杀死一些进程(用户态进程,不是内核线程),以便 释放内存。
vm.overcommit_memory:
0 — 默认设置。个人理解:当应用进程尝试申请内存时,内核会做一个检测。内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。举个例子,比如1G的机器,A进程已经使用了500M,当有另外进程尝试malloc 500M的内存时,内核就会进行check,发现超出剩余可用内存,就会提示失败。
1 — 对于内存的申请请求,内核不会做任何check,直到物理内存用完,触发OOM杀用户态进程。同样是上面的例子,1G的机器,A进程500M,B进程尝试malloc 500M,会成功,但是一旦kernel发现内存使用率接近1个G(内核有策略),就触发OOM,杀掉一些用户态的进程(有策略的杀)。
2 — 当 请求申请的内存 >= SWAP内存大小 + 物理内存 * N,则拒绝此次内存申请。解释下这个N:N是一个百分比,根据overcommit_ratio/100来确定,比如overcommit_ratio=50,那么N就是50%。
vm.overcommit_ratio
只有当vm.overcommit_memory = 2的时候才会生效,内存可申请内存为
SWAP内存大小 + 物理内存 * overcommit_ratio/100
所以修vm.overcommit_memory参数也可以避免一些错误,修改vm.overcommit_memory=1
在/etc/sysctl.conf 添加一项 'vm.overcommit_memory = 1' ,然后重启
(或者运行命令'sysctl vm.overcommit_memory=1' )使其生效。