kafka每秒千万级优化思路

问题点描述:

  1. 秒级发送数据量在78万左右
  2. 消费端时不时赶不上发送端性能,导致整个kafka链路抖动

 

Broker下topic数据存储不均衡

先来看下为什么会出现存储不均衡的原因

流程图:

源码如下:

private def nextLogDirs(): List[File] = {
    if(_liveLogDirs.size == 1) {
        // 如果可用log目只有1个,返回这个目录
        List(_liveLogDirs.peek())
    } else {
        // count the number of logs in each parent directory (including 0 for empty directories
        // 统计所有目录以及目录中的log数量
        val logCounts = allLogs.groupBy(_.parentDir).map { case (parent, logs) => parent -> logs.size }
        val zeros = _liveLogDirs.asScala.map(dir => (dir.getPath, 0)).toMap
        val dirCounts = (zeros ++ logCounts).toBuffer

        // choose the directory with the least logs in it
        // 按照各个目录的log size从小到大排序,创建File后返回
        dirCounts.sortBy(_._2).map {
            case (path: String, _: Int) => new File(path)
        }.toList
    }
}

新的Topic数据大概率会存储在日志数量最少的borker磁盘上,如果这部分topic数据量比较大,那么就会导致存储不均衡,这个borker磁盘会率先报警,部分borker磁盘到达存储阈值后会对kafka带了很大的性能影响

消息中间件都是IO密集型的应用,当磁盘ioutil过高时就会严重影响MQ的性能了

解决方案:

  • 迁移broker下的topic数据
  • 减少log保存时间
  • 清理无用topic

官方天然支持了数据迁移的命令,迁移完成后会自动均衡,但是也存在缺点,就是大数据量的迁移速度很慢并且是串行迁移

-- 查看topic数据在哪些broker上面
bin/kafka-topics.sh --zookeeper xxx.xxx.xxx.xxx:2181 --describe --topic topic_name
-- 确定需要迁移的topic信息,保存json文件
{
    "topics": [
        {"topic": "topicA"},
        {"topic": "topicB"}
    ],
    "version":1
}
-- 然后使用如下命令,Kafka会自动生成各个partition需要转移到的目标broker,partition的均衡性自动保证
bin/kafka-reassign-partitions.sh --zookeeper zk:2181 --topics-to-move-json-file topics-to-move.json --broker-list "3,4,5" --generate 

执行完上面这个命令后会得到如下输出

Current partition replica assignment
{"version":1,"partitions":[{"topic":"topicA","partition":2,"replicas":[0,2]},
{"topic":"topicA","partition":1,"replicas":[1,0]},
{"topic":"topicB","partition":1,"replicas":[0,1]},
{"topic":"topicA","partition":0,"replicas":[2,1]},
{"topic":"topicB","partition":0,"replicas":[2,0]},
{"topic":"topicB","partition":2,"replicas":[1,2]}]}

Proposed partition reassignment configuration

{"version":1,"partitions":[{"topic":"topicA","partition":2,"replicas":[3,4]},
{"topic":"topicA","partition":1,"replicas":[5,3]},
{"topic":"topicB","partition":1,"replicas":[3,4]},
{"topic":"topicA","partition":0,"replicas":[4,5]},
{"topic":"topicB","partition":0,"replicas":[5,3]},
{"topic":"topicB","partition":2,"replicas":[4,5]}]}

Proposed partition reassignment configuration的内容存储到temp.json中,然后继续执行

bin/kafka-reassign-partitions.sh --zookeeper zk:2181 --reassignment-json-file move-to-brokers.json --execute

可以通过如下命令查看迁移状态

bin/kafka-reassign-partitions.sh --zookeeper zk:2181 --reassignment-json-file move-to-brokers.json --verify

上面已经提到过,官方提供的迁移命令存在一些不足点:

  • 迁移只能串行提交,第一个未迁移完成后续都无法提交迁移
  • 迁移持续到高峰期,那么读写性能受损严重
  • 迁移和实时拉取共用线程问题,会影响实时拉取效率

如果需要规避以上这些问题,那么会有比较复杂的迁移解决方案(流水线加速+迁移动态取消/动态续迁),这里不在展开说了

Consumer 消费过慢陷阱

下面是Kafka的NIO关键节点的流程

 问题描述:

  • 在老版本中consumer和broker的心跳检测线程和消费处理线程是同一个,所以当消费过慢的时候,会导致心跳无法执行,然后broker认为这个consumer离线会触发rebalance,这个在老版本是比较致命的
  • 由于Kafka内部是事件驱动模型,所以当consumer消费过慢会出现kafka内部监控误判问题,kafka-apis 这个步骤会去所有TP(Topic-Partition)调用让他们准备数据,当各个TP数据准备完成后,handler会先将最快准备好的数据拉取到ResponseQueue中, 这个时候如果消费速度太慢,会导致apis-handler不在拉取新的TP数据到RQ中,这样会导致RQ数据准备过程的总耗时很长,但是其实TP数据早就准备完成了,这个时候就会误报Kafka内部监控预警,这个对排查问题绝对是个错误的引导(大坑),如下图:

PageCache 问题

首先了解下pc在kafka内部的使用逻辑

 如果秒级产生150MB的数据,如果Consumer消费的速度不够快,那么8G的PageCache可能不到半小时就没了,那么就会带来新的问题了,consumer消费的数据由于在PC上面找不到,就会不停的去硬盘查找数据,那么内存度和交换度的性能是数量级的差别,

解决方案:

  • 提升消费端的速度,当然很多场景下我们很难做到,因为基本都是发送端和消费端是2波人,属于不同部门,这个时候很难推动下游去改动
  • 重新整合PageCache,由于PC受限于物理内存大小以及内存的动态规划控制,目前Raid 卡有一种命令可以开启高速缓存,有些Raid卡加速后可以达到15GB/S的速度,具体原理我也没仔细研究过,不过我们可以通过这种技术将多个Raid卡集成成一个更大的缓存,然后一次性写入硬盘

上面的流程其实还会有一个严重的问题,那么就是PageCache 污染问题

这会造成冷数据被 回刷到了宝贵的PageCache中...并且这个无法通过配置去避免CPU的这个操作,那么我们的解决方案就比较复杂了,如果非必要个人觉得不要去考虑或者解决这个问题

业内常用的解决方案是对应用层做入侵改造,利用数据冷热特性进行时间线存储以及消费端带上流量标来判断消费数据的时间线

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菠萝-琪琪

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值