应用连接redis,无法获取数据池
(1)可能是由于数据持久化卡住,无法重新写入数据
如果 = yes : redis 会创建一个新的后台进程dump rdb。
假设 :创建快照(硬盘上,产生一个新的rdb文件)需要 20s时间,redis主进程,在这20s内,会继续接受客户端命令,但是,就在这20s,内,创建快照!!!,出错了,比如磁盘满了,那么redis会认为,
当前!!!,Redis is configured to save RDB snapshots, but is currently not able to persist on disk. but is currently not able to persist on disk.
那么,redis会,拒绝 新的写入,也就是说,它认为,你当下,持久化数据出现了问题
执行config set stop-writes-on-bgsave-error no 即可
(2)执行后,无法成功,报错如下
经过查看 ,发现redis无法执行任何命令,查看服务器内存占用了很多
./redis-cli -h ip -a "密码" shutdown 无法正常关闭redis
查看先有的连接数,发现连接数有九百多个 netstat -na|grep ESTABLISHED|wc -l
可能是由于连接较多,redis的数据也特别多 造成的内存占用,无法释放
断开redis的连接后,进行持久化保存bgsave---重启redis,为了避免,配置一下redis的淘汰机制和redis的最大使用内存
maxmemory-policy allkeys-lru
maxmemory 8G (不要超过10个G)
现在连接上redis,就可以正常查询了,启动应用后,发现日志再报(error) LOADING Redis is loading the dataset in memory
这是因为数据量过大,redis刚启动需要将之持久化的数据重新写入,等待数据写入完成以后即可正常访问
参数:
maxmemory参数用于控制redis可使用的最大内存容量。如果超过maxmemory的值,就会动用淘汰策略来处理expaire字典中的键;
关于redis的淘汰策略:
Redis提供了下面几种淘汰策略供用户选择,其中默认的策略为noeviction策略:
· noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错。
· allkeys-lru:在主键空间中,优先移除最近未使用的key。
· volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。
· allkeys-random:在主键空间中,随机移除某个key。
· volatile-random:在设置了过期时间的键空间中,随机移除某个key。
· volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。
PS:
关于maxmemory的设置,如果redis的应用场景是作为db使用,那不要设置这个选项,因为db是不能容忍丢失数据的。
如果作为cache使用,则可以启用这个选项(其实既然有淘汰策略,那就是cache了。。。)
但是在集群环境下(尤其是有多个slavers的情形),maxmeomory的值并不是实际redis使用的内存,这个选项值并没有包括slaver的output buffer。
redis早期版本出过一个bug,在多个slaver的情形下,设置了maxmemory值,同时设定了淘汰策略,会造成master上的数据被渐渐擦除。
antirez先生给出了这个问题的原因:
1 2 3 4 5 6 7 |
|
简单说来,删除过期键,需要产生del命令发送给slaver,如果slaver足够多,output buffer将会占用足够多的内存,导致更多的键过期,如此往复,陷入了无线循环。
解决方案有多种,比如output buffer可以不计入maxmemory。
因此,在3.0版本的配置说明中有了以下表述:
1 2 3 4 5 6 7 8 9 10 11 12 |
|
由此可见,如果有slaver的情况下,建议适当调低maxmemory,给output buffer留出一定的可用空间是合理的。