这是我参与8月更文挑战的第4天,活动详情查看:8月更文挑战
Kafka
架构
基础架构
kafka是一个分布式, 分区的, 多副本的, 多生产者, 多订阅者,基于zookeeper协调的分布式日志系统,主要应用场景是日志收集系统和消息系统。
kafka采用发布,订阅模式, 只有消息的拉取,没有推送, 可以通过轮询实现消息的推送。
kafka优势
- 高吞吐量: 每秒几十上百万的消息量
- 高性能: 单节点支持上千客户端, 保证零停机和零数据丢失
- 持久化数据存储: 将数据持久化到磁盘, 通过将数据持久化到硬盘以及replication防止数据丢失
- 分布式系统,易于扩展, 所有的Producer,Broker,Consumer都有多个, 均为分布式
- 可靠性: 分布式分区,复制容错的
- 客户端状态维护: 消息被处理的状态时在Consumer端维护, 当失败时能够自动平衡
- 支持online和offline场景
- 支持多种语言 Java, .Net, php,python等
基础架构
-
消息和批次
kafka数据单元称为消息, 批次就是一组消息,属于同一个主题和分区,把消息分成批次可以减少网络开销,批次越大, 单位时间内处理的消息越多, 单个消息的传输时间越长, 批次数据会被压缩,提升数据传输和存储能力
-
模式
消息模式(schema) 有很多可用选项,如JSON和XML,缺乏强类型处理能力。数据格式一致性,消除了消息读写操作之间的耦合性
-
主题和分区
主题被分成若干分区,一个主题通过分区分布在kafka集群中,提供了横向扩展能力
-
生产者和消费者
生产者创建消息,消费者消费消息,通过偏移量来区分已经读过的消息。消费者组保证每个分区只能被一个消费者使用,避免重复消费
-
broker和集群
一个独立的kafka服务器称为broker,broker接收消息,设置偏移量, 提交消息到磁盘保存。
每个集群都有一个broker是集群控制器,控制器负责将分区分配给broker,监控broker
核心概念
-
Producer
生产者创建消息
-
Consumer
消费者读取消息
-
Broker
一个独立的Kafka服务器
-
Topic
发布到kafka集群的消息类别
-
Partition
主题氛围若干分区,一个分区是一个日志,无法保证整个主题消息顺序,可以保证单个分区的顺序,如果要严格保证消息的消费顺序,partition顺序设置为1
-
Replicas
每个分区有多个 ,副本有两种: leader follower
follower副本包括同步副本和不同步副本, leader切换时只有同步副本可以切换成leader
分区的所有副本统称为AR,所有与leader副本保持一定程度同步的副本(包括leader) 组成ISR, 同步滞后过多的副本组成OSR
HW,高水位, 表示一个特定消息的偏移量, 消费者只能拉到这个offset之前的消息
LEO, 当前日志文件中下一条待写入的offset
-
Offset
生产者Offset: 消息写入的时候,每个分区都有一个offset, 同时也是这个分区最新最大的offset
消费者Offset: consumer A 从0消费到9, offset 记录在9, 下次消费可以选择接着上一次位置消费或者从头消费
安装与配置
基础环境
-
版本对应关系
spring boot : 2.3.6.RELEASE
kafka : kafka_2.13-2.6.0.tgz
zk: apache-zookeeper-3.5.8.tar.gz
-
3台服务器
kf1 kf2 kf3
-
创建路径: /opt/module, /opt/software
hostnamectl set-hostname kf1 hostnamectl set-hostname kf2 hostnamectl set-hostname kf3 # 修改 /etc/hosts 192.168.35.53 kf1 192.168.35.54 kf2 192.168.35.55 kf3 -
关闭防火墙
systemctl stop firewalld systemctl disable firewalld systemctl list-unit-files | grep firewalld -
安装JDK1.8, 配置/etc/profile
export JAVA_HOME=/usr/java/jdk1.8.0_181 export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=$JAVA_HOME/lib:$CLASSPATH export PATH=$JAVA_HOME/bin:$JRE_HOME/bin:$PATH -
ssh 安装
# 用户目录下查看隐藏文件夹.ssh # 没有执行 sudo apt-get install ssh # 进入home目录 cd ~ ssh-keygen -t rsa # 将id_rsa.pub文件内容追加到授权的key文件中 cat ~/.ssh/id_rsa.pub >> ~/.ssh/authroized_keys # 将第一台机器的authorized_keys文件复制到第二台机器上,并将第二台机器的公钥追加到authorized_keys文件中 scp authorized_keys root@xxx.xxx.xxx:~/.ssh/ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys # 将第二台机器的authorized_keys文件复制到第三台机器上,并将第三台机器的公钥追加到authorized_keys文件中 scp authorized_keys root@xxx.xxx.xxx:~/.ssh/ cat ~/.ssh/id_rsa.pub >> ~/.ssh/authorized_keys
zookeeper安装
-
上传 apache-zookeeper-3.5.8-bin.tar.gz 至 /opt/software
-
解压至 /opt/module
tar -zxvf apache-zookeeper-3.5.8-bin.tar.gz -C /opt/module/ -
配置 zoo.cfg,zoo.sample.cfg 重命名为 zoo.cfg
dataDir=/data/zookeeper/data dataLogDir=/data/zookeeper/logs server.1=kf1:2888:3888 server.2=kf2:2888:3888 server.3=kf3:2888:3888 -
分别在 /data/zookeeper/data目录下创建myid文件,文件内容分别为1,2,3
-
各机器上配置ZOOKEEPER_HOME
export ZOOKEEPER_HOME=/opt/module/zookeeper-3.5.8 export PATH=$ZOOKEEPER_HOME/bin:$PATH -
启动zk
# 启动zk zkServer.sh start # 查看zk状态 zkServer.sh status # kafka-server-1 上部署 zookeeper一键启动停止脚本 # startzk.sh cat /opt/onekey/zookeeper/slave | while read line do { echo $line ssh $line "source /etc/profile;nohup zkServer.sh start >/dev/nul* 2>&1 &" }& wait done # stopzk.sh cat /opt/onekey/zookeeper/slave | while read line do { echo $line ssh $line "source /etc/profile;zkServer.sh stop" }& wait done
kafka安装
-
上传kafka_2.13-2.6.0.tgz至 /opt/software
-
解压至 /opt/module
tar -zxvf kafka_2.13-2.6.0.tgz -C /opt/module/ -
各台机器上配置KAFKA_HOME
export KAFKA_HOME=/opt/module/kafka_2.13-2.6.0 export PATH=$KAFKA_HOME/bin:$PATH -
config/server.properties配置
broker.id=1 log.dirs=/opt/data/kafka/logs zookeeper.connect=kf1:2181,kf2:2181,kf3:2181/kafka -
分别启动kafka
kafka-server-start.sh -daemon ../config/server.properties # 执行jps查看java进程 # 通过zookeeper登录查看验证 zkCli.sh -server kf1:2181 ls / ls /brokers/ids # kafka-server-1 上部署 kafka一键启动停止脚本 # startkafka.sh cat /opt/onekey/kafka/slave | while read line do { echo $line ssh $line "export JMX_PORT=9988 && /opt/module/kafka_2.13-2.6.0/bin/kafka-server-start.sh -daemon /opt/module/kafka_2.13-2.6.0/config/server.properties" }& wait done # stopkafka.sh cat /opt/onekey/kafka/slave | while read line do { echo $line ssh $line "/opt/module/kafka_2.13-2.6.0/bin/kafka-server-stop.sh stop" }& wait done -
查看kafka集群topic
kafka-topics.sh --create --bootstrap-server 192.168.35.53:9092 --replication-factor 3 --partitions 1 --topic test-ken-io kafka-console-producer.sh --broker-list 192.168.35.53:9092 --topic test-ken-io kafka-console-consumer.sh --bootstrap-server 192.168.35.54:9092 --topic test-ken-io --from-beginning
kafka eagle监控
-
下载 kafka-eagle-bin-2.0.5.tar.gz,上传至:/opt/software目录
-
解压至 /opt/module 目录
tar -zxvf kafka-eagle-bin-2.0.5.tar.gz -C /opt/module/ cd /opt/module mv kafka-eagle-2.0.5 kafka-eagle -
配置环境变量
export KE_HOME=/opt/module/kafka-eagle export PATH=$PATH:$KE_HOME/bin # kf1 export JAVA_HOME=/opt/module/jdk1.8.0_181 export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=$JAVA_HOME/lib:$CLASSPATH export ZOOKEEPER_HOME=/opt/module/apache-zookeeper-3.5.8 export KAFKA_HOME=/opt/module/kafka_2.13-2.6.0 export ONE_KEY_HOME=/opt/onekey export PATH=$ONE_KEY_HOME/zookeeper:$KAFKA_HOME/bin:$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin:$JRE_HOME/bin:$PATH # kf3 export JAVA_HOME=/opt/module/jdk1.8.0_181 export JRE_HOME=$JAVA_HOME/jre export CLASSPATH=$JAVA_HOME/lib:$CLASSPATH export ZOOKEEPER_HOME=/opt/module/apache-zookeeper-3.5.8 export KAFKA_HOME=/opt/module/kafka_2.13-2.6.0 export KE_HOME=/opt/module/kafka-eagle/kafka-eagle-web-2.0.5 export PATH=$KE_HOME/bin:$KAFKA_HOME/bin:$ZOOKEEPER_HOME/bin:$JAVA_HOME/bin:$JRE_HOME/bin:$PATH -
配置 /opt/software/kafka-eagle/conf/system-config.properties
cd ${KE_HOME}/conf vi system-config.properties # Multi zookeeper&kafka cluster list -- The client connection address of the Zookeeper cluster is set here kafka.eagle.zk.cluster.alias=cluster1 cluster1.zk.list=kafka-server-1:2181,kafka-server-2:2181,kafka-server-3:2181 # Add zookeeper acl cluster1.zk.acl.enable=false cluster1.zk.acl.schema=digest cluster1.zk.acl.username=test cluster1.zk.acl.password=test123 # Kafka broker nodes online list cluster1.kafka.eagle.broker.size=3 # Zkcli limit -- Zookeeper cluster allows the number of clients to connect to kafka.zk.limit.size=25 # Kafka Eagle webui port -- WebConsole port access address kafka.eagle.webui.port=8048 # Kafka offset storage -- Offset stored in a Kafka cluster, if stored in the zookeeper, you can not use this option cluster1.kafka.eagle.offset.storage=kafka # Whether the Kafka performance monitoring diagram is enabled kafka.eagle.metrics.charts=true # Kafka Eagle keeps data for 30 days by default kafka.eagle.metrics.retain=30 # If offset is out of range occurs, enable this property -- Only suitable for kafka sql kafka.eagle.sql.fix.error=false kafka.eagle.sql.topic.records.max=5000 # Delete kafka topic token -- Set to delete the topic token, so that administrators can have the right to delete kafka.eagle.topic.token=keadmin # Kafka sasl authenticate cluster1.kafka.eagle.sasl.enable=false cluster1.kafka.eagle.sasl.protocol=SASL_PLAINTEXT cluster1.kafka.eagle.sasl.mechanism=SCRAM-SHA-256 cluster1.kafka.eagle.sasl.jaas.config=org.apache.kafka.common.security.scram.ScramLoginModule required username="admin" password="admin-secret"; # If not set, the value can be empty cluster1.kafka.eagle.sasl.client.id= # Add kafka cluster cgroups cluster1.kafka.eagle.sasl.cgroup.enable=false cluster1.kafka.eagle.sasl.cgroup.topics=kafka_ads01,kafka_ads02 # Default use sqlite to store data kafka.eagle.driver=org.sqlite.JDBC # It is important to note that the '/hadoop/kafka-eagle/db' path must be exist. kafka.eagle.url=jdbc:sqlite:/opt/module/kafka_2.13-2.6.0/db/ke.db kafka.eagle.username=root kafka.eagle.password=smartloli # (Optional) set mysql address #kafka.eagle.driver=com.mysql.jdbc.Driver #kafka.eagle.url=jdbc:mysql://127.0.0.1:3306/ke?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull #kafka.eagle.username=root #kafka.eagle.password=smartloli -
启动
cd ${KE_HOME}/bin chmod +x ke.sh ./ke.sh start # 重启 和 终止 ke.sh restart ke.sh stop
kafka服务端配置
$KAFKA_HOME/config/server.properties
-
zookeeper.connect
配置kafka要连接的ZK集群地址
zookeeper.connect=zk1:2181, zk2:2181, zk3:2181/kafka -
listeners
用于指定当前Broker对外发布服务的地址和端口, 与advertised.listeners配合,做内外网隔离
内外网配置隔离:
-
listener.security.protocol.map
监听器名称和安全协议的映射配置,每个监听器名称只能出现一次
-
inter.broker.listener.name
用于配置broker之间通信使用的监听器名称, 名称必须在advertised.listeners中
-
listeners
用于配置broker监听的URI和监听器名称列表,使用逗号隔开多个URI及监听器名称, 如果监听器名称不是安全协议,必须配置listener.security.protocol.map,每个监听器必须使用不同的网络端口
-
advertised.listeners
将该地址发布到zk供客户端使用
listener.security.protocol.map=INTERNAL:PLAINTEXT, EXTERNAL:PLAINTEXT listeners=INTERNAL://192.168.100.101:9092, EXTERNAL://192.168.100.130:9093 inter.broker.listener.name=EXTERNAL advertised.listeners=EXTERNAL://192.168.100.130:9093 -
-
broker.id
唯一标记kafka的Broker
-
log.dir
指定kafka在磁盘上保存消息的日志片段的记录,是一组用逗号隔开的本地文件系统路径。
如果制定了多个路径,broker根据最少使用原则,同一个分区的日志片段保存到同一个路径下
broker会往拥有最少数目分区的路径新增分区, 而不是往拥有最小磁盘空间的路径新增分区。