前言背景
算法优化改版有大需求要上线, 在线特征 dump 数据逐步放量, 最终达到现有 Kafka 集群 5 倍的流量, 预计峰值达到万兆网卡 80% 左右(集群有几十个物理节点, 有几 PB 的容量, 网卡峰值流出流量会达到 800MB 左右 / sec, 写入消息 QPS 为 100w+ msgs/sec). 上下游服务需要做扩容评估, 提前做好容量规划, 保障服务持续稳定运行
L3 层 dump 特征 @xxx
1. 依赖文章特征公共服务
2. 依赖用户特征公共服务 前期可以一起共建
评估 dump 特征数据量 @xxx
kafka 新增 Topic 接收 dump 数据, 评估 kafka 是否需要扩容 @xxx
新增拼接数据流支撑 dump 特征, 需要评估新增机器 @xxx
经过对 Kafka 集群软硬件资源及利用率综合分析与评估, 决定不扩容机器, 完全可以应对流量扩大 5 倍的性能挑战
流量灰度时间表
2020-02-21 放量进度 流量灰度 10%
2020-02-24 放量进度 流量灰度 30%
2020-03-02 放量进度 流量灰度 50%
2020-03-02 放量进度 流量灰度 70%
2020-03-03 放量进度 流量灰度 85%
2020-03-05 放量进度 流量灰度 100%
优化纪实
预先优化在 topics 创建的情况下, 没有流量时做的优化工作
本次在线特征 dump 放量 topics 列表如下:
- onlinefeedback
- indata_str_onlinefeedback_mixxxbrowser
- indata_str_onlinefeedback_oppoxxxbrowser
- indata_str_onlinefeedback_3rd
- ......
violet 集群的 topics 为 indata_str_click_s3rd 和 indata_str_video_3rd_cjv 完成扩容并 rebalance 找出其他流量大的 topics 列表
以上 topic 都已经创建, 但是只覆盖了少数磁盘挂载点, violet 集群有 21 个节点 252 磁盘挂载点, 但有些 topics 的 partitions 数量不到 30, 造成磁盘利用率不高, IO 不均衡.
优化点: 扩容 partitions 数量, 覆盖更多磁盘挂载点
现状 & 优化旅程
2020-02-21 日 开始放量 topics 均值流量小于 20%, 以下是放量后 22~23 日监控数据(读写 IOPS,IOutil)
从以上数据分析, 读写 IOPS 和 ioutil 极其不均衡, 而且其中写 IOPS 走向极端上下两条线, 后来查明原因是 zk 事务日志是实时单条 commit, 大量 flink 使用 0.8.x 版本, 消费状态用 zk 存储造成的. 另外还发现 violet 出口流量不均衡, 高的 70%, 低的 10% 左右, 当时 flink 消费出现阻塞现象, 原因为上线前 Flink 未及时调大 fetch.message.max.bytes 的大小, 引发 violet 集群部分 broker 网络出口流量飙升.
2020-02-26 日在线特征 dump 数据的 topics 均值放量到 50% 左右
优化 zk 集群写入性能从 1.5k 降到 100 以内, 单事务写强制刷盘改为事务批量定期刷盘, 在线 Dump 特征流量放量, 排查 violet 集群线上隐患, 由于消费端 flink 还是依赖的较低 kafka-0.8.x 版本, 消费状态存储 zk, 导致写入频繁. 此外 zk 的日志数据和事务数据目录从数据盘调整到系统盘, 数据盘统一 Kafka 使用
客户端使用优化
serving 使用 kafka 按 key 进行 hash 分配出现生产倾斜导致消费出现 lag, 和业务方商定修改消费逻辑解决此问题
2020-03-02 日 在线特征 dump 放量 75%, 优化 violet 集群 IO 完成了 80% 以上, 支撑在线特征 100% 放量应该没有问题, 主要对 10.120.14.11,10.103.35.7,10.103.35.2,10.120.10.8 等 4 个节点 IO 削峰均衡化, 热点挂载点 IO 峰值下降 30~60% 不等, 操作策略如下:
扩容 partitions,topics 数据量大, partitions 数量少, 与业务沟通, 扩 partitions 分配到低 IO 挂载点上
迁移 partitions,partitions 目录迁移和节点迁移, 找出热点挂载点, 分析出高读写的 partitions, 迁移到使用率低的磁盘挂载点上
调整 topic 保留时间, 保证业务磁盘容量够用不浪费, 与业务沟通, 设置 topics 最小保留时间
优化前监控(3.02~3.03 区间数据)
ioutil 被打满, 磁盘非常繁忙, 响应变慢等待时间变长
优化后效果如下(3.06 日区间数据)
红框部分 IO 持续高位为当时部分 partition 迁移导致的, 可以忽略不计, 由于 2020-03-02,2020-03-03,2020-03-05 持续放量直到 100%, 优化效果不明显
2020-03-04 日客户端参数优化
jstorm
flink
03-06 日 优化 violet 集群 IO 完成了 95% 以上, 主要对 10.120.14.11,10.103.35.7,10.103.35.2,10.103.35.3,10.103.35.10,10.120.10.2,10.120.10.3,10.120.10.5,10.120.10.6,10.120.10.7,10.120.10.8,10.120.10.9,10.120.10.11 等 13 个节点 IO 削峰均衡化和磁盘使用率均衡化
下面是 3.07~3.08 日区间监控数据
3.08 日 内时间点监控数据
3.08 日是周日 通过监控获知 indata_str_onlinefeedback_mibrowser 和 indata_str_onlinefeedback_3rd-small 消费流量比较大, 需要做 IO 均衡化
indata_str_onlinefeedback_mibrowser 每秒消费流量
indata_str_onlinefeedback_3rd-small 每秒消费流量 2.5GB
03.09 日 截止下午 17:00 最近 6 小时数据(3.08 日晚优化后效果)
内核参数优化
- sudo blockdev --setra 16384 /dev/sdx
- sudo sh -c 'echo"4096"> /sys/block/sdx/queue/nr_requests'
- sudo sh -c 'echo"500"> /proc/sys/vm/dirty_writeback_centisecs'
- sudo sh -c 'echo"35"> /proc/sys/vm/dirty_ratio'
- sudo sh -c 'echo"5"> /proc/sys/vm/dirty_background_ratio'
- sudo sh -c 'echo"2000"> /proc/sys/vm/dirty_expire_centisecs'
2020-03-11 日 截止下午 17:00 最近 6 小时数据
能否完全磁盘 IO 均衡, 比较困难, 但还可以降低, 因为这跟客户端生产 / 消费策略及消费历史数据有关, 有些不可控因素.
2020-03-11 日 kafka jvm heap 优化 通过 Kafka 集群业务监控发现利用率低
减少 jvm heap 大小, 让渡给 pagecache 做系统级数据缓存
另外 Apache Kafka PMC 大神王国璋回复: Kafka 对内存要求不大, 但是如果客户端版本较低会需要 down convert version, 这个过程是非常消耗 CPU 和内存的. 原因是 Producer 向 Kafka 写入数据时, 占用的堆外内存 NIO Buffer, 当消费读数据时, Kafka 并不维护内存数据, 因为使用系统函数 sendfile 将数据直接从磁盘文件复制到网卡设备中, 而不需要经由应用程序之手. 采集监控数据如下:
NIO Buffer
non-heap memory
早期 jvm heap 配置为 32GB, 后来优化为 16GB, 现在降到 10GB, 既保证了 kafka 进程稳定, 又不浪费内存
优化能否一次性解决到位
性能优化能否预先或提前一次性全部搞定?
一般性 topics 的 partitions 扩容可以提前做, jvm heap 也可以提前修改, 但是有些参数就没法确定了, 因为集群流量不大, 负载不高, 没有性能瓶颈, 找不到更看不出瓶颈在哪里, 优化了也看不出效果. 以内核参数优化为例
CentOS Performance Tuning
另外 IO 均衡化也是, 集群流量压力不大, 找不到需要 IO 均衡化的目标 topics. 只有流量逐步放大, 才容易发现并识别问题 topics
所以优化需要分类, 分批, 分场景, 根据瓶颈, 风险, 效果, 难易程度逐步推进.
从预先优化到全面优化
在线特征 dump 上线持续放量直至 100% 过程, 我们做了大量调整和优化, 它是一个循序渐进和不断完善的过程, 不可能一蹴而就, 回顾优化列表如下:
提前预先优化, 预估大流量 topics, 扩容 partitions 覆盖更多磁盘挂载点
依赖服务 zookeeper 优化: 单条事务消息刷盘改为批量刷盘
容器级优化: jvm heap 利用率优化, 从 16GB 降低大 10GB, 多余物理内存腾出给 pagecache 使用
Kafka 服务应用级优化
调大 replica.fetch.wait.max.ms, 降低 replica fetch Request 无效请求数, 释放 CPU 计算和内存资源
增大 replica.fetch.max.bytes, 特别是 kafka 重启降低目标 broker 读 IOPS
调大为 zookeeper.session.timeout = 20000ms, 避免网络抖动异常导致 broker 掉线
业务客户端优化
jstorm
生产端: 增大 batch 大小, 降低 Producer Request 次数, 给磁盘 write IO 降压
消费端: 增大各个 fetch 参数, 降低生产 / 消费速率, 给磁盘 read IO 降压
flink: 增大并行度, 结合异步和 jvm 参数
持续 IO 均衡化
扩容 partitions,topics 数据量大, partitions 数量少, 与业务沟通, 扩 partitions 分配到低 IO 挂载点上
迁移 partitions,partitions 目录迁移和节点迁移, 找出热点挂载点, 分析出高读写的 partitions, 迁移到使用率低的磁盘挂载点上
调整 topic 保留时间, 保证业务磁盘容量够用不浪费, 与业务沟通, 设置 topics 最小保留时间
CentOS 内核参数优化, 目标是提升性能, 保证稳定, 同时充分利用 pagecache 和 OS 读写磁盘特性, 用各种策略榨干取尽其资源
设置 / sys/block/sdb/queue/read_ahead_kb
设置 / sys/block/sdc/queue/nr_requests
... 省略, 了解更多请看 CentOS 系统参数优化
partition 迁移重点分析
要做到全面性, 多维度, 立体化的综合性能优化并达到预期理想效果, 需要对相关 Kafka,jvm,netty 技术原理及 OS 等等 (不限于) 有相当理解. 例如持续 IO 均衡化, 就是需要运用综合手段来解决, 利用管理平台, 各类监控数据和 shell 命令找出触发瓶颈的 topics 及对应 partitions, 然后用工具迁移实现 IO 再平衡.
以上操作是反复循环进行的动作, 观察 -》分析 -》操作 -》查看效果 -》再观察... 反复进行直至达到最佳状态
以下为 partitions 目录迁移 bugs, 经过分析, 重启后解决, 错误原因是 broker 应用内存中保留了 partition 目录迁移状态信息, 重启后还原, 但继续执行迁移需要重新操作
小结
预先优化, 保证初期放量稳定, 性能不打折
持续优化, 采取多种手段拍平 IO 毛刺, 同时兼顾磁盘容量均衡
想要达到最佳效果, 需要对 CentOS 底层 TCP 传输, 网络处理, pagecache 使用, IO 调度, 磁盘读写调度及刷盘机制有综合性全面的理解; 要对 Kafka 的底层原理, 各种配置参数项等具有深刻理解, 可以进行 Kafka 集群参数调优, 快速处理突发故障, 恢复集群抖动和动态进行集群扩缩容等
博客引用地址: https://www.cnblogs.com/lizherui/p/12632988.html
posted on 2020-04-06 20:53 李志涛 阅读(...) 评论(...) 编辑 收藏
来源: https://www.cnblogs.com/lizherui/p/12632988.html