本人英文水平非常有限,看不懂勿喷。
1.3快速入门
教程假定你是开始无经验的,没有kafka或者Zookeeper数据。由于kafka控制台脚本在unix和windows平台是不同的,在windows平台使用bin\windows代替bin/,修改扩展名为.bat。
步骤1:下载源码
下载0.10.2.0版本,然后解压。
> tar -xzf kafka_2.11-0.10.2.0.tgz > cd kafka_2.11-0.10.2.0
步骤2:运行server
kafka使用zookeeper,因此你需要首先启动zookpeer server加入他没有。你能方便的使用脚本包装kafka来得到快捷的单例zookeeper实例。
> bin/zookeeper-server-start.sh config/zookeeper.properties
[2013-04-22 15:01:37,495] INFO Reading configuration from: config/zookeeper.properties (org.apache.zookeeper.server.quorum.QuorumPeerConfig)
...
现在启动kafka server:
> bin/kafka-server-start.sh config/server.properties
[2013-04-22 15:01:47,028] INFO Verifying properties (kafka.utils.VerifiableProperties)
[2013-04-22 15:01:47,051] INFO Property socket.send.buffer.bytes is overridden to 1048576 (kafka.utils.VerifiableProperties)
...
步骤3:创建topic
让我们创建名称为test的topic,使用一个分区一个副本:
> bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 1 --partitions 1 --topic test
我们运行topic list命令可以看到topic:
> bin/kafka-topics.sh --list --zookeeper localhost:2181
test
或者,代替手动创建,你也可以配置brokers自动创建topic,当不存在要发布的topic时。
步骤4:发送消息
kafka从命令行客户端开始,把输入从文件或者标准输入发送到kafka集群。默认的,每一行发送一个单独的消息。
启动生产者然后输入一些消息到控制台,发送给server。
> bin/kafka-console-producer.sh --broker-list localhost:9092 --topic test
This is a message
This is another message
步骤5:启动一个消费者
kafka也有一个消费者命令行,能把消息输出到标准输出。
> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic test --from-beginning
This is a message
This is another message
假如你运行上面命令在不同终端,然后你输入不能消息在生产者,你能看见他们在消费者终端。
所有命令行工具有附加参数;运行命令无参数可以显示使用详细信息。
步骤6:以集群方式运行
目前为止我们运行都是单个代理,没有什么意思。kafka一个代理仅仅是集群中的一个,没有什么改变来运行多个代理。为了感受,我们扩展到三个节点(所有仍然在本地主机)。
首先我们做一个配置文件为每个brokers(windows平台使用copy命令代替)
> cp config/server.properties config/server-1.properties > cp config/server.properties config/server-2.properties现在编辑这些新文件,设置下面属性:
config/server-1.properties: broker.id=1 listeners=PLAINTEXT://:9093 log.dir=/tmp/kafka-logs-1 config/server-2.properties: broker.id=2 listeners=PLAINTEXT://:9094 log.dir=/tmp/kafka-logs-2broker.id属性是集群中 每个节点唯一的不变的名称。我们不得不重写端口和日志目录,因为我们在同一台机器运行所有,我们想
让brokers免于注册用相同端口或复写别人的数据。
我们已经有zookeeper和开始单个节点,我们仅仅需要启动两个新节点:
> bin/kafka-server-start.sh config/server-1.properties & ... > bin/kafka-server-start.sh config/server-2.properties & ...
现在创建一个topic有三个负直节点:
> bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic
现在我们有了集群,我们怎么知道代理做了什么,看运行
"describe topics"命令:
> bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic
Topic:my-replicated-topic PartitionCount:1 ReplicationFactor:3 Configs:
Topic: my-replicated-topic Partition: 0 Leader: 1 Replicas: 1,2,0 Isr: 1,2,0
这是输出的解释。第一行是总的概述,每个附加行说明了每一部分的信息。因为我们只有一个topic分区,这只有一行。
leader是节点负责人对于所有读写分区。每个节点成为一个负责人随机选择分区一部分。
replicas是节点列表,复制日志给分区不管他们是否是负责人或者是否他们当前可用。
isr是同步的副本,他是副本的子集,是当前活跃的抓取的负责人。
在我的例子中node1是责任人对对于每个topic分区。
我们可以运行同样的命令看原始创建的topic:
> bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test
Topic:test PartitionCount:1 ReplicationFactor:1 Configs:
Topic: test Partition: 0 Leader: 0 Replicas: 0 Isr: 0
不用惊讶原始topic没有replicas,仅仅server在我们集群当我们创建的时候。
让我们发布一些消息在新topic:
> bin/kafka-console-producer.sh --broker-list localhost:9092 --topic my-replicated-topic ... my test message 1 my test message 2 ^C现在我们消费这些消息:
> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic ... my test message 1 my test message 2 ^C现在我们验证容错性。broker 1作为责任人,我们kill它:
> ps aux | grep server-1.properties 7564 ttys002 0:15.91 /System/Library/Frameworks/JavaVM.framework/Versions/1.8/Home/bin/java... > kill -9 7564
在windows使用:
> wmic process get processid,caption,commandline | find "java.exe" | find "server-1.properties" java.exe java -Xmx1G -Xms1G -server -XX:+UseG1GC ... build\libs\kafka_2.10-0.10.2.0.jar" kafka.Kafka config\server-1.properties 644 > taskkill /pid 644 /f领导人已经转换为从节点,node1不再有同步复制配置:
> bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic my-replicated-topic
Topic:my-replicated-topic PartitionCount:1 ReplicationFactor:3 Configs:
Topic: my-replicated-topic Partition: 0 Leader: 2 Replicas: 1,2,0 Isr: 2,0
但是这些消息对于消费者仍然可用,即使责任人已经挂掉:
> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic ... my test message 1 my test message 2 ^C步骤7:使用kafka导入导出数据
从控制台写数据,作为快捷的开始,但是你可能想使用数据从其他来源或者从kafka导出数据到其他系统。对于很多系统,代替自定有集成代码,你能使用kafka连接器来导入导出数据。
kafka连接器是一个工具包含在kafka导入导出数据到kafka。它是一个扩展工具通过运行connectors,实现了和外部系统互动的自定义逻辑。在这个快速入门里怎么运行kafka connectors来从文件导入数据和导出数据到文件。
首先,我们一些测试的种子数据:
> echo -e "foo\nbar" > test.txt
接下来,我们启动两个标准模式的connectors,意味着他们运行在单个本地进程。我们提供三个配置文件作为参数。第一个通常是kafka connect进程的配置,包含像kafka brokers通用配置来连接和序列化数据。其余配置文件一个connectors创建一个。这些文件包含唯一connector名称,connector实例类,和其他connector要求的配置。
> bin/connect-standalone.sh config/connect-standalone.properties config/connect-file-source.properties config/connect-file-sink.properties
这些包含在kafka简单的配置文件使用默认本地集群配置,当你最初启动创建两个connectors:第一个是原始connector,按行读取文件,生辰kafka topic,第二个是渗透connector从kafka读取消息,生成行数据到输出文件。
在启动过程中你能看到一些日志信息,包含一些具体的connectors说明。一旦kafka connector进程启动,原始connector开始从test.txt按行读取数据,然后生成topic connect-test;渗透connector开始从topic connect-test读取消息,把他们写入test.sink.txt。我们验证数据通过检查输出文件内容:
> cat test.sink.txt
foo
bar
说明数据被存储在kafka topic connect-test中,因此我们也能运行控制台消费者来看这个topic(或者用户自定义消费者来处理它):
> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 --topic connect-test --from-beginning
{"schema":{"type":"string","optional":false},"payload":"foo"}
{"schema":{"type":"string","optional":false},"payload":"bar"}
...
connectors继续处理数据,因此我们可以添加数据看见他从通道移除:
> echo "Another line" >> test.txt
你应该能看见这行在消费者输出控制台和渗透文件中。
步骤8:使用kafka流处理数据
kafka流是一个kafka客户端lib,为了实时流处理和分析数据存贮在kafka brokers。这个入门指南实例将展示怎样使用lib运行流应用。这是WordCountDemo示例代码的主要部分(转换成java8更容易阅读):
// Serializers/deserializers (serde) for String and Long types final Serde<String> stringSerde = Serdes.String(); final Serde<Long> longSerde = Serdes.Long(); // Construct a `KStream` from the input topic ""streams-file-input", where message values // represent lines of text (for the sake of this example, we ignore whatever may be stored // in the message keys). KStream<String, String> textLines = builder.stream(stringSerde, stringSerde, "streams-file-input"); KTable<String, Long> wordCounts = textLines // Split each text line, by whitespace, into words. .flatMapValues(value -> Arrays.asList(value.toLowerCase().split("\\W+"))) // Group the text words as message keys .groupBy((key, value) -> value) // Count the occurrences of each word (message key). .count("Counts") // Store the running counts as a changelog stream to the output topic. wordCounts.to(stringSerde, longSerde, "streams-wordcount-output");
他实现了WordCount算法,来计算输入文本中单词出现的频率。然而,不像之前你见过的有边界其他WordCount实例,这个WordCount实例表现稍微有些不同,它设计区操作无限无边界的流数据。类似有边界的变种,他是有状态更新单词数目。然而,因为他必须假定无边界数据,他将周期的输出当前状态结果然后继续处理更多数据,因为他不知道输入数据的边界。
第一步,我们给kafka topic准备输入数据,随后会被kafka stream应用处理。
> echo -e "all streams lead to kafka\nhello kafka streams\njoin kafka summit" > file-input.txt
或者windows平台:
> echo all streams lead to kafka> file-input.txt > echo hello kafka streams>> file-input.txt > echo|set /p=join kafka summit>> file-input.txt接下来,我们发送输入数据给输入名称是 streams-file-input的topic,使用控制台生产者,他将读取从STDIN一行行读取数据,然后发布每一行作为单独消息用null key和value编码成string到topic(事实上,流数据将不断流入kafka当应用在一直运行中):
> bin/kafka-topics.sh --create \
--zookeeper localhost:2181 \
--replication-factor 1 \
--partitions 1 \
--topic streams-file-input
> bin/kafka-console-producer.sh --broker-list localhost:9092 --topic streams-file-input < file-input.txt
我们能运行WordCount实例应用来处理输入数据:
> bin/kafka-run-class.sh org.apache.kafka.streams.examples.wordcount.WordCountDemo
这个实例应用将从
streams-file-input topic读取数据,执行WordCount算法指令来处理每个读取到的消息,然后不断写当前结果到streams-wordcount-output输出topic。因此我们没有标准输出除了日志记录返回给kafka。这个实例将运行几秒钟,不像传统刘处理应用自动结束。
我们可以检验WordCount实例应用的输出从topic输出:
> bin/kafka-console-consumer.sh --bootstrap-server localhost:9092 \
--topic streams-wordcount-output \
--from-beginning \
--formatter kafka.tools.DefaultMessageFormatter \
--property print.key=true \
--property print.value=true \
--property key.deserializer=org.apache.kafka.common.serialization.StringDeserializer \
--property value.deserializer=org.apache.kafka.common.serialization.LongDeserializer
看下面打印在控制台的输出:
all 1 lead 1 to 1 hello 1 streams 2 join 1 kafka 3 summit 1第一列是kafka消息key用string格式,第二列是消息值用Long格式。说明输出实际上是连续的流更新,每一条数据记录是一个唯一单词的更新数,aka记录key像kafka。为了多个记录用相同key,后续记录会更新前面记录。
下面两个图标说明了这个场景。第一列显示了统计copunt当前KTable<String,Long>变化状态.第二列显示了变化记录和从KTable状态更新结果,将发送给输出kafka topic streams-wordcount-output。
第一个文本行“all streams lead to kafka”正在被处理。KTable被构建为每一个新单词结果在table entry实例(高亮绿色),一个类似改变记录发送给下游KStream。
当第二行“hello kafka streams”在处理,我们观察到,对于第一时间,存在的实体KTable被更新(对于单词“kafka”和“streams"),然后改变的记录被发送给输出topic。
等等(我们跳过第三行数据处理)。这解释了为什么输出topic中有显示的以下内容,因为它包含所有记录改变。
在实例范围之外,kafka stream利用a table和改变stream的对等性(table=the KTable,chaelog stream=the downstream kStream):你可以发布每一个table改变到stream,假如你从开始到结果消费整个改变的stream,你能重构table的内容。
现在你可以写更新输入消息到streams-file-input topic,然后观察附加消息被添加到streams-wordcount-output topic,反射更新单词数(使用控制台生产者和控制台消费者)。
你能停止控制台消费者使用ctr-c。
本人英文水平非常有限,看不懂勿喷。