kafka是一个消息队列服务器,服务称为broker, 消息发送者称为producer, 消息接收者称为consumer;通常我们部署多个broker以提供高可用性的消息服务集群.


典型的是3个broker;消息以topic的形式发送到broker,消费者订阅topic,实现按需取用的消费模式;创建topic需要指定replication-factor(复制数目,通常=broker数目);


每个topic可能有多个分区(partition), 每个分区的消息内容不会重复:


Broker


Kafka集群包含一个或多个服务器,这种服务器被称为broker

 

Topic
每条发布到Kafka集群的消息都有一个类别,这个类别被称为topic。(物理上不同topic的消息分开存储,逻辑上一个topic的消息虽然保存于一个或多个broker上但用户只需指定消息的topic即可生产或消费数据而不必关心数据存于何处)

Partition
parition是物理上的概念,每个topic包含一个或多个partition,创建topic时可指定parition数量。每个partition对应于一个文件夹,该文件夹下存储该partition的数据和索引文件

Producer
负责发布消息到Kafka broker

Consumer
消费消息。每个consumer属于一个特定的consuer group(可为每个consumer指定group name,若不指定group name则属于默认的group)。使用consumer high level API时,同一topic的一条消息只能被同一个consumer group内的一个consumer消费,但多个consumer group可同时消费这一消息。

Producer在发布消息到某个Partition时,先通过Zookeeper找到该Partition的Leader,然后无论该Topic的Replication Factor为多少(也即该Partition有多少个Replica),Producer只将该消息发送到该Partition的Leader。Leader会将该消息写入其本地Log。每个Follower都从Leader pull数据。这种方式上,Follower存储的数据顺序与Leader保持一致。Follower在收到该消息并写入其Log后,向Leader发送ACK。一旦Leader收到了ISR中的所有Replica的ACK,该消息就被认为已经commit了,Leader将增加HW并且向Producer发送ACK。
为了提高性能,每个Follower在接收到数据后就立马向Leader发送ACK,而非等到数据写入Log中。因此,对于已经commit的消息,Kafka只能保证它被存于多个Replica的内存中,而不能保证它们被持久化到磁盘中,也就不能完全保证异常发生后该条消息一定能被Consumer消费。但考虑到这种场景非常少见,可以认为这种方式在性能和数据持久化上做了一个比较好的平衡。在将来的版本中,Kafka会考虑提供更高的持久性。
Consumer读消息也是从Leader读取,只有被commit过的消息(offset低于HW的消息)才会暴露给Consumer。

Leader会跟踪与其保持同步的Replica列表,该列表称为ISR(即in-sync Replica)

1. 安装前需要把zookeeper 安装好.参考另一个blog

2. 下载

http://kafka.apache.org/downloads

Binary downloads:

2.00 是版本,2.11,2.12 是编译scale 版本,我下载了 2.11的

3. 解压

tar zvfx  kafka_2.12-2.0.0.tgz

4. 配置 config/server.properties 文件

#保证broker.id唯一性 本机为0 其它两台为1 2
broker.id=0
 broker.id.generation.enable=falselisteners=PLAINTEXT://10.10.3.11:9092
 #listeners=PLAINTEXT://10.10.3.12:9092
 #listeners=PLAINTEXT://10.10.3.13:9092
 port=9092#绑定本机IP地址 也可以不用设置
 #host.name=172.16.18.233num.network.threads=3
 num.io.threads=8
 socket.send.buffer.bytes=1048576
 socket.receive.buffer.bytes=1048576
 socket.request.max.bytes=104857600log.dirs=/data/kafka
 num.partitions=2
 num.recovery.threads.per.data.dir=1log.flush.interval.messages=10000
 log.flush.interval.ms=1000
 log.retention.hours=960
 log.retention.bytes=1073741824
 log.segment.bytes=1073741824
 log.retention.check.interval.ms=300000
 log.cleanup.policy=delete
 log.cleaner.enable=true#多台机器逗号分开
zookeeper.connect=10.10.3.11:2181,10.10.3.12:2181,10.10.3.13:2181
 zookeeper.connection.timeout.ms=60000
 zookeeper.session.timeout.ms=6000
 zookeeper.sync.time.ms=3000#是否允许自动创建topic 允许为true,不允许为false,就需要通过命令创建topic
 auto.create.topics.enable=false
 delete.topic.enable=true

 3台机器 配置一致就可以,除了broker.id,listen

单机版 也需要listen,注意一定是ip,不要写localhost

5. 后台启动

bin/kafka-server-start.sh -daemon  config/server.properties

或者

nohup kafka-server-start.sh -daemon  config/server.properties &

 

6.停止应执行脚本(传递ctrl+c的信号),这样加载避免检测错误,加载快

sh bin/kafka-server-stop.sh

7. 配置hosts

10.10.3.11 bj-6-dqy-msg-queue01
 10.10.3.12 bj-6-dqy-msg-queue02
 10.10.3.13 bj-6-dqy-msg-queue03

问题1 :

kafka Exception thrown when sending a message with key='null'
org.springframework.kafka.support.LoggingProducerListener [76] - Exception thrown when sending a message with key=’null’ and payload=’2017-11-14 15:36:53|iZbp1115ogry6vyp418vplZ|192.168.3.1|{“token”:”708037c594e04850bfd48f82fa862dd…’ to topic


解决:

/etc/hosts中加主机名和ip 映射