Redis-常见持久化开发运维问题
开发运维常见问题
fork操作
1.同步操作 :fork操作只是做一个内存页的拷贝,而不是完全作为一个内存的拷贝,所以大部分情况下速度都是非常快的,但是呢,如果说本身fork操作比较慢,或者说卡在某个地方了,那么就会阻塞redis的主线程
2.与内存量息息相关:内存越大,耗时越长(与机器类型有关 虚拟机和物理机 相对来说虚机较慢,物理机较快,但不是绝对的,是相对的,只是说和内存量有关和机型也有关系,本身是一个同步的操作,所以会引起一个问题,如果它非常慢,他执行了一秒,对于redis来说,就会卡住一秒,对于一个每秒执行QBS上万的操作,那么就会卡住一秒,也会造成客户端超时)
3.info:latest_fork_usec :如何看fork执行的时间,在redis中有一个info可以查持久化的时间,latest_fork_usec也就是说上一次所执行fork操作所消耗的微秒数。如果这个数比较大,会阻塞redis,如果需要对他重点关注呢,可以实行重点监测或者相对应的告警
改善fork
1.优先使用物理机或者高效支持fork操作的虚拟化技术
2.控制Redis实例最大可用内存 : maxmemory
3.合理配置Linux内存分配策略:vm.overcommit_memory = 1 (默认值为0,就是说,当它发现没有足够内存去做内存分配的时候,就不做内存分配,对于fork来说,会照成阻塞)
4.降低fork频率 : 例如放宽AOF重写自动触发时机,减少不必要的AOF的重写,不必要的全量复制
进程外开销:子进程开销与优化
1.CPU:
开销:RDB和AOF文件生成,属于CPU密集型(体现在文件的重写,就相当于RDB和AOF最终都要将内存中的数据存储到硬盘中,通常这个子进程的cpu开销达到90%以上,因为他的写入是一个非常集中的过程)
优化:不做CPU绑定,不和CPU密集型部署 (不要做CPU的一个绑定,也就是说不让把redis进程绑定在一个CPU上,这样的话,如果发生了这样的子进程的话,他会和主进程集中消耗这个CPU,会对主进程造成很大的影响,第二个呢,不要和CPU密集型应用一起部署,这样的话就会保证不会产生CPU的过度紧张,还有一个就是这里没有写的是,我们在单机多部署的时候,一定要保证不要发生大量的AOF重写或者说RDB的bgsave的过程,这样保证可以节省一定的CPU)
2.内存:
开销:fork内存开销, copy-on-write (内存的开销是非常明显的,因为他要生成一个子进程,是要通过fork来争的,占用内存是相当于等于主进程的,但是Linux有一个写时拷贝技术(copy-on-write) 机制,父子进程会共享内存页,但是当父进程写请求的时候,会创建一个副本,这个时候才会消耗内存,而在整个期间子进程会共享主内存的开张)
优化:echo never > /sys/kernel/mm/transparent_hugepage/enabled
3.硬盘
开销:AOF和RDB文件写入,可以结合iostat,iotop工具分析
硬盘优化:
1.不要和高硬盘负载服务部署一起: 存储服务,消息队列等
2. no-appendfsync-on-write = yes
3.根据写入量决定磁盘类型 : 例如 ssd(固态硬盘)
4.单机多实例持久化文件目录可以考虑分盘或者说资源限制的操作
AOF追加阻塞
AOF阻塞定位
1.Redis日志 :查看日志
2.info persistence (信息的持久化)
3.通过硬盘去观察