kafka基础入门(一)

一. KafKa概述

1.1 什么是kfk

kfk是一个分布式的基于发布订阅模式消息队列. 主要应用于大数据实时处理领域.

1.2 消息队列的两种模式

消息队列有两种模式: 点对点模式 和 发布订阅模式. kfk是基于发布订阅模式的消息队列.

  • 点对点模式(一对一): 消费者主动拉取消息, 消息收到后删除消息 在这里插入图片描述
    生产者生产消息发送到queue中, 然后消费者从queue中主动拉取数据并消费.
    消息被消费后从queue中删除, 所以消费者不可能消费到已经被消费的消息.
    queue支持存在多个消费者, 但是对一个消息而言, 只能被一个消费者消费.

  • 发布订阅模式(一对多):
    在这里插入图片描述
    生产者将消息发布到topic, 多个消费者订阅该topic. 发布到topic的消息会被所有的的订阅者消费.
    topic作用是进行消息分类, 例如订单相关消息放到订单topic, 用户相关消息放到用户topic.
    订阅topic类似订阅微信公众号.

  • 发布订阅模式下又分为两种模式:消息队列主动向消费者推送消息消费者主动从队列中拉取消息.
    kafka属于发布订阅模式中的消费者主动从队列中拉取消息的模式.

  • 发布订阅模式中消费者主动拉取数据的模式的优点

    1. 同样的消息可以发送给多个消费者(这是发布订阅模式的优点).
    2. 消费者消费数据的速度可以让消费者自己决定(如果是队列主动推送消息到消费者, 假如队列
      每秒推送50M数据, 消费者每秒消费10M数据, 那么消费者就崩了, 每个消费者的消费能力是不
      同的).
  • 发布订阅模式中消费者主动拉取数据的模式的缺点

    1. 有时候会很浪费资源(消费者主动拉取消息, 那么消费者必须一直轮询队列判断是否有新消息,
      即便是队列中没有新消息时也要寻轮询问队列是否有消息. 即维护一个长轮询, 不断询问是否
      有新消息).

  • 注意: 根据上面两点可以知道点对点模式的优缺点.

  • 注意: "发布订阅模式中消费者主动拉取数据的模式"中, 缺点是需要消费者维护一个长轮询, 不断询
    问mq是否有新消息. 那么能不能mq中收到消息之后通知消费者, 这时让消费者再主动拉取呢? 可以,
    但是这样也是有缺点的. 优点就是消费者不用维护和mq的长轮询了. 缺点就是mq需要维护一个列
    表, 这个列表中放的是所有要订阅这个topic的消费者. 还有一个缺点是如果消费者挂了, mq就通知
    不到了.

  • 注意: 消息队列并不是文件存储系统, 所以消息队列保存数据是有期限的 , 不能无限期保存数据, 期限可配置.
    kfk中数据默认保存168小时, 即7天. kafka存消息存到磁盘中, 即能持久化.


  • kfk的日志清理策略:

    • kfk有3种日志清理策略: ①基于时间 ②基于日志大小 ③基于日志起始偏移量
      • 基于时间可以设置日志保留的小时、分钟、毫秒,毫秒的优先级最高,小时的优先级最低
      • 基于日志大小默认1G
    • 默认基于时间,168小时(7天)后删除

1.3 kfk的架构

