Redis持久化——问题定位与优化(三)
核心知识点:
1.fork操作
a.在RDB或AOF重写时,会执行fork操作创建子进程,fork操作是一个重量级操作。
b.改善fork操作耗时的手段:避免使用Xen、配置Redis实例最大使用内存、合理配置Liunx内存使用技术、降低fork操作的频率。
2.子进程开销监控与优化
1).CPU
2).内存
3).硬盘
3.AOF追加阻塞
Redis持久化功能一直是影响Redis性能的高发地,下面我们结合常见的持久化功能问题进行分析定位和优化。
一、fork操作
当Redis做RDB或AOF重写时,一个必不可少的操作就是执行fork操作创建子进程,对于大多是系统来说fork是一个重量级操作。
虽然fork创建的子进程不需要拷贝父进程的物理内存空间,但是会复制父进程的空间内存页表。
例如对于10GB的Redis进程,需要复制大约20MB的内存页表,因此fork操作耗时跟进程总内存息息相关,
如果使用虚拟化技术,特别是Xen虚拟机,fork操作会更耗时。
fork耗时问题定位:对于高流量的Redis实例OPS可达5万以上,
如果fork操作耗时在秒级别将拖慢Redis几万条命令执行,对线上应用延迟影响非常明显。
正常情况下,fork耗时应该是每GB消耗20毫秒。可以在info stats统计中查latest_fork_usec指标获取最近一次fork操作耗时,单位微秒。
如何改善fork操作的耗时:
1)优先使用物理机或者高效支持fork操作的虚拟机技术,避免使用Xen。
2)控制Redis实例最大可用内存,fork耗时跟内存量成正比,线上建议每个Redis实例内存控制在10GB以内。
3)合理配置Linux内存分配策略,避免物理内存不足导致fork失败。
4)降低fork操作的频率,如适度放宽AOF自动触发时机,避免不必要的全量复制等
二、子进程开销监控和优化
子进程负责AOF或者RDB文件的重写,它的运行过程主要涉及CPU、内存、硬盘三部分的消耗。
1.CPU
(1)CPU开销分析
子进程负责把进程内的数据分批写入文件,这个过程属于CPU密集操作,通常子进程对单核CPU利用率接近90%。
(2)CPU消耗。
Redis是CPU密集型操作,不要做绑定单核CPU的操作。由于子进程非常消耗CPU,会和父进程产生单核资源竞争。
不要和其他CPU密集型服务部署在一起,造成CPU过度竞争。
如果部署多个Redis实例,尽量保证同一时刻只有一个子进程执行重写工作。
2.内存
(1)内存消耗分析
子进程通过fork操作产生,占用内存大小等同于父进程,理论上需要两倍的内存来完成持久化的操作,但是Linux有写时复制机制。
父进程会共享相同的物理内存页,当父进程处理写请求时会把要修改的页创建副本,而子进程在fork操作过程中共享整个父进程内存快照。
(2)内存消耗监控
如果重写过程中存在内存页操作,父进程负责创建所修改内存页的副本,从日志中可以看出这部分的内存消耗。
父进程维护页副本消耗同RDB重写过程类似,不同之处在于AOF重写需要AOF重写缓冲区。
提示:编写shell脚本根据Redis日志可快速定位子进程重写期间内存过度消耗的情况。
(3)内存消耗优化
- 同CPU优化一样,如果部署多个Redis实例,尽量保证同一时刻只有一个子进程在工作。
- 避免大量写入时做子进程重写操作,这样将导致父进程维护大量页副本,造成内存消耗。
在Linux kernel在2.6.38内核增加了Transparent Huge pages(THP),支持huge page(2MB)的页分配,默认开启。
当开启时可以降低fork创建子进程的速度,但执行fork之后,如果开启HTP,复制页单位会从原来4KB变为2MB,会大幅增加重写期间父进程的内存消耗。
3.硬盘
(1)硬盘开销分析
子进程主要职责是把AOF或者RDB文件写入硬盘持久化,势必会造成硬盘写入压力,
根据Redis重写AOF/RDB的数据量,结合系统工具如sar、iotop等,可分析出重写期间硬盘负载情况。
(2)硬盘开销优化
- 不要和其它高硬盘负载的服务部署在一起。如:存储服务、消息队列服务。
- AOF重写时会消耗大量硬盘IO,可以开启配置no-appendfsync-on-rewrite,默认关闭。表示在AOF重写期间不做fsync操作。
- 当开启AOF功能的Redis用于高流量写入场景时,如果使用普通机械磁盘,写入吞吐一般在100MB/s左右,这是瓶颈主要在AOF同步硬盘上。
- 对于单机配置多个Redis实例的情况,可以配置不同实例分盘存储AOF文件,分摊硬盘写入压力。
三、AOF追加阻塞
当开启持久化时,常用的同步硬盘的策略是everysec,用于平衡性能和数据安全性。
对于这种方式,Redis使用另一条线程每秒执行fsync同步硬盘。当系统硬盘资源繁忙时,会造成Redis主线程阻塞。
1.阻塞流程分析:
(1)主线程负责写入AOF缓冲区。
(2)AOF线程负责每秒执行一次同步操作,并记录最近一次同步时间。
(3)主线程负责每秒执行一次同步磁盘操作,并记录最近一次同步时间。
- 如果距上次同步成功时间在2秒内,主线程直接返回。
- 如果距上次同步时间超过两秒,主线程将会阻塞,直到同步操作完成。
通过分析AOF阻塞流程可以发现两个问题:
(1)everysec配置最多可能丢失2秒数据,不是1秒。
(2)如果系统fsync缓慢,将会导致Redis主线程阻塞影响效率。
2.AOF阻塞问题定位
(1)发生AOF阻塞问题,Redis会在日志中记录其行为。
(2)每当发生AOF追加阻塞事件,在info Persistence统计中,aof_delayed_fsync指标会累加,查看这个指标方便定位AOF阻塞问题。
(3)AOF同步最多允许2秒延迟,当延迟发生时说明硬盘存在高负载问题,可以通过监控工具如iotop,定位消耗硬盘IO资源的进程。
Redis持久化——问题定位与优化(三)的更多相关文章
- Redis持久化的原理及优化
更多内容,欢迎关注微信公众号:全菜工程师小辉~ Redis提供了将数据定期自动持久化至硬盘的能力,包括RDB和AOF两种方案,两种方案分别有其长处和短板,可以配合起来同时运行,确保数据的稳定性. RD ...
- Redis持久化存储(三)
redis高级特性-发布订阅消息服务功能 Pub/Sub 订阅,取消订阅和发布实现了发布/订阅消息范式(引自wikipedia),发送者(发布者)不是计划发送消息给特定的接收者(订阅者).而是发布的消 ...
- redis学习(三)redis持久化
redis持久化 1.redis持久化介绍 我们知道redis性能之所以强悍,是因为redis在运行时将数据都存放在了访问效率远高于硬盘的内存之中.可是这带来了新的问题:在redis或者外部系统重启时 ...
- redis 持久化策略、aof配置、测试、手动持久化、aof文件体积优化
redis持久化策略 1.数据文件.rdb 2.更新日志.aof 设置aof 1.命令方式config set appendonly noconfig rewrite2.配置文件方式 redis持久化 ...
- Redis学习总结(三)--Redis持久化
Redis 是将数据存储在内存中的,如果出现断电或系统故障的时候数据就会存在丢失的现象,Redis通过将数据持久化到硬盘中来避免这个问题的出现,我们今天就来学习下 Redis 持久化. Redis 持 ...
- Redis持久化(三)
Redis持久化 Redis提供了哪些持久化机制 1. RDB持久化: 该机制是指在指定的时间间隔内将内存中的数据集快照写入磁盘. 2. AOF持久化: 该机制 ...
- Redis基础(三)Redis持久化:RDB与AOF
什么是Redis持久化? Redis是键值对的内存数据库,它将数据存储在内存里.客户端发送命令到服务器,再由服务器到内存里查找数据. 一旦Redis服务器进程退出,存储在内存里的数据就会丢失. 为了解 ...
- 深入Redis持久化
转载:https://segmentfault.com/a/1190000017193732 一.Redis高可用概述 在介绍Redis高可用之前,先说明一下在Redis的语境中高可用的含义. 我们知 ...
- 高可用Redis(七):Redis持久化
1.什么是持久化 持久化就是将数据从掉电易失的内存同步到能够永久存储的设备上的过程 2.Redis为什么需要持久化 redis将数据保存在内存中,一旦Redis服务器被关闭,或者运行Redis服务的主 ...
随机推荐
- python——操作符重载(重要)
类可以重载python的操作符 旧认识:__X__的名字 是系统定义的名字:是python特殊方法专用标识. 操作符重载使我们的对象与内置的一样.__X__的名字的方法是特殊的挂钩(hook) ...
- react-native 常用组件的用法(一)
1.View组件 View是一个支持Flexbox布局.样式.一些触摸处理.和一些无障碍功能的容器,并且它可以放到其它的视图里,也可以有任意多个任意类型的子视图. View的设计初衷是和StyleSh ...
- Docker Push 镜像到公共仓库
首选需要在https://hub.docker.com/上注册用户. 1.登录docker账号主要命令:docker login sudo docker login 2.推送镜像主要命令:docker ...
- Android下ListView的分页(9.6)
1 http://www.cnblogs.com/noTice520/archive/2012/02/10/2345057.html 2 http://www.92coding.com/blog/in ...
- .Net 异步调用
.NET异步编程之新利器——Task与Await.Async 一. FrameWork 4.0之前的线程世界 在.NET FrameWork 4.0之前,如果我们使用线程.一般有以下几种方 ...
- Dephi泛型
TArray TEnumerator(抽象) TEnumerable(抽象) 实际使用:TList TQueue TStack TPair TDictionary ,内部都包含 TValueEnume ...
- free bsd x修改UTC->SCT
#cp /usr/share/zoneinfo/Asia/Taipei /etc/localtime #ntpdate asia.pool.ntp.org #adjkerntz -a #date
- webAPI 405
web.config 配置 <system.webServer> <modules> <remove name="WebDAVModule" /> ...
- 【Python+selenium】之奇怪问题总结
问题1: <_io.TextIOWrapper name='<stderr>' mode='w' encoding='UTF-8'> Time Elapsed: 0:00:04 ...
- 嵌入式开发之手机arm汇总---科普手机arm
http://www.leiphone.com/news/201406/1102-zzl-arm.html