可视化管理工具

线上环境规划

  • 评估日均消息数据量
  • 按照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高性能的原因

  1. 磁盘顺序读写
  2. 数据传输的零拷贝
  3. 读写数据的批量batch处理以及压缩传输
kafka消息不能修改以及不会从文件中间删除保证了磁盘顺序读,kafka的消息写入文件都是追加在文件末尾,不会写入文件中的某个位置(随机写)保证了磁盘顺序写
  1. 附数据零拷贝原理图:

kafka生产环境实践经验总结-LMLPHP

03-23 14:08