Kafka and So on.

Kafka消息顺序消费

Kafka分区的目的
• 分区对于 Kafka 集群的好处是:实现负载均衡
• 分区对于消费者来说:可以提高并发度,提高效率

Kafka如何做到全局消息有序:
  一个topic、一个分区,虽然保证全局有序,但是生产性能下降,与Kafka分区原意相违。Kafka是无法保证全局的消息顺序性的,只能保证主题的某个分区的消息顺序性。Kafka中的每个 partition 中的消息在写入时都是有序的,而且单独一个 partition 只能由一个消费者去消费,可以在里面保证消息的顺序性。但是分区之间的消息是不保证有序的 。

• Kafka如何保证数据的顺序消费:
  Kafka的顺序消息仅仅是通过partitionKey,将某类消息写入同一个partition,一个partition只能对应一个消费线程,以保证数据有序,除了发送消息需要指定partitionKey外,producer和consumer实例化无区别

• 多线程进行消息消费如何保证顺序?
Kafka and So on.
解决办法
  为了保证一个消费者中多个线程去处理时,不会使得消息的顺序被打乱,则可以在消费者中,消息分发至不同的线程时,加一个队列,消费者去做hash分发,将需要放在一起的数据,分发至同一个队列中,最后多个线程从队列中取数据,如下图所示。
Kafka and So on.

Kafka原理pull与push

Kafka选择由producer向broker push消息并由consumer从broker pull消息。
push
优点:生产者主动推送给消费者,及时性很高
缺点:push模式很难适应消费速率不同的消费者,因为消息发送速率是由broker决定的。push模式的目标是尽可能以最快速度传递消息,但是这样很容易造成consumer来不及处理消息,典型的表现就是拒绝服务以及网络拥塞。如果push的速度太慢,容易造成消费者性能浪费。

pull
优点:可以根据consumer的消费能力以适当的速率消费消息。
缺点:拉取消息的间隔不太好设置。间隔太短,对服务器请求压力过大。间隔时间过长,那么必然会造成一部分数据的延迟。实时性相对较低。

Kafka丢失数据的情况

• producer配置acks=0 、1
• kafka的数据一开始就是存储在PageCache上的,定期flush到磁盘上的,也就是说,不是每个消息都被存储在磁盘了,如果出现断电或者机器故障等,PageCache上的数据就丢失了
• 网络负载很高或者磁盘很忙写入失败的情况下(无重发重试)
• 消费者崩溃,还没有处理的数据就被commit offset了

Kafka数据积压、数据倾斜

Kafka如果生产端并发量很高,broker不能承受,怎么解决这个问题?
(1)数据积压如果是Kafka消费能力不足,则可以考虑增加 topic 的 partition 的个数,同时提升消费者组的消费者数量,消费数 = 分区数 (二者缺一不可)
(2)若是下游数据处理不及时,则提高每批次拉取的数量。批次拉取数量过少(拉取数据/处理时间 < 生产速度),使处理的数据小于生产的数据,也会造成数据积压

数据倾斜
可以考虑增加 topic 的 partition 的个数

Kafka和其他的MQ相比的优势

与其他MQ相比较,Kafka有一些优缺点,主要如下:
优点
1、可扩展:Kafka集群可以透明的扩展,增加新的服务器进集群。
2、高性能:Kafka性能远超过传统的ActiveMQ、RabbitMQ等,Kafka支持Batch操作
3、容错性:Kafka每个Partition数据会复制到几台服务器,当某个Broker失效时,Zookeeper将通知生产者和消费者从而使用其他的Broker。

缺点
1、重复消息:Kafka保证每条消息至少送达一次,虽然几率很小,但一条消息可能被送达多次
2、消息乱序:Kafka某一个固定的Partition内部的消息是保证有序的,如果一个Topic有多个Partition,partition之间的消息送达不保证有序
3、复杂性。Kafka需要Zookeeper的支持,Topic一般需要人工创建,部署和维护比一般MQ成本更高

RabbitMQ
  遵循AMQP实现,传统的messaging queue系统实现,基于Erlang语言开发,用在对数据一致性、稳定性和可靠性要求很高的场景,对性能和吞吐量还在其次。支持协议还包括XMPP、SMTP、STOMP,是一款重量级MQ,更适合于企业级的开发。实现Broker构架,消息在发送给客户端时先在中心队列排队。对路由、负载均衡及数据持久化都有良好的支持。

ZeroMQ
  只是一个网络编程的Pattern库,将常见的网络请求形式模式化、组件化。ZeroMQ能实现RabbitMQ不擅长的高级复杂队列,但开发人员需要自己组合多种技术框架,技术复杂度是一个挑战。仅提供非持久性的队列,如果Down机,数据将丢失。

Redis
  Key-Value的NoSQL数据库,本身也支持MQ功能,可以完全当做一个轻量级的队列使用。Redis在数据量大的时候入队较慢,Redis出队则无论数据量大小性能都不错。