可视化管理工具
线上环境规划
- 评估日均消息数据量
- 按照80%数据集中在20%的时间计算QPS ?万/s
- 合理设置副本数
- 按数据默认保留7天计算磁盘容量
- 规划机器,最好为物理机,虚拟机抗大并发效果不佳
- 最后得出机器cpu,内存磁盘及其数量
- 还有考虑峰值流量,选千兆网卡或万兆网卡
- 磁盘一般考虑选机械盘即可,思考为何?
JVM参数设置
- 大内存的情况一般都要用G1垃圾收集器
- 年轻代内存比较大,用G1可以设置GC最大停顿时间
- 不至于一次minor gc就花费太长时间
- 像kafka,rocketmq,es这些中间件,写数据到磁盘会用到操作系统的page cache
- 所以JVM内存不宜分配过大,还需要考虑给操作系统的缓存留出几个G
线上问题及优化
消息丢失
- 发送端:可设置acks=?,若配置为-1或all,可最大可能性保证消息能送达broker集群,但吞吐量太低
- 消费端:消费一条,手动提交一条最靠谱
消息重复消费
- 开启重试机制即可能发生
- 最靠谱做法就是消费端都是要做消费幂等处理
消息乱序
- 将所有有序消息发送到同一个分区,然后用一个消费者去消费
- 性能极低,基本不用考虑
- 可思考通过什么思路能实现吗?CountDownLatch
消息积压
- 与Rocketmq类似,搞一个消费者将消息搬迁到更多分区的新topic中
- 然后再启动多个消费者同时消费新主题的不同分区
- 重复消费不成功的消息也可能会积压
- 考虑自己实现类似死信队列来解决
延迟消息
- kafka默认不提供
- 如果让你实现,思路是什么?
- 思路类似Rocketmq,搞一批Topic,按时间分类
- 然后通过定时器,轮询消费这些Topic
- 对消息的发送时间做判断
- 发现一条不在时间间隙内,则立即结束本次轮询
- 并提交的offset需要-1,思考?
分区数越多吞吐量越高吗?
- 通过
bin/kafka-producer-perf-test.sh
压测 - 分区数到达某个值吞吐量反而开始下降
- 事实上任何东西都有一个临界值
- 一般情况分区数跟集群机器数量相当就差不多了
“Too many open flies”,这是一种常见的 Linux 系统错误
一般发生在创建线程、创建 Socket、打开文件这些场景下
Linux系统的默认设置下,这个文件描述符的个数不是很多 ,通过 ulimit -n 命令可以查看:一般默认是1024,可以将该值增大,比如:ulimit -n 65535
kafka生产者的幂等性
- kafka的幂等性可以保证重复发送的消息只接收一次
- 只需在生产者加上参数 props.put(“enable.idempotence”, true) 即可
- 默认是false不开启
原理是:kafka每次发送消息会生成PID和Sequence Number,并将这两个属性一起发送给broker,broker会将PID和Sequence Number跟消息绑定一起存起来,下次如果生产者重发相同消息,broker会检查PID和Sequence Number,如果相同不会再接收
- 总而言之,鸡肋,还是在消费者端通过幂等性来保障是最为靠谱
kafka的事务
- 保障本地事务(比如数据库)与mq消息发送的事务一致性
- 一次发送多条消息的事务一致性(要么同时成功要么同时失败)
- 作为了解有这种机制即可
kafka高性能的原因
- 磁盘顺序读写
- 数据传输的零拷贝
- 读写数据的批量batch处理以及压缩传输
kafka消息不能修改以及不会从文件中间删除保证了磁盘顺序读,kafka的消息写入文件都是追加在文件末尾,不会写入文件中的某个位置(随机写)保证了磁盘顺序写
- 附数据零拷贝原理图: