kafka也有生产者和消费者的概念,生产者把消息发给kafka,消费者从kafka拿消息进行消费,这个跟之前的activemq和rabbitmq类似。
我们从生产者发消息开始,探讨kafka的整个流程。这里的版本是0.10.1.0
。
消息对象
消息对象 ProducerRecord包含了topic、partition、key、value、timestamp,其中topic和value在构建ProducerRecord时是必须的。
topic代表了一个集合的名称,当消息发往kafka的时候,kafka需要把这个消息存放起来的,此时就需要一个集合的名称,把同一个集合的消息,存放在一起,这个就类比于mysql的表,同一个表的数据,都是存放在一个表中。
value是消息的主体,比如我们往名称为topic1的topic发送一个hello的消息时,这个value就等于hello。
partition代表着分区号,kafka是分布式系统的,也就是说,一个topic的数据,会存放在多个服务器中,所以就有很多分区,设置partition可以指定消息发完哪个分区。
key作为消息的键,可以根据key对这个消息进行分区。
timestamp指消息的时间戳,既可以表示消息的时间戳,也可以表示消息追加到日志文件的时间。
我们假定一个消息体为hello的消息发送给topic1。
KafkaProducer
消息构建好后,我们就需要把消息发出去,不然构建干嘛,对吧。
负责发消息的是KafkaProducer,每个KafkaProducer都有一个clientId,如果没有设置,就会默认为producer-
+数字,这个数字是AtomicInteger
类型的,所以是线程安全的,没有设置的话,clientId就是producer-1
、producer-2
。由于KafkaProducer也是线程安全的,所以客户端构建一个KafkaProducer用来发送消息,也是可以的。
发送消息的时候,我们是需要知道服务器(即broker)地址的,所以实例化KafkaProducer的时候,bootstrap.servers
也是需要赋值的,如果有多个的话,用逗号隔开,格式为host1:port1,host2:port2
,这里我们假设服务器地址为hadoop1:9092
。
拦截器
拦截器并不是必须的,比如对消息做一些定制化的操作,对topic和value修改等或者定制回调函数,不过正常情况,一般是不用的。
序列化
在网络传输中,broker是以以字节数组(byte[])的形式进行接收的,所以在发送的时候,需要预先把消息的key和value进行序列化。
在初始化KafkaProducer的时候,设置key.serializer
和value.serialize
来制定key和value的序列化器。
分区器
Kafka是一个分布式系统,每个topic都对应着多个broker,所以我们在发送消息之前,需要对消息分配他所在的分区。
消息累加器
Kafka并不是一条一条的消息进行发送,而且保存在消息累加器这个缓存中,然后再批次发送,这样可以减少网络传输的资源消耗,进而提升性能。
Sender线程
消息保存在内存后,Sender线程就会把符合条件的消息按照批次进行发送。除了发送消息,元数据的加载也是通过Sender线程来处理的。
Sneder线程发送消息以及接收消息,都是基于java NIO的Selector。通过Selector把消息发出去,并通过Selector接收消息。
后面我们慢慢对本章的内容进行展开。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。