Redis配置上遇到的一些问题 - Wangxiaoman/tech-note GitHub Wiki

redis数据超过服务器内存一半,RDB的时候报错

log如下

[1821] 10 Nov 09:59:04.086 # Can't save in background: fork: Cannot allocate memory
[1821] 10 Nov 09:59:10.002 * 1 changes in 900 seconds. Saving...

原因是linux的内核参数vm.overcommit_memory的限制,该参数linux对于进程的内存保护机制

vm.overcommit_memory = 0:则比较 此次请求分配的虚拟内存大小和系统当前空闲的物理内存加上swap,决定是否放行
vm.overcommit_memory = 1,直接放行
vm.overcommit_memory = 2:则会比较 进程所有已分配的虚拟内存加上此次请求分配的虚拟内存和系统当前的空闲物理内存加上swap,决定是否放行

直接将vm.overcommit_memory设置为1,对redis在做rdb的fork进程放行

在/etc/sysctl.conf文件里面加入或者直接删除也可以,因为它缺省值就是0
vm.overcommit_memory = 0
运行使之生效
#sysctl -p

redis同步slave的时候,复制中断和无限同步问题

相关参数

  • client-output-buffer-limit,通过CONFIG GET *查看,可以找到客户端输出缓冲区的默认配置
167) "client-output-buffer-limit"
168) "normal 0 0 0 slave 268435456 67108864 60 pubsub 33554432 8388608 60" 
  1. 对于普通客户端来说,限制为0,也就是不限制。因为普通客户端通常采用阻塞式的消息应答模式,何谓阻塞式呢?如:发送请求,等待返回,再发送请求,再等待返回。这种模式下,通常不会导致Redis服务器输出缓冲区的堆积膨胀;
  2. 对于Pub/Sub客户端(也就是发布/订阅模式),大小限制是8M,当输出缓冲区超过8M时,会关闭连接。持续性限制是,当客户端缓冲区大小持续60秒超过2M,则关闭客户端连接;
  3. 对于slave客户端来说,大小限制是256M,持续性限制是当客户端缓冲区大小持续60秒超过64M,则关闭客户端连接。

解决方案:在给redis挂slave的时候,如果出现无限同步,可以配置client-output-buffer-limit slave 0 0 0,不限制缓冲区大小。

  • repl-backlog-size

解决方案:repl-backlog-size 是一个环形缓冲区,整个master进程中存贮,所有slave公用。如果出现同步失败,将改值配置调大。

redis启动的warning处理

  • 几个相关参数
#最大队列长度,应付突发的大并发连接请求
net.core.somaxconn = 65535
#半连接队列长度,此值受限于内存大小
net.ipv4.tcp_max_syn_backlog = 20480
#内存分配策略
vm.overcommit_memory = 1

echo never > /sys/kernel/mm/transparent_hugepage/enabled
  • net.core.somaxconn 此值表示网络连接的队列大小(同一个端口建立tcp连接,等待连接的队列大小值),在配置文件redis.conf中的“tcp-backlog 511”就配置在高并发环境下的最大队列大小,此值受限于系统的somaxconn与tcp_max_syn_backlog这两个值,所以应该把这两个内核参数值调大

redis主从需要注意的问题

3.2之前的版本,主上的命令 expire key,但是从在执行的时候,并不会将key删除,而是ttl时间为0,这样这个key在从上是一直可以查询到的。