1、概念
Kafka 是基于 zookeeper 协调的分布式日志系统(也可以当做MQ系统),常见可以用于 web/nginx 日志、访问日志,消息服务等等,主要的应用场景就是日志收集系统和消息系统
- borker:对应一个 kafka 实例
- topic:某一类消息的集合
- partition:一个 topic 可以设置为多个 partition,每个 partition 对应一个机器上的物理位置,即文件夹
- segment:每个 partition 中的日志可以分为多个小文件,多个小文件拼接成一个完整的 partition。各 segment 都是有序的。一个 segment 可分为两个文件,一个是index、一个是log文件
- 副本:partition 的数据备份,一个 partition 可以有多个数据备份
- LSR:副本同步队列,比如一个partition有两个副本,那就形成一个 leader+2个 follow 这样的 LSR,leader负责这个 partition 的读写操作,follow 负责同步 leader 的数据
- LEO:partition 的每个副本的最后一条消息的偏移位置
- HW:最高水位,partition 中的副本中LEO最小的作为整个partition的HW,也是consumer能看到的位置
- repilca.lag.time.max.ms:当 follower 滞后 leader 数据的时长大于这个值,就会被删除出 LSR,放入 OSP 中,但还是有机会重新进入 LSR 的
- 发送模式:
- 同步:producer.type=sync
- 异步:producer.type=async
- AR:Assigned Replicas,所有的副本(replicas)统称,LSR 是其子集
- OSR:因与 leader 进度落差大,并打到了配置的阀值,而被从 LSR 删除出来的副本队列
2、高可靠性配置
一个 partition 可以配置1个以上的数据冗余备份数,通过 offsets.topic.replication.factor 就可以设置一个 partition 对应的副本数
request_required_acks:0、1、-1(all)
min_insync.repilcas:定义在 broker 回复生产者前,需要至少有多少个副本同步了 leader 的数据
要保证数据写入 Kafka 是安全的、高可靠的,需要如下配置:
- topic 的配置:
- replication.factor >= 3,即副本数量至少是3个
- 2 <= min.insync.replicas <= replication.factor
- broker 的配置:leader 的选举条件unclean.leader.election.enable=false
producer 的配置:request.required.acks = -1(all),producer.type=sync
3、监控
3.1 整体监控
leader 选举频率
-
3.2 Kafka Broker 监控
broker 是否存活
- broker 是否提供服务
- 数据流入/流出速度
-
3.3 Kafak Controller
3.4 Kafka Producer 监控
producer 队列中排队请求数
- 请求响应时间
-
3.5 Kafka Consumer监控
consumer 队列中排队请求数
- 请求响应时间
-
3.6 Topic监控
数据量大小
- offset
数据流入、流入速度、流出速度(message / byte)
4、重试机制
Kafka Producer 重试参数 retries 设置取舍
retries = integer.MAX_VALUE
- max.in.flight.requests.per.connection = 1,如果没设置后面这行,则意味着放弃消息的顺序性
5、性能压测结果
客户端的 acks 策略对发送的 TPS 有较大的影响,TPS:ackso > acks_1 > acks-1
- 副本数越高,TPS越低,副本数一直时min.insync.replicas不影响TPS;
- acks=0/1 时,TPS与min.insync.replicas参数以及副本数无关,仅受acks策略的影响
min.insync.replicas不影响TPS
partition 的不同会影响 TPS,随着 partition 的个数增长 TPS 会有所增长,但并不是一直成正比关系,到达一定临界值时,partition 数量的增加反而会使TPS略微降低
6、影响性能的因素
- request.required.acks = -1(all) | 0 | 1,producer.type = sync/asyn
- min.insync.replicas
- offset.topic.replication.factor,每个 partition 数量的大小
- 消息体大小
7、风险
7.1 消息乱序
只保证 partition 内是有序的,跨 partition 是不保证有序的,partition 数量= 同一个消费者组中消费者数量时,可能需要顺序的数据分布到了不同的 partition,导致处理时乱序。解决:
- 可以设置 topic 有且只有一个 partition
- 根据业务需要,需要顺序的指定为同一个 partition
- 根据业务需要,比如同一个订单,使用同一个key,可以保证分配到同一个partition上
即使一个 topic 只有一个 partition,但当顺序的消息进入了同一个消费者组之后,用了多线程来处理消息,会导致消息的乱序。解决:消费者内部根据线程数量创建等量的内存队列,对于需要顺序的一系列业务数据,根据 key或者业务数据,放到同一个内存队列中,然后线程从对应的内存队列中取出并操作
7.2 消息重复
实现的是 At least once 的传输保证方式,但会有消息重复的风险,依赖于业务方自身去做消息去重
