共计 4707 个字符,预计需要花费 12 分钟才能阅读完成。
本文首发于 vivo 互联网技术 微信公众号
链接:https://mp.weixin.qq.com/s/MaeXn-kmgLUah78brglFkg
作者:Yang Yijun
本文次要形容 Linux Page Cache 优化的背景、Page Cache 的基本概念、列举之前针对 Kafka 的 IO 性能瓶颈采取的一些解决方案、如何进行 Page Cache 相干参数调整以及性能优化前后成果比照。
一、优化背景
当业务快速增长,每天须要解决万亿记录级数据量时。在读写数据方面,Kafka 集群的压力将变得微小,而磁盘 IO 成为了 Kafka 集群最大的性能瓶颈。
当呈现入流量突增或者出流量突增状况,磁盘 IO 继续处于被打满状态,导致无奈解决新的读写申请,甚至造成局部 broker 节点雪崩而影响集群的稳固。
如下图所示,磁盘 IO 被继续打满:
这重大的影响了集群的稳固,从而影响业务的稳固运行。对此,咱们做出了一些针对性的优化计划:
- 对 Linux 操作系统的 Page Cache 参数进行优化;【本文次要解说内容】
- 对 kafka 集群用户的出入流量进行限度,防止出入流量突增给磁盘 IO 带来的压力;【本文对此计划不做解说】
- 按业务对集群进行资源组隔离(集群 broker 的物理隔离),防止不同业务间因为共享磁盘 IO 相互影响;【本文对此计划不做解说】
- 对 Kafka 集群 broker 节点服务参数进行优化;【本文对此计划不做解说】
- 革新 Kafka 正本迁徙源码,实现增量并发正本迁徙,缩小正本迁徙给集群 broker 节点磁盘 IO 带来的压力;【本文对此计划不做解说】
- 开发一套 Kafka 集群主动负载平衡服务,定期对集群进行负载平衡;【本文对此计划不做解说】
- 采纳 IO 性能更好的 SSD 固态硬盘替换一般的机械硬盘;进行磁盘 RAID 让 broker 外部多块磁盘间 IO 负载更加平衡【本文对此计划不做解说】
- 革新 Kafka 源码,对 Kafka 集群单个 broker 及单个 topic 进行出入流量限度,实现流量对最细粒度管制;当单个 broker 流量突增时能够对其进行下限限度,防止节点被异样流量打挂;【本文对此计划不做解说】
- 革新 Kafka 源码,修复正本迁徙工作启动后不可手动终止的缺点,实现当因迁徙导致负载过高却无奈进行的问题;【本文对此计划不做解说】
- 机房网络带宽的竞争也将间接的影响到 follower 同步 leader 的数据,最终将导致 follower 同步拉取历史数据而减少 IO 负载,因而须要对网络带宽进行优先级打标,当有竞争时进步 Kafka 集群的优先级,防止 kafka 集群的 broker 和其余大量耗费网络带宽的业务共用机房交换机。【本文对此计划不做解说】
以上只是列举了几点次要的优化计划,还有一些其余的内容这里不再赘述。本文咱们次要来解说一下 Linux 操作系统的 Page Cache 参数调优 。
二、基本概念
1、什么是 Page Cache?
Page Cache 是针对文件系统的缓存,通过将磁盘中的文件数据缓存到内存中,从而缩小磁盘 I / O 操作进步性能。
对磁盘的数据进行缓存从而进步性能次要是基于两个因素:
- 磁盘拜访的速度比内存慢好几个数量级(毫秒和纳秒的差距);
- 被拜访过的数据,有很大概率会被再次拜访。
文件读写流程如下所示:
2、读 Cache
当内核发动一个读申请时(例如过程发动 read() 申请),首先会查看申请的数据是否缓存到了 Page Cache 中。
如果有,那么间接从内存中读取,不须要拜访磁盘,这被称为 cache 命中(cache hit);
如果 cache 中没有申请的数据,即 cache 未命中(cache miss),就必须从磁盘中读取数据。而后内核将读取的数据缓存到 cache 中,这样后续的读申请就能够命中 cache 了。
page 能够只缓存一个文件局部的内容,不须要把整个文件都缓存进来。
3、写 Cache
当内核发动一个写申请时(例如过程发动 write() 申请),同样是间接往 cache 中写入,后备存储中的内容不会间接更新(当服务器呈现断电关机时,存在数据失落危险)。
内核会将被写入的 page 标记为 dirty,并将其退出 dirty list 中。内核会周期性地将 dirty list 中的 page 写回到磁盘上,从而使磁盘上的数据和内存中缓存的数据统一。
当满足以下两个条件之一将触发脏数据刷新到磁盘操作:
- 数据存在的工夫超过了 dirty_expire_centisecs(默认 300 厘秒,即 30 秒)工夫;
- 脏数据所占内存 > dirty_background_ratio,也就是说当脏数据所占用的内存占总内存的比例超过 dirty_background_ratio(默认 10,即零碎内存的 10%)的时候会触发 pdflush 刷新脏数据。
4、Page Cache 缓存查看工具
咱们如何查看缓存命中率呢?在这里咱们能够借助一个缓存命中率查看工具 cachestat。
(1)下载安装
mkdir /opt/bigdata/app/cachestat
cd /opt/bigdata/app/cachestat
git clone --depth 1 https://github.com/brendangregg/perf-tools
(2)启动执行
(3)输入内容阐明
5、如何回收 Page Cache
执行脚本:echo 1 > /proc/sys/vm/drop_caches 这里可能须要期待一会,因为有应用程序正在写数据。
回收前:
回收后:
缓存回收后,失常状况下,buff/cache 应该是 0 的,我这里之所以不为 0 是因为有数据正在不停的写入。
三、参数调优
备注:不同硬件配置的服务器可能成果不同,所以,具体的参数值设置须要思考本人集群硬件配置。
思考的因素次要包含:CPU 核数、内存大小、硬盘类型、网络带宽等。
1、如何查看 Page Cache 参数
执行命令 sysctl -a|grep dirty
2、操作系统 Page Cache 相干参数默认值
vm.dirty_background_bytes = 0 # 和参数 vm.dirty_background_ratio 实现雷同性能,但两个参数只会有其中一个失效,示意脏页大小达到多少字节后开始触发刷磁盘
vm.dirty_background_ratio = 10
vm.dirty_bytes = 0 # 和参数 vm.dirty_ratio 实现雷同性能,但两个参数只会有其中一个失效,示意脏页达到多少字节后进行接管写申请,开始触发刷磁盘
vm.dirty_ratio = 20
vm.dirty_expire_centisecs = 3000 #这里示意 30 秒(工夫单位:厘秒)vm.dirty_writeback_centisecs = 500 #这里示意 5 秒(工夫单位:厘秒)
3、如果零碎中 cached 大量数据可能存在的问题
- 缓存的数据越多,丢数据的危险越大。
- 会定期呈现 IO 峰值,这个峰值工夫会较长,在这期间所有新的写 IO 性能会很差(极其状况间接被 hang 住)。
后一个问题对写负载很高的利用会产生很大影响。
4、如何调整内核参数来优化 IO 性能?
(1)vm.dirty_background_ratio 参数优化
当 cached 中缓存当数据占总内存的比例达到这个参数设定的值时将触发刷磁盘操作。
把这个参数适当调小,这样能够把原来一个大的 IO 刷盘操作变为多个小的 IO 刷盘操作,从而把 IO 写峰值削平。
对于内存很大和磁盘性能比拟差的服务器,应该把这个值设置的小一点。
# 设置办法 1:sysctl -w vm.dirty_background_ratio=1(长期失效,重启服务器后生效)
#设置办法 2(永恒失效):
echo vm.dirty_background_ratio=1 >> /etc/sysctl.conf
sysctl -p /etc/sysctl.conf
#设置办法 3(永恒失效):
#当然你还能够在 /etc/sysctl.d/ 目录下创立一个本人的参数优化文件,把系统优化参数进行归类寄存,而后设置失效,如:touch /etc/sysctl.d/kafka-optimization.conf
echo vm.dirty_background_ratio=1 >> /etc/sysctl.d/kafka-optimization.conf
sysctl --system
(2)vm.dirty_ratio 参数优化
对于写压力特地大的,倡议把这个参数适当调大;对于写压力小的能够适当调小;如果 cached 的数据所占比例(这里是占总内存的比例)超过这个设置,
零碎会进行所有的应用层的 IO 写操作,期待刷完数据后复原 IO。所以万一触发了零碎的这个操作,对于用户来说影响十分大的。
(3)vm.dirty_expire_centisecs 参数优化
这个参数会和参数 vm.dirty_background_ratio 一起来作用,一个示意大小比例,一个示意工夫;即满足其中任何一个的条件都达到刷盘的条件。
为什么要这么设计呢?咱们来试想一下以下场景:
- 如果只有参数 vm.dirty_background_ratio,也就是说 cache 中的数据须要超过这个阀值才会满足刷磁盘的条件;
- 如果数据始终没有达到这个阀值,那相当于 cache 中的数据就永远无奈长久化到磁盘,这种状况下,一旦服务器重启,那么 cache 中的数据必然失落。
联合以上状况,所以增加了一个数据过期工夫参数。当数据量没有达到阀值,然而达到了咱们设定的过期工夫,同样能够实现数据刷盘。
这样能够无效的解决上述存在的问题,其实这种设计在绝大部分框架中都有。
(4)vm.dirty_writeback_centisecs 参数优化
实践上调小这个参数,能够进步刷磁盘的频率,从而尽快把脏数据刷新到磁盘上。但肯定要保障间隔时间内肯定能够让数据刷盘实现。
(5)vm.swappiness 参数优化
禁用 swap 空间,设置 vm.swappiness=0
5、参数调优前后成果比照
(1)写入流量比照
从下图能够看出,优化前写入流量呈现大量突刺,稳定十分大,优化后写入流量更加平滑。
(2)磁盘 IO UTIL 比照
从下图能够看出,优化前 IO 呈现大量突刺,稳定十分大,优化后 IO 更加平滑。
(3)网络入流量比照
从下图能够看出,优化前后对网络入流量并无影响。
四、总结
这里不同机型,不同硬件配置可能最终优化成果也不一样,然而参数变动的趋势应该是统一的。
1、当 vm.dirty_background_ratio、vm.dirty_expire_centisecs 变大时
- 出入流量抖动变大,呈现大量突刺;
- IO 抖动变大,呈现大量突刺,磁盘有间断打满的状况;
- 出入流量均匀大小不受影响;
2、当 vm.dirty_background_ratio、vm.dirty_expire_centisecs 变小时
- 出入流量抖动变小,趋于平滑稳固,无突刺;
- 磁盘 IO 抖动变小,无突刺,磁盘 IO 无打满状况;
- 出入流量均匀大小不受影响;
3、当 vm.dirty_ratio 变小(低于 10)
- 出入流量隔一段时间呈现一个显著的波谷;这是因为 cache 数据量超过 vm.dirty_ratio 设定的值将阻塞写申请,进行刷盘操作。
4、当 vm.dirty_ratio 变大时(高于 40),出入流量无显著的波谷,流量平滑;
5、当以下三个参数别离为对应值时,出入流量十分平滑,趋于一条直线;
- vm.dirty_background_ratio=1
- vm.dirty_ratio=80
- vm.dirty_expire_centisecs=1000
6、如下图所示,整个调整过程均匀流量不受影响
更多内容敬请关注 vivo 互联网技术 微信公众号
注:转载文章请先与微信号:Labs2020 分割