Redis持久化以及相关优化
2019-06-22 本文已影响0人
彩云Coding
Redis持久化以及相关优化
1.windows安装redis
(1)https://github.com/MicrosoftArchive/redis
(2)点击release
![redis_windows.png](https://img.haomeiwen.com/i14720179/cc67d62aa7c6dead.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)(3)选择安装文件并且下载,我这边选择的是镜像文件,平各自喜好。
下载成功之后就可以双击安装,傻瓜式安装这里就不一一赘述了。
安装成功之后的目录结构如下图所示:
redis安装目录机构.png2.windows使用redis
(1)redis-cli.exe //redis命令行
(2)shutdown //关闭redis服务
(3)exit //退出命令行
(4)redis-server.exe redis.windows.conf //启动redis服务
redis启动.png
3.redis持久化配置
redis持久化设置有两种方式RDB
和AOF
,RDB
主要是全量备份,AOF
主要是将写操作以命令的形式append
到日志文件中,两者各有优缺点,这里我们使用RDB
的方式,最主要的命令:
CONFIG SET save '2 1' //设置备份机制:2秒内至少有一个键被改动,则触发备份,更新dump.rdb文件
CONFIG SET save '' //关闭rdb持久化
config rewrite //如果调用config set 之后没有使用config rewrite命令的话是不会将更改保存 redis.conf的,只对当前允许的redis实例生效,进程结束之后就失效里,所以如果想保存到配置文件的话别忘了在使用config set 之后调用config rewrite
bgsave //手动强制写入rdb
备注:
aof:如果没有打开配置:CONFIG SET appendonly yes,那么就算有AOF文件,redis在启动的时候也不会去加载这个文件。
rdb:只要有这个redis文件,就算rdb的功能没有打开,rdb在启动的时候也会去加载rdb文件。
4.redis连接异常保护处理的必要性
redis
的配置有最大空闲连接时间,你可以先看看配置是什么CONFIG GET TIMEOUT
。如果 CONGIG SET TIMEOUT 0
设置为0
,则redis
服务器则不会主动断开连接,万一由于某些特殊情况导致redis连接迟迟没有返回,而你又没有设置超时时间,那么这是极度危险的。
/*
离线队列offline_queue:当前连接不可用时,客户端会将命令放置到离线队列之中,同时重连接规则尝试连接服务器,每次尝试失败都会清空离线队列。
长度查询:client.offline_queue.length
可使用enable_offline_queue:false选项关闭该功能。
这个配置,我的理解是禁止离线命令队列,是否某种意义上也就在没有活的连接时重试了.
*/
enable_offline_queue: false,
/*
A function that receives an options object as parameter including the retry attempt, the total_retry_time indicating how much time passed since the last time connected, the error why the connection was lost and the number of times_connected in total. If you return a number from this function, the retry will happen exactly after that time in milliseconds. If you return a non-number, no further retry will happen and all offline commands are flushed with errors. Return an error to return that specific error to all offline commands. Example below.
这是一个函数,接受一个option对象作为参数,其参数包含重试attempt,指示距离最后一次连接的时间total_retry_time,为什么连接失败的error 和总共重连次数的times_connected 。如果在这个函数中你返回一个数字,那么将在这个数字的毫秒数的时间后尝试重连。如果你返回一个非数字,则不会再发生重连,并且所有脱机命令将会刷新并显示错误。返回一个错误,将特定错误返回给所有脱机命令。
*/
retry_strategy: function (options) {
if (options.error && options.error.code === 'ECONNREFUSED') {
// End reconnecting on a specific error and flush all commands with
// a individual error
return new Error('The server refused the connection');
}
if (options.total_retry_time > 1000 * 2) {
// End reconnecting after a specific timeout and flush all commands
// with a individual error
return new Error('Retry time exhausted');
}
if (options.attempt > 1) {
// End reconnecting with built in error
return new Error('重试次数大于1');
}
// reconnect after
//return Math.min(options.attempt * 100, 3000);
return new Error('不重试'); //不希望重试,希望直接去查数据库
}
跑redis的机器至少要预留和redis占用内存同样大小的空闲内存空间,redis RDB持久化进行fork时最坏会占用双倍内存,内存不足就会动用交换分区,系统性能急剧下降。
一般情况下,redis的超时时间(timeout 60)需要大于你的客户端连接池的超时时间, 否则会产生大量close_wait导致服务上没有可用的文件描述符,进一步导致网络不可用,进一步导致无法写redis。
开启redis日志功能:
配置logfile和loglevel
logfile "/usr/local/logs/redis.log"
loglevel debug
创建目录和日志文件
mkdir logs
touch redis.log
修改日志文件的权限
chmod 777 redis.log
重启redis。
问题:39的每一次构建都是重新起一个新的容器?里面没有预设这些文件夹,是否要改基础镜像?不然构建时redis起不来。
修改启动redis时的警告:
1. WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
baklog参数实际控制的是已经3次握手成功的还在accept queue的大小。
net.core.somaxconn:
是linux中的一个kernel参数,表示socket监听(listen)的backlog上限。backlog是socket的监听队列,当一个请求(request)尚未被处理或建立时,他会进入backlog。而socket server可以一次性处理backlog中的所有请求,处理后的请求不再位于监听队列中。当server处理请求较慢,以至于监听队列被填满后,新来的请求会被拒绝。所以说net.core.somaxconn限制了接收新 TCP 连接侦听队列的大小。对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。大多数环境这个值建议增加到 1024 或者更多。
2.WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
overcommit_memory:
设置内存分配策略(可选,根据服务器的实际情况进行设置)
/proc/sys/vm/overcommit_memory
可选值:0、1、2。
0, 表示内核将检查是否有足够的可用内存供应用进程使用;如果有足够的可用内存,内存申请允许;否则,内存申请失败,并把错误返回给应用进程。
1, 表示内核允许分配所有的物理内存,而不管当前的内存状态如何。
2, 表示内核允许分配超过所有物理内存和交换空间总和的内存
注意:redis在dump数据的时候,会fork出一个子进程,理论上child进程所占用的内存和parent是一样的,比如parent占用的内存为8G,这个时候也要同样分配8G的内存给child,如果内存无法负担,往往会造成redis服务器的down机或者IO负载过高,效率下降。所以这里比较优化的内存分配策略应该设置为 1(表示内核允许分配所有的物理内存,而不管当前的内存状态如何)。
3.WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
解决方案:
第一个警告:
第一种说法: 临时方案:echo 511 > /proc/sys/net/core/somaxconn
永久解决方案:将其写入/etc/rc.local文件中。
重启redis
第二种说法: 永久方案:vi /etc/sysctl.conf
添加net.core.somaxconn=1024
sysctl -p
重启redis
第二个警告:
第一种说法: 临时方案:echo "vm.overcommit_memory=1" > /etc/sysctl.conf
永久解决方案:vi /etc/sysctl.conf
添加vm.overcommit_memory = 1
sysctl -p
重启redis
第三个警告:
第一种说法: 临时方案:echo never > /sys/kernel/mm/transparent_hugepage/enabled。
永久解决方案:将上面这句话写入/etc/rc.local文件中。
重启
综上想要永久解决这三个警告需执行:
vi /etc/sysctl.conf
添加net.core.somaxconn=1024
添加vm.overcommit_memory = 1
sysctl -p
将echo never > /sys/kernel/mm/transparent_hugepage/enabled写入/etc/rc.local 文件中。
重启redis
容器内修改这些内核参数不生效,需要请教一下丁教和光明哥