最近研究的东西需要用到消息队列来缓冲数据,所以对linkedin开源的的kafka进行了简单的配置测试,记录如下:
关于kafka的原理介绍、配置文档、命令等,可以参考apache的官方文档:http://kafka.apache.org/documentation.html#gettingStarted
上图就是kafka的基本工作原理:
1、producer负责向broker的topic上发送消息,发送时指定topic名字
2、kafka cluster server(即broker集群)负责维护各个topic,接受消息和接受订阅,其中集群中的每个server上运行一个broker,broker维护多个topic,每个topic包含多个partition,每个partition对应一个逻辑log,由多个segment组成,而每个partition在内存中对应一个index,记录每个segment中第一条消息偏移量。
3、consumer负责连接指定的topic 接受消息
kafka的负载均衡和HA由zookeeper完成,所以如果使用集群状态的kafka,首先需要正确配置zookeeper。
本次安装集群服务器为3个,hostname为server1 sever2 server3,已正确安装zookeeper在此3个服务器上。安装配置过程如下:
0、在官网下载0.8.1版本(截止目前最新),可根据自己使用的scala版本选择在对应版本上编译过的kafka,本例中选择kafka_2.10-0.8.1.tgz
$ tar -zxvf kafka_2.10-0.8.1.tgz -C /app
$ mv kafka_2.10-0.8.1 kafka
mv的原因是为了在版本升级时减少工作量,解压后配置用户的环境变量
export KAFKA_HOME=/app/kafka
export PATH=$PATH:$KAFKA_HOME/bin
1、修改配置文件:
$ cd $KAFKA_HOME/config
$ vi server.properties
主要更改以下参数:
# 每个broker所在的server的id配置为不同的值,本次安装中server1上配置为1,server2上配置为2,以此类推
broker.id=1
# 同上,每个broker上的端口配置为不同,server1配置为9092,server2配置为9091,server上配置为9090
port=9092
# 存放kafka的log的路径,需要提前建好并赋予正确的读写权限,本次使用/data/kafkalog为日志存放路径
log.dirs=/data/kafkalog
#之前已经正确安装的zookeeper的hostname:port列表
zookeeper.connect=server3:2181,server2:2181,server1:2181
$ vi producer.properties
主要更改以下参数:
#broker的meta数据存放列表
metadata.broker.list=gtx3:9092,gtx2:9091,gtx1:9090
# 配置消息是同步发送
producer.type=sync
# 配置消息编码格式
serializer.class=kafka.serializer.DefaultEncoder
#配置为1表示当一个broker上的produce request完成时,至少有一个另外的broker上也将这个消息固化到log并通知leader
request.required.acks=1
$ vi consumer.properties
主要更改以下参数:
#zookeeper的集群
zookeeper.connect=server3:2181,server2:2181:server1:2181
#group可配置一个,如果有不同的应用,也可配置多个
group.id=gtxgroup1
2、在每个server上修改上述配置文件后,在每个server上执行如下命令启动集群:
$ kafka-server-start.sh /app/kafka/server.properties
3、在其中一台server上运行如下命令可创建一个topic命名为servertest-topic1,其中zookeeper的地址可指定server1-server3中的任意一个
$ bin/kafka-topics.sh --create --zookeeper server2:2181 --replication-factor 3 --partitions 1 --topic servertest-topic1
4、在任意一台server上运行如下命令可查看刚才创建的topic,其中zookeeper的地址可指定server1-server3中的任意一个,也可以指定所有的 zk地址和端口
$ kafka-topics.sh --describe --zookeeper server2:2181 --topic servertest-topic1
Topic:servertest-topic01 PartitionCount:1 ReplicationFactor:3 Configs:
Topic: servertest-topic01 Partition: 0 Leader: 3 Replicas: 3,1,2 Isr: 3,2,1
输出结果说明:
第一排:topic名字,partition总个数,冗余份数
第二排:topic名字,partition编号(此处的0表示的是第0个partition),leader所在的节点编号(此处leader是server3,kafka自主随机选择),冗余备份存在的节点列表(server1-server3上都有备份),已经同步的节点列表(isr: is sync already)。
5、测试在server1上发布消息到指定的topic servertesttopic1上,在server3上接受消息到指定的topic上
在server1上执行如下命令:
$ kafka-console-producer.sh --broker-list server1:9092 --topic servertest-topic01
命令指定server1上的broker地址和端口
在server3上执行如下命令:
$ kafka-console-consumer.sh --zookeeper server1:2181 --from-beginning --topic servertest-topic01
其中zk的地址可以在集群中随意选择一个任意指定,也可以指定所有的zk地址和端口,e.g.
$ kafka-console-consumer.sh --zookeeper server1:2181,server2:2181,server3:2181 --from-beginning --topic servertest-topic01
这时在server1上刚才启动命令的console中输入字符,在server3上就会同步显示出来,简单测试环境的配置到此结束,kafka提供了java-client的代码,可以通过client发送信息到kafka集群上,同时kafka也支持其他多种语言。
kafka依赖于zk实现了高可用,杀掉任意一个集群中的server,消息不会丢失,服务也仍然可用。