Kafka架构以及一键化部署
什么是Kafka?
Apache Kafka是一个开放源代码的分布式事件流平台,成千上万的公司使用它来实现高性能数据管道,流分析,数据集成和关键任务等相关的应用程序。
Kafka的应用场景
- 构造实时流数据管道,它可以在系统或应用之间可靠地获取数据 (相当于message queue),特别是在集群情况下,多个服务器需要建立交流
- 构建实时流式应用程序,对这些流数据进行转换或者影响。 (就是流处理,通过kafka stream topic和topic之间内部进行变化)
Kafka架构设计
Producer:生产者可以将数据发布到所选择的topic(主题)中。生成者负责将记录分配到topic的哪一个分区(partition)中,这里可以使用对多个partition循环发送来实现多个server负载均衡
Broker:日志的分区(partition)分布在Kafka集群的服务器上。每个服务器处理数据和请求时,共享这些分区。每一个分区都会在以配置的服务器上进行备份,确保容错性。
其中,每个分区都有一台server作为leader,零台或堕胎server作为follows。leader server处理一切对分区的读写请求,而follwers只需被动的同步leader上的数据。当leader宕机了,followers中的一台server会自动成为新的eader,每台server都会成为某些分区的leader和某些分区的follower,因此集群的负载是均衡的
Consumer:消费者使用一个group(消费组)名称来表示,发布到topic中的每条记录将被分配到订阅消费组中的其中一个消费者示例。消费者实例可以分布在多个进程中或多个机器上
这里有两个注意的地方
- 如果所有的消费者实例在同一个消费组中,消息记录会负载均衡到消费组中的每一个消费者实例
- 如果所有的消费者实例在不同的消费组中,则会将每条消息记录广播到所有的消费组或消费者进程中
如图中所示,这个Kafka集群中有两台server,四个分区(p0-p3)和两个消费组。这时分区中的消息记录会广播到所有的消费者组中
KAFKA文件存储方式
这里比较好理解:
- 一个Topic分别存储在不同的partition中
- 一个partitioin对应着多个replica备份
- 一个relica对应着一个Log
- 一个Log对应多个LogSegment
- 而在LogSegment中存储着log文件、索引文件、其它文件
常见部署
部署之前准备必要的jdk,zookeeper,kafka安装包已经打包好了再网盘里面
链接:https://pan.baidu.com/s/1Kfntr0B-vJNIs25ZgqwCdA
提取码:4fsf
将下载下来的传到要部署的节点执行
tar -zxvf kafka.tar.gz
之后执行脚本
bash -x deploy_kafka.sh ip1 ip2 ip3 0 1 2
其中脚本内容如下所示
#!/bin/bash # 创建目录结构 mkdir -p /opt/kafka/{jdk,kafka,zookeeper} # 解压Java JDK tar -xzvf Alibaba_Dragonwell_8.10.11_x64_linux.tar.gz -C /opt/kafka/jdk # 配置Java环境变量 cat << EOF | sudo tee -a /etc/profile export JAVA_HOME=/opt/kafka/jdk/dragonwell-8.10.11 export PATH=\$PATH:\$JAVA_HOME/bin export CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar export JRE_HOME=\$JAVA_HOME/jre EOF source /etc/profile # 解压Kafka和Zookeeper tar -xvf kafka_2.11-0.10.1.1.tgz -C /opt/kafka/kafka tar -zxvf zookeeper-3.5.4-beta.tar.gz -C /opt/kafka/zookeeper # 检查传入参数数量 if [ "$#" -ne 6 ]; then echo "Usage: $0 IP1 IP2 IP3 ID1 ID2 ID3" exit 1 fi # 读取传入的参数 IP1=$1 IP2=$2 IP3=$3 ID1=$4 ID2=$5 ID3=$6 # 配置Zookeeper cat << EOF | sudo tee /opt/kafka/zookeeper/zookeeper-3.5.4-beta/conf/zoo.cfg > /dev/null tickTime=2000 initLimit=10 syncLimit=5 dataDir=/opt/kafka/zookeeper/zookeeper-3.5.4-beta/zoo/data clientPort=2181 maxClientCnxns=500 server.0=$IP1:2888:3888 server.1=$IP2:2888:3888 server.2=$IP3:2888:3888 EOF # 创建数据和日志目录 mkdir -p /opt/kafka/zookeeper/zookeeper-3.5.4-beta/zoo/{data,logs} # 设置myid文件和Kafka配置文件 CURRENT_IP=$(hostname -I | awk '{print $1}') case $CURRENT_IP in $IP1) echo $ID1 > /opt/kafka/zookeeper/zookeeper-3.5.4-beta/zoo/data/myid sed -i "s/broker.id=0/broker.id=$ID1/g" /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties echo "listeners=PLAINTEXT://$IP1:9092" >> /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties echo "advertised.listeners=PLAINTEXT://$IP1:9092" >> /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties ;; $IP2) echo $ID2 > /opt/kafka/zookeeper/zookeeper-3.5.4-beta/zoo/data/myid sed -i "s/broker.id=0/broker.id=$ID2/g" /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties echo "listeners=PLAINTEXT://$IP2:9092" >> /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties echo "advertised.listeners=PLAINTEXT://$IP2:9092" >> /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties ;; $IP3) echo $ID3 > /opt/kafka/zookeeper/zookeeper-3.5.4-beta/zoo/data/myid sed -i "s/broker.id=0/broker.id=$ID3/g" /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties echo "listeners=PLAINTEXT://$IP3:9092" >> /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties echo "advertised.listeners=PLAINTEXT://$IP3:9092" >> /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties ;; *) echo "Error: Current IP address ($CURRENT_IP) does not match any provided IPs." exit 1 ;; esac # 启动Zookeeper并检查状态 /opt/kafka/zookeeper/zookeeper-3.5.4-beta/bin/zkServer.sh start /opt/kafka/zookeeper/zookeeper-3.5.4-beta/bin/zkServer.sh status # 修改zookeeper.properties配置 echo "dataDir=/opt/kafka/zookeeper/zookeeper-3.5.4-beta/zoo/data" > /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/zookeeper.properties echo "clientPort=2181" >> /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/zookeeper.properties echo "maxClientCnxns=0" >> /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/zookeeper.properties # 修改server.properties配置 sed -i "s/zookeeper.connect=localhost:2181/zookeeper.connect=$IP1:2181,$IP2:2181,$IP3:2181/g" /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties # 启动Kafka echo "等待10s快去启动其他2台" sleep 10 /opt/kafka/kafka/kafka_2.11-0.10.1.1/bin/kafka-server-start.sh -daemon /opt/kafka/kafka/kafka_2.11-0.10.1.1/config/server.properties
自动配置
该脚本会帮你配置zookeeper以及kafka
# zookeeper的zoo.cfg路径以及配置
/opt/kafka/zookeeper/zookeeper-3.5.4-beta/conf/zoo.cfg
tickTime=2000
initLimit=10
syncLimit=5
dataDir=/opt/kafka/zookeeper/zookeeper-3.5.4-beta/zoo/data
clientPort=2181
maxClientCnxns=500
server.0=10.196.52.65:2888:3888
server.1=10.196.52.66:2888:3888
server.2=10.196.52.67:2888:3888
# zookeeper的启动|停止|状态命令
/opt/kafka/zookeeper/zookeeper-3.5.4-beta/bin/zkServer.sh start|stop|status
# zookeeper的日志路径
/opt/kafka/zookeeper/zookeeper-3.5.4-beta/logs
#kafka命令
#创建主题 /opt/kafka/kafka/kafka_2.11-0.10.1.1/bin/kafka-topics.sh --create --zookeeper localhost:2181 --replication-factor 2 --partitions 6 --topic test #列出主题信息 /opt/kafka/kafka/kafka_2.11-0.10.1.1/bin/kafka-topics.sh --list --zookeeper localhost:2181 #查看某个主题的分区信息 /opt/kafka/kafka/kafka_2.11-0.10.1.1/bin/kafka-topics.sh --describe --zookeeper localhost:2181 --topic test #生产者: /opt/kafka/kafka/kafka_2.11-0.10.1.1/bin/kafka-console-producer.sh \ --broker-list 10.196.52.65:9092,10.196.52.66:9092,10.196.52.67:9092 --topic test #消费者: /opt/kafka/kafka/kafka_2.11-0.10.1.1/bin/kafka-console-consumer.sh \ --bootstrap-server 10.196.52.65:9092,10.196.52.66:9092,10.196.52.67:9092 --topic test --from-beginning
# kafka主要路径