到目前为止,我们一直在使用单个代理,这并不好玩。对 Kafka来说,单个代理只是一个大小为一的集群,除了启动更多的代理实例外,没有什么变化。 为了深入了解它,让我们把集群扩展到三个节点(仍然在本地机器上)。
首先,为每个代理创建一个配置文件 (在Windows上使用copy
命令来代替):
1
2
>
cp
config
/server
.properties config
/server-1
.properties
>
cp
config
/server
.properties config
/server-2
.properties
现在编辑这些新文件并设置如下属性:
1
2
3
4
5
6
7
8
9
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-2
broker.id
属性是集群中每个节点的名称,这一名称是唯一且永久的。我们必须重写端口和日志目录,因为我们在同一台机器上运行这些,我们不希望所有的代理尝试在同一个端口注册,或者覆盖彼此的数据。
我们已经建立Zookeeper和一个单节点了,现在我们只需要启动两个新的节点:
1
2
3
4
> bin
/kafka-server-start
.sh config
/server-1
.properties &
...
> bin
/kafka-server-start
.sh config
/server-2
.properties &
...
现在创建一个副本为3的新topic:
1
> bin
/kafka-topics
.sh --create --zookeeper localhost:2181 --replication-factor 3 --partitions 1 --topic my-replicated-topic
Good,现在我们有一个集群,但是我们怎么才能知道那些代理在做什么呢?运行"describe topics"命令来查看:
1
2
3
> 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
以下是对输出信息的解释。第一行给出了所有分区的摘要,下面的每行都给出了一个分区的信息。因为我们只有一个分区,所以只有一行。
- “leader”是负责给定分区所有读写操作的节点。每个节点都是随机选择的部分分区的领导者。
- “replicas”是复制分区日志的节点列表,不管这些节点是leader还是仅仅活着。
- “isr”是一组“同步”replicas,是replicas列表的子集,它活着并被指到leader。
请注意,在示例中,节点1是该主题中唯一分区的领导者。
我们可以在已创建的原始主题上运行相同的命令来查看它的位置:
1
2
3
> 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
这没什么大不了,原来的主题没有副本且在服务器0上。我们创建集群时,这是唯一的服务器。
让我们发表一些信息给我们的新topic:
1
2
3
4
5
> bin
/kafka-console-producer
.sh --broker-list localhost:9092 --topic my-replicated-topic
...
my
test
message 1
my
test
message 2
^C
现在我们来消费这些消息:
1
2
3
4
5
> 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 现在是 leader,让我们来杀了它:
1
2
3
>
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 上用:
1
2
3
4
> wmic process where
"caption = 'java.exe' and commandline like '%server-1.properties%'"
get processid
ProcessId
6016
> taskkill
/pid
6016
/f
领导权已经切换到一个从属节点,而且节点1也不在同步副本集中了:
1
2
3
> 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
不过,即便原先写入消息的leader已经不在,这些消息仍可用于消费:
1
2
3
4
5
> bin
/kafka-console-consumer
.sh --bootstrap-server localhost:9092 --from-beginning --topic my-replicated-topic
...
my
test
message 1
my
test
message 2
^C
这个是对应官网得文档,但是在实际学习中,还是会遇到很多坑。
如,配置多个配置文件,
这个标红得一定要和其他配置文件不一样。
这是两个不一样得代理,但是同步还是很快得,实现了高可用和高扩展。