kafka基础架构

190 阅读6分钟

这是我参与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会往拥有最少数目分区的路径新增分区, 而不是往拥有最小磁盘空间的路径新增分区。