在这里插入图片描述

  • 每个broker就是一个kfk服务, 就是一个kfk进程. 多个broker构成一个kfk集群. 一个broker可以容纳多个topic.

  • topic作用是消息分类. 例如订单相关消息存到订单topic, 用户相关消息存到用户topic.

  • 一个topic可以分为多个partition 分区, 一个topic可以分布到多个broker中.
    分区的作用是提高topic的负载能力, 可以说是提高读写并发度.

  • replica 副本. 为了保证broker发生故障时, 该节点中的partition数据不会丢失且kfk能继续工作, kfk提供了副本机制, 一个topic的每个partition都可以有多个replica. 一个leader和若干个follower, 说一个partition有3个replica, 说明这个partition有1个leader和2个follower.
    分区的副本的作用是做高可用. lader挂掉会将follower提升为leader. 同一个partition的leader和follower肯定不能在同一个broker(kafka服务器)中, 否则不能高可用. 无论是生产者还是消费者, 无论是发送消息还是接受消息, 只会找leader, follower只是起到备份作用.

  • consumer group 消费者组(CG). 由多个consumer组成. 消费者组中每个消费者负责消费不同partition的数据, 一个partition只能由一个组内的消费者消费. 消费者组之间互不影响. 消费者肯定属于某个消费者组. 消费者组是一个逻辑上的订阅者.

    这里面有一个消费者组中的分区分配策略问题. 生产者也有一个消息发送到分区的分配策略问题.

    某一个partition分区中的数据只能被同一个消费者组中的某一台消费者消费. 但是可以有多个消费者组中的一台消费者消费同一个partition分区中的数据. 我们可以将同一个组的所有消费者当做一个大的消费者.

    消费者组的作用是提高消费者的消费能力. 假如一个topic两个partition, 每个partition中各有50条数据, 只有一台消费者, 那么一台消费者需要消费50条数据. 假如一个topic两个partition, 每个partition中有50条数据, 两台消费者, 那么每台消费者可以消费50条数据, 速度快了一倍. 两台消费者必须同一个组(消费者集群中的所有节点作为一个mq消费者组), 因为两个partition属于同一个topic. 消费者组中消费者的个数多于topic的partition分区数没有意义, 最好消费者组中的消费者个数和topic中的partition分区数相同.

  • zk在kfk中的作用: 帮kafka集群存信息, 帮消费者存储消费数据的位置偏移量offset(看kfk版本).

    zk帮助我们管理kafka集群. 如果想使多台kafka作为一个集群, 只需要让这多台kafka使用同一个zk即可, 当然zk可以是集群.

    消费者也要向zk中存储一些数据. 比如一个partition里面10条消息, 一台消费者消费到5条的时候挂了, 那么消费者重启需要从第6条消息开始消费, 消费者消费数据的位置信息就需要存到zk中. 肯定不能只 保存在消费者的内存中啊, 消费者挂了就操蛋了. 消费者内存中也是有一份消费数据的位置信息(offset偏移量)的.

    注意, kafka0.9版本前, 消费者消费消息的offset存在zk中; kafka0.9版本及之后, 消费者消费消息的offset存在kafka中, 存在kafka内置的topic中; 无论消费者消费消息的offset存在哪里, 作用都是记录消费位置, 以便当消费者挂掉后重启后可以接着消费消息.

    为什么要改呢, 肯定是存在zk中不好. 消费者和kfk之间维持连接, 还要和zk之间维持连接, 消费者拉取消息是很快的, 那么就需要消费者频繁和zk交互, 为了避免这种情况就改了.

二. kfk入门

2.1 安装部署kfk

(可以参考:https://www.cnblogs.com/malcolmfeng/p/13372081.html
在这里插入图片描述

# 解压即可使用 
[root@king kafka]# tar -axvf kafka_2.11-0.11.0.0.tgz 
# 重命名
[root@king kafka]# mv kafka_2.11-0.11.0.0 kafka

[root@king kafka]# pwd
/opt/kafka/kafka
[root@king kafka]# ll
total 52
drwxr-xr-x 3 root root  4096 Jun 23  2017 bin
drwxr-xr-x 2 root root  4096 Jun 23  2017 config
drwxr-xr-x 2 root root  4096 Nov 22 23:18 libs
-rw-r--r-- 1 root root 28824 Jun 23  2017 LICENSE
-rw-r--r-- 1 root root   336 Jun 23  2017 NOTICE
drwxr-xr-x 2 root root  4096 Jun 23  2017 site-docs

[root@king config]# pwd
/opt/kafka/kafka/config
[root@king config]# ll
total 64
-rw-r--r-- 1 root root  906 Jun 23  2017 connect-console-sink.properties
-rw-r--r-- 1 root root  909 Jun 23  2017 connect-console-source.properties
-rw-r--r-- 1 root root 5807 Jun 23  2017 connect-distributed.properties
-rw-r--r-- 1 root root  883 Jun 23  2017 connect-file-sink.properties
-rw-r--r-- 1 root root  881 Jun 23  2017 connect-file-source.properties
-rw-r--r-- 1 root root 1111 Jun 23  2017 connect-log4j.properties
-rw-r--r-- 1 root root 2730 Jun 23  2017 connect-standalone.properties
-rw-r--r-- 1 root root 1199 Jun 23  2017 consumer.properties
-rw-r--r-- 1 root root 4696 Jun 23  2017 log4j.properties
-rw-r--r-- 1 root root 1900 Jun 23  2017 producer.properties
-rw-r--r-- 1 root root 6954 Jun 23  2017 server.properties
-rw-r--r-- 1 root root 1032 Jun 23  2017 tools-log4j.properties
-rw-r--r-- 1 root root 1023 Jun 23  2017 zookeeper.properties

# 重点的配置文件:
server.properties
zookeeper.properties 
  • /opt/kafka/kafka/config/server.properties

    ############################# Server Basics #############################
    # kfk服务器的id, 每台kfk都要配置唯一的整数
    broker.id=0
    # 设置是否可以删除topic, 默认注释掉, 默认false. 一般我们将其改为true, 打开注释即可.
    delete.topic.enable=true
    ############################# Socket Server Settings #############################
    # kfk默认端口9092, 在此修改为9091
    listeners=PLAINTEXT://:9091
    # 当前的kfk可以被外界访问. PLAINTEXT://当前kfk的ip:当前kfk的端口 
    advertised.listeners=PLAINTEXT://47.111.177.219:9091
    ############################# Log Basics #############################
    # kfk存储数据使用的目录. kfk的数据和日志都存在这个目录中.
    # kfk存储数据的文件的后缀名叫.log, kfk日志文件的后缀名也叫.log
    # 我们是有办法将日志和数据存放的目录区分开的, 需要额外的配置.
    log.dirs=/tmp/kafka-logs
    ############################# Log Retention Policy #############################
    # kfk中的数据(生产者发来的消息)默认保存到磁盘7天
    log.retention.hours=168
    # 存储kfk数据的一个文件的大小, 1G
    log.segment.bytes=1073741824
    ############################# Zookeeper #############################
    # zk, 如果是zk集群那么多个节点配置按照"127.0.0.1:3000,127.0.0.1:3001,127.0.0.1:3002".
    zookeeper.connect=localhost:2181
    

    完成上述配置, 先启动zk, 再自动kfk.

  • kfk的启动命令 /opt/kafka/kafka/bin
    在这里插入图片描述

  • kfk启动/停止 单台节点

    # 启动kfk. 不加-daemon不能后台启动
    /opt/kafka/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/kafka/config/server-1.properties 
    /opt/kafka/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/kafka/config/server-2.properties 
    /opt/kafka/kafka/bin/kafka-server-start.sh -daemon /opt/kafka/kafka/config/server-3.properties
    # 停止kfk 
    /opt/kafka/kfk/bin/kafka-server-stop.sh 
    

    可以编写shell脚本群启kfk.
    三台broker只要连接同一个zk集群, 就是同一个kfk集群中的节点, 注意三台broker中的broker.id不能相同.

    # linux检查端口占用
    netstat -unltp | grep 909*
    

2.2 kfk的命令行操作

2.2.1 命令行操作topic

  • 创建topic并指定分区和副本

    /bin/kafka-topics.sh --create --zookeeper localhost:2181 --topic topic01 --partitions 2 --replication-factor 2
    

    创建topic. 使用--create参数. 需要指定zk地址.

    --topic topic01 # 主题的名字. 主题的作用是帮我们分类消息.
    --partitions 2 # 两个分区.
    --replication-factor 2 # 每个分区有两个副本.

    创建同名topic将报错;

  • 查看所有的topic

    /bin/kafka-topics.sh --list --zookeeper localhost:2181
    

    查看topic将打印topic的名字.

  • kfk集群和消费者需要向zk中存数据, 因此需要指定zk地址. 如果操作生产者则无需指定zk地址;
    kfk0.9前消费者将消息偏移量存入zk, kfk0.9开始消费者将offset存入broker.

  • 创建topic后, 存储生产者发送过来的数据的文件

    • 我在/opt/kafka/kafka/config/中创建了三个kfk配置文件部署了伪集群:
      server-1.propertiesserver-2.propertiesserver-3.properties.

    • server-*.properties中配置了存放kfk日志和数据的目录(在kfk中数据也叫日志):

      log.dirs=/tmp/kafka-logs-1log.dirs=/tmp/kafka-logs-2log.dirs=/tmp/kafka-logs-3.

    • /tmp/kafka-logs-1目录中有topic01-0topic01-1;
      /tmp/kafka-logs-2目录中有topic01-1;
      /tmp/kafka-logs-3目录中有topic01-0;

    • 可见我们创建了一个topic叫topic01, 这个topic有2个分区, 每个分区有两个副本;
      两个分区就是topic01-0topic01-1. topic01-0topic01-1各有两个副本, 一个是leader一个是follower;
      0和1是分区号;

  • kfk的日志(非数据)文件

    • kfk日志文件目录是/opt/kafka/kafka/logs/server.log; 如果使用jps看不到kfk进程, 查看该文件排查问题;
    • 找不到日志文件就使用命令find / -name server.log获取日志文件路径;
  • 删除名字为first的topic

    /bin/kafka-topics.sh --delete --zookeeper localhost:2181 --topic first
    

    执行上述命令可能提示下面两行:

    Topic first is marked for deletion.

    Note: This will have no impact if delete.topic.enable is not set to true.

    意思是名字为first的topic已被标记删除;

    只有当delete.topic.enable设置为true时topic才会被物理删除;

    经过测试, 实际上无论delete.topic.enable设置为t还是f, 都会有该提示;

  • 查看一个topic详情

    /bin/kafka-topics.sh --describe --topic topic01 --zookeeper localhost:2181
    

    在这里插入图片描述

    因为有两个副本, 所以Replicas后面跟了两个数字.

  • 注意kfk副本数不能超过集群节点数(broker), 否则创建失败报错;
    一个分区的多个副本不能同时存在同一个broker中, 否则不能高可用;

    kfk的分区数(partition)可以超过集群节点数(broker), 这样做时某个broker中会有多个分区;
    在这里插入图片描述

2.2.2 命令行测试生产者消费者

  • 启动控制台的生产者

    /bin/kafka-console-producer.sh --topic topic01 --broker-list localhost:9091
    

    启动生产者时, 需要往指定的topic中发送数据, 因此指定了topic; 需要指定broker; 生产者不和zk交互, 无需指定zk;

  • 启动控制台的消费者 – kfk0.9前

    /bin/kafka-console-consumer.sh --topic topic01 --zookeeper localhost:2181
    # Using the ConsoleConsumer with old consumer is deprecated and will be removed in a future major release. Consider using the new consumer by passing [bootstrap-server] instead of [zookeeper].
    

    启动消费者时, 需要指定从哪个topic消费数据, 因此指定了topic; kfk0.9之后消费者不将offset存到zk, 因此我们指定zk会提示已过时;

  • --from-beginning参数

    • 指定该参数可以让新启动的消费者从头开始消费数据, 否则只有当生产者再次生产数据时新启动的消费者才能消费数据; kfk中数据默认存放7天;

      /bin/kafka-console-consumer.sh --topic topic01 --zookeeper localhost:2181 --from-beginning
      
  • 启动控制台的消费者 – kfk0.9开始

    /bin/kafka-console-consumer.sh --topic topic01 --bootstrap-server localhost:9091 --from-beginning
    

    kfk0.9开始消费者将offset存到broker而不是zk, 因此不指定zk而使用--bootstrap-server参数指定kfk

  • 查看/tmp/kafka-logs-1/tmp/kafka-logs-2/tmp/kafka-logs-2
    在这里插入图片描述

    • 可见多了很多__consumer_offsets-数字, 实际上__consumer_offsets是kfk内置的topic, 数字代表partition分区编号, 实际该topic默认分区数50, 每个分区只有1个副本;
    • 我搭建的是3个broker的伪集群. 这50个partition均匀分布在3台broker中;
    • 小结: kfk中存数据的地方叫topic, 消费者消费消息的位置(消费消息的偏移量offset)在kfk0.9后存储在kfk的内置topic中, 这个topic叫做__consumer_offsets, 默认50个partition, 每个分区1个副本.
  • 注意

    • 如果往一个不存在的topic发送消息, 也能发送成功. kfk会自动创建该topic, 该topic默认有1个分区1个副本; 可在server.properties中配置kfk自动创建topic的分区数和副本数;
    • 如果指定每个分区2个副本, 指的是leader+follower一共2个, 并不是1个leader和2个follower;
    • 同一个partition的leader和follower不能在同一个broker中, 同一个partition的多个follower也不能在同一个broker中;

2.2.3 kafka-topics.sh --describe 显示结果解释

  • 查看名字为mytopic002的topic的详细信息

    [root@king tmp]# /opt/kafka/kafka/bin/kafka-topics.sh --describe --topic mytopic002 --zookeeper localhost:2181
    Topic:mytopic002	PartitionCount:6	ReplicationFactor:2	Configs:
    	Topic: mytopic002	Partition: 0	Leader: 20	Replicas: 20,10	Isr: 20,10
    	Topic: mytopic002	Partition: 1	Leader: 10	Replicas: 10,20	Isr: 10,20
    	Topic: mytopic002	Partition: 2	Leader: 20	Replicas: 20,10	Isr: 20,10
    	Topic: mytopic002	Partition: 3	Leader: 10	Replicas: 10,20	Isr: 10,20
    	Topic: mytopic002	Partition: 4	Leader: 20	Replicas: 20,10	Isr: 20,10
    	Topic: mytopic002	Partition: 5	Leader: 10	Replicas: 10,20	Isr: 10,20
    
    • 第一行显示所有Partition的总结, 以下每一行给出一个Partition中的信息. 因为mytopic002有6个Partition, 所以有6行

    • Leader: 给出所有Partition中负责读写的broker节点, 每个节点都有可能成为leader

    • Replicas: 给定Partition的副本分布在哪些broker节点上

    • Isr: 副本都已同步的broker节点集合, 这个集合中所有节点都是存活状态, 并且跟Leader同步

    • 第二行信息解释

      Topic: mytopic002	Partition: 0	Leader: 20	Replicas: 20,10	Isr: 20,10
      
      • Partition的编号是0, 这个分区属于mytopic002这个topic, Leader副本在broker.id=20的这个broker上, 所有的副本分布在broker.id=10broker.id=20这两个broker上. 所有的副本都存活, 并且跟broker.id=20这个节点同步.
  • ISR的简要解释

    • ISR是所有不落后的replica集合, 不落后有两层含义: 距离上次FetchRequest的时间不大于某一个值或落后的消息数不大于某一个值, Leader失败后会从ISR中随机选取一个Follower做Leader, 该过程对用户是透明的
      • ISR实际上就是同步速度快 同步条数多的副本的集合, 如果Leader副本挂了, 会从ISR中随机选一个副本作为Leader副本
    • ISR是与leader副本保持一定程度同步的副本(ISR包括leader副本)

2.2.4 kfk常用命令

(详见我的这篇博客:https://blog.csdn.net/weixin_43990804/article/details/111997068

# 创建topic并指定分区和副本
/opt/kafka/kafka/bin/kafka-topics.sh --create --zookeeper localhost:2181 --topic topic01 --partitions 2 --replication-factor 2

# 查看topic列表
/opt/kafka/kafka/bin/kafka-topics.sh --list --zookeeper localhost:2181

# 查看某个topic的详情
/opt/kafka/kafka/bin/kafka-topics.sh --describe --topic topic01 --zookeeper localhost:2181

# 删除名字为first的topic
/opt/kafka/kafka/bin/kafka-topics.sh --delete --zookeeper localhost:2181 --topic first

# 启动生产者
/opt/kafka/kafka/bin/kafka-console-producer.sh --topic topic01 --broker-list localhost:9091

# 启动消费者 kfk0.9之前
/opt/kafka/kafka/bin/kafka-console-consumer.sh --topic topic01 --zookeeper localhost:2181

# 启动消费者 kfk0.9开始
/opt/kafka/kafka/bin/kafka-console-consumer.sh --topic topic01 --bootstrap-server localhost:9091 --from-beginning

注意: --from-beginning 代表从头消费数据. 

# 消费指定topic指定partition中的数据,显示数据的key和value
./bin/kafka-console-consumer.sh --topic topicName --bootstrap-server localhost:9092 --property print.key=true --partition 0 --from-beginning

# 查看消费者组
bin/kafka-consumer-groups.sh --zookeeper localhost:2181 --list 或者 
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --list

# 查看某消费者组详细信息
bin/kafka-consumer-groups.sh --zookeeper localhost:2181 --describe --group consumer_group_name 或者 
bin/kafka-consumer-groups.sh --bootstrap-server localhost:9092 --describe --group consumer_group_name 

注意: 
CURRENT-OFFSET表示消费者当前消费到该分区的偏移量。
LOG-END-OFFSET表示当前分区最后的偏移量。
LAG表示消费者“落后”的消费进度。

# 检查topic isr是否完整
./bin/kafka-topics.sh --zookeeper zookeeper.host --describe | less

# 检查缺失isr的topic
./bin/kafka-topics.sh --zookeeper zookeeper.host --describe --under-replicated-partitions

# 检查是否有数据堆积
sh kafka-consumer-offset-checker.sh --zookeeper localhost:2181 --group basp_log --topic topic_name 

# 查看当前消费者组的offset
./kafka-consumer-offset-checker.sh  -zookeeper localhost:2181 --topic topic_name --group consumer_group_name

# 修改分区数
./kafka-topics.sh --zookeeper localshot:2181 --alter --topic topic_name --partition 18  

# 列出消费者组的详细信息
./kafka-run-class.sh kafka.tools.ConsumerOffsetChecker --zookeeper http:2181 --group cousumer_group_name --topic topic_name

# 查看磁盘分布不均衡 (将kfk的数据存放目录设置为data*,方便查询)
du -sh /data*/kafka/log/ 

# 对topic排序
du /data01/kafka/log/* |sort -k1,1n

2.3 kfk的日志和数据分目录存放

在这里插入图片描述注意data目录需要手动创建一下; logs目录不需要手动创建; 在这里插入图片描述

三. kfk架构深入

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
当然可以!以下是一些步骤,可以帮助你快速入门Kafka: 1. 下载并安装Kafka:首先,你需要下载并安装Kafka。你可以从官方网站上下载Kafka:https://kafka.apache.org/downloads。根据你的操作系统选择正确的版本下载并安装。 2. 启动Kafka服务器:安装完成后,你需要启动Kafka服务器。使用终端,进入Kafka文件夹并运行以下命令: ```bash bin/zookeeper-server-start.sh config/zookeeper.properties ``` 然后,在另一个终端窗口中,启动Kafka服务器: ```bash bin/kafka-server-start.sh config/server.properties ``` 3. 创建一个主题:在Kafka中,消息被发送到主题。你需要创建一个主题,以便你可以在其中发布和消费消息。使用以下命令创建一个名为“test”的主题: ```bash bin/kafka-topics.sh --create --topic test --bootstrap-server localhost:9092 ``` 4. 发布消息:现在,你可以向“test”主题发布消息。使用以下命令将消息“Hello, Kafka!”发布到主题: ```bash bin/kafka-console-producer.sh --topic test --bootstrap-server localhost:9092 ``` 5. 消费消息:你可以使用以下命令从“test”主题中消费消息: ```bash bin/kafka-console-consumer.sh --topic test --from-beginning --bootstrap-server localhost:9092 ``` 这将从主题的开头开始读取消息,并将它们打印到控制台上。 这些是入门Kafka的基本步骤。当你掌握了这些基础知识后,你可以进一步了解Kafka的更高级功能和用法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值