系统环境准备
首先准备三个centos系统的虚拟机。
IP地址分别配成:
- 192.168.240.101
- 192.168.240.102
- 192.168.240.103
安装jdk1.8
下载jdk1.8。
-rw-r--r--. 1 root root 194042837 Jan 14 22:40 jdk-8u202-linux-x64.tar.gz
解压并且移动到/opt目录中,然后配置环境变量。
>tar -zxvf jdk-8u202-linux-x64.tar.gz
>mkdir -p /opt/java
>mv jdk1.8.0_202 /opt/java
以上我都是用root用户权限执行。我们看一下新目录的属性:
drwxr-xr-x. 3 root root 26 Jan 14 22:40 java
只要保证其他用户有执行权限和读取权限就可以了。
然后我们可以配置java的环境变量。我把环境变量配到/etc/profile
文件中,因为我觉得jdk是一个全局的工具软件。
>vim /etc/profile
JAVA_HOME=/opt/java/jdk1.8.0_202
PATH=$JAVA_HOME/bin:$PATH
export JAVA_HOME PATH
unset i
unset -f pathmunge
实际我只添加了前三行,最后两行贴出来是为了表示出我添加的配置所在的位置。它们位于unset i
这条语句前面。配置好环境变量以后我们用source
命令让其生效。
>source /etc/profile
执行java -version
命令检查配置是否生效:
>java -version
java version "1.8.0_202"
Java(TM) SE Runtime Environment (build 1.8.0_202-b08)
Java HotSpot(TM) 64-Bit Server VM (build 25.202-b08, mixed mode)
看到java版本号后表明jdk安装成功。
安装zookeeper集群
安装
我准备在三个机器上分配安装一个节点的zookeeper组成集群环境。首先下载zookeeper安装包。建议去apache zookeeper官网下载。
https://zookeeper.apache.org/
-rw-rw-r--. 1 node01 node01 9311744 Feb 29 13:11 apache-zookeeper-3.5.7-bin.tar.gz
执行以下命令将安装包解压,并且重命名为zookeeper-3.5.7(非必要,我只是想让名字简短一点儿)。然后移动到/opt
目录中。我的前两个命令是在我的自定义用户node01下执行的,为了移动到/opt
目录中,所以最后一个命令我加上了sudo。
>tar -zxvf apache-zookeeper-3.5.7-bin.tar.gz
>mv apache-zookeeper-3.5.7-bin zookeeper-3.5.7
>sudo mv zookeeper-3.5.7 /opt
配置
zookeeper的配置文件在${ZOOKEEPER_HOME}/conf
中,我们看一下这个目录的内容:
-rw-r--r--. 1 node01 node01 535 May 4 2018 configuration.xsl
-rw-r--r--. 1 node01 node01 2712 Feb 7 21:54 log4j.properties
-rw-r--r--. 1 node01 node01 922 Feb 7 21:54 zoo_sample.cfg
我们配置一份zoo_sample.cfg
并且重名为zoo.cfg
作为我们的zookeeper配置文件。
>cp zoo_sample.cfg zoo.cfg
>ls -l
-rw-r--r--. 1 node01 node01 535 May 4 2018 configuration.xsl
-rw-r--r--. 1 node01 node01 2712 Feb 7 21:54 log4j.properties
-rw-r--r--. 1 node01 node01 922 Feb 29 15:11 zoo.cfg
-rw-r--r--. 1 node01 node01 922 Feb 7 21:54 zoo_sample.cfg
我们看一下zoo.cfg
的内容:
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
dataDir=/tmp/zookeeper
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1
配置如下几个配置项:
# 数据目录
dataDir=/opt/zookeeper-3.5.7/data
# the port at which the clients will connect
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
# 集群节点
server.1=192.168.240.101:2888:3888
server.2=192.168.240.102:2888:3888
server.3=192.168.240.103:2888:3888
创建/opt/zookeeper-3.5.7/data
目录:
>mkdir -p /opt/zookeeper-3.5.7/data
启动zookeeper:
>cd /opt/zookeeper-3.5.7/
>bin/zkServer.sh start
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.5.7/bin/../conf/zoo.cfg
Starting zookeeper ... STARTED
我们查看以下状态:
>bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Error contacting service. It is probably not running.
似乎启动失败了,我们检查以下日志,日志文件位于${ZOOKEEPER_HOME}/logs
中。
>cd /opt/zookeeper-3.5.7/logs
>ls -l
-rw-rw-r--. 1 node01 node01 1343 Feb 29 15:47 zookeeper-node01-server-localhost.localdomain.out
>cat zookeeper-node01-server-localhost.localdomain.out
org.apache.zookeeper.server.quorum.QuorumPeerConfig$ConfigException: Error processing /opt/zookeeper-3.5.7/bin/../conf/zoo.cfg
at org.apache.zookeeper.server.quorum.QuorumPeerConfig.parse(QuorumPeerConfig.java:156)
at org.apache.zookeeper.server.quorum.QuorumPeerMain.initializeAndRun(QuorumPeerMain.java:113)
at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:82)
Caused by: java.lang.IllegalArgumentException: myid file is missing
at org.apache.zookeeper.server.quorum.QuorumPeerConfig.checkValidity(QuorumPeerConfig.java:736)
at org.apache.zookeeper.server.quorum.QuorumPeerConfig.setupQuorumPeerConfig(QuorumPeerConfig.java:607)
at org.apache.zookeeper.server.quorum.QuorumPeerConfig.parseProperties(QuorumPeerConfig.java:422)
at org.apache.zookeeper.server.quorum.QuorumPeerConfig.parse(QuorumPeerConfig.java:152)
... 2 more
Invalid config, exiting abnormally
可以看到缺失了myid
文件。我们手动创建这个文件。这个文件需要放到数据目录中,也就是我们之前创建的/opt/zookeeper-3.5.7/data
目录中。
>echo "1" > /opt/zookeeper-3.5.7/data/myid
这个“1”对应着配置文件中server.1=192.168.240.101:2888:3888
里面的“1”。其它两个服务器参照以上操作。另外还需要防火墙放开两个端口,一个是2181,一个是3888。centos七中可以命令firewall-cmd
来操作,如下:
>firewall-cmd --add-port=2181/tcp --permanent
>firewall-cmd --add-port=3888/tcp --permanent
>firewall-cmd --reload
再次启动zk,我们再次查看状态:
>bin/zkServer.sh start
bin/zkServer.sh status
ZooKeeper JMX enabled by default
Using config: /opt/zookeeper-3.5.7/bin/../conf/zoo.cfg
Client port found: 2181. Client address: localhost.
Mode: leader
至此,zookeeper集群启动成功。其中一个leader节点,两个follower节点。
kafka集群安装
安装
下载kafka安装包,依然去官网下载:
http://kafka.apache.org/
-rw-rw-r--. 1 node01 node01 62283588 Feb 29 13:06 kafka_2.12-2.4.0.tgz
解压kafka安装包,重命名为kafka_2.12-2.4.0
,并且移动到/opt
目录下面。
>tar -zxf kafka_2.12-2.4.0.tgz
>mv kafka_2.12-2.4.0 /opt
配置
我们看一看目录结构:
>cd /opt/kafka_2.12-2.4.0/
>ls -l
drwxr-xr-x. 3 node01 node01 4096 Dec 10 00:52 bin
drwxr-xr-x. 2 node01 node01 4096 Feb 29 16:18 config
drwxr-xr-x. 2 node01 node01 8192 Feb 29 13:07 libs
-rw-r--r--. 1 node01 node01 32216 Dec 10 00:46 LICENSE
-rw-r--r--. 1 node01 node01 337 Dec 10 00:46 NOTICE
drwxr-xr-x. 2 node01 node01 44 Dec 10 00:52 site-docs
配置文件位于config目录中,里面有很多配置文件:
-rw-r--r--. 1 node01 node01 906 Dec 10 00:46 connect-console-sink.properties
-rw-r--r--. 1 node01 node01 909 Dec 10 00:46 connect-console-source.properties
-rw-r--r--. 1 node01 node01 5321 Dec 10 00:46 connect-distributed.properties
-rw-r--r--. 1 node01 node01 883 Dec 10 00:46 connect-file-sink.properties
-rw-r--r--. 1 node01 node01 881 Dec 10 00:46 connect-file-source.properties
-rw-r--r--. 1 node01 node01 2247 Dec 10 00:46 connect-log4j.properties
-rw-r--r--. 1 node01 node01 1539 Dec 10 00:46 connect-mirror-maker.properties
-rw-r--r--. 1 node01 node01 2262 Dec 10 00:46 connect-standalone.properties
-rw-r--r--. 1 node01 node01 1221 Dec 10 00:46 consumer.properties
-rw-r--r--. 1 node01 node01 4675 Dec 10 00:46 log4j.properties
-rw-r--r--. 1 node01 node01 1925 Dec 10 00:46 producer.properties
-rw-r--r--. 1 node01 node01 6848 Dec 10 00:46 server.properties
-rw-r--r--. 1 node01 node01 1032 Dec 10 00:46 tools-log4j.properties
-rw-r--r--. 1 node01 node01 1169 Dec 10 00:46 trogdor.conf
-rw-r--r--. 1 node01 node01 1441 Dec 10 00:46 zookeeper.properties
目前我们只需要修改server.properties
这个文件。
修改以下zookeeper地址:
#zookeeper.connect=localhost:2181
zookeeper.connect=192.168.240.101:2181,192.168.240.102:2181,192.168.240.103:2181
设置broker.id
。这个值必要在所有节点中保持唯一,我们有三个节点,所以分别设置为0
,1
,2
。
配置监听地址和端口:
listeners=PLAINTEXT://192.168.240.101:9092
每个节点根据实际情况配置。
启动
在后台启动kafka:
bin/kafka-server-start.sh -daemon config/server.properties
在任一节点创建一个topic:
>bin/kafka-topics.sh --create --bootstrap-server 192.168.240.101:9092 --replication-factor 3 --partitions 1 --topic topic-test
查看创建的topic:
>bin/kafka-topics.sh --describe --bootstrap-server 192.168.240.101:9092 --topic topic-test
Topic: topic-test PartitionCount: 1 ReplicationFactor: 3 Configs:
Topic: topic-test Partition: 0 Leader: 1 Replicas: 1,0,2 Isr: 1,0,2
到此,kafka集群创建完毕。
附注
名词解释
- Broker - Kafka集群包含一个或多个服务器,服务器节点称为broker。broker存储topic的数据。如果某topic有N个partition,集群有N个broker,那么每个broker存储该topic的一个partition。如果某topic有N个partition,集群有(N+M)个broker,那么其中有N个broker存储该topic的一个partition,剩下的M个broker不存储该topic的partition数据。如果某topic有N个partition,集群中broker数目少于N个,那么一个broker存储该topic的一个或多个partition。在实际生产环境中,尽量避免这种情况的发生,这种情况容易导致Kafka集群数据不均衡。
- Topic - 每条发布到Kafka集群的消息都有一个类别,这个类别被称为Topic。(物理上不同Topic的消息分开存储,逻辑上一个Topic的消息虽然保存于一个或多个broker上但用户只需指定消息的Topic即可生产或消费数据而不必关心数据存于何处)。类似于数据库的表名。
- Partition - topic中的数据分割为一个或多个partition。每个topic至少有一个partition。每个partition中的数据使用多个segment文件存储。partition中的数据是有序的,不同partition间的数据丢失了数据的顺序。如果topic有多个partition,消费数据时就不能保证数据的顺序。在需要严格保证消息的消费顺序的场景下,需要将partition数目设为1。
- Producer - 生产者即数据的发布者,该角色将消息发布到Kafka的topic中。broker接收到生产者发送的消息后,broker将该消息追加到当前用于追加数据的segment文件中。生产者发送的消息,存储到一个partition中,生产者也可以指定数据存储的partition。
- Consumer - 消费者可以从broker中读取数据。消费者可以消费多个topic中的数据。
- Consumer Group - 每个Consumer属于一个特定的Consumer Group(可为每个Consumer指定group name,若不指定group name则属于默认的group)。
- Leader - 每个partition有多个副本,其中有且仅有一个作为Leader,Leader是当前负责数据的读写的partition。
- Follower - Follower跟随Leader,所有写请求都通过Leader路由,数据变更会广播给所有Follower,Follower与Leader保持数据同步。如果Leader失效,则从Follower中选举出一个新的Leader。当Follower与Leader挂掉、卡住或者同步太慢,leader会把这个follower从“in sync replicas”(ISR)列表中删除,重新创建一个Follower。
参数
kafka-topics.sh参数
- replication-factor - 用来设置主题的副本数。每个主题可以有多个副本,副本位于集群中不同的broker上,也就是说副本的数量不能超过broker的数量,否则创建主题时会失败。