初识kafka

Kafka 是一款分布式的基于 发布/订阅 模式的消息中间件。
相较于其他框架,kafka与大数据生态的组件更兼容(比如直接有Flink-kafka数据源DataStream、甚至Kafka Table(Flink SQL) 的API,)。(大数据组件也可以使用其他MQ)

  • 消息中间件主要作用:

    1. 异步通信
    2. 削峰
    3. 解耦:代替应用间接口调用,降低应用互相依赖
  • kafka用于数据实时采集流程举例

    1. log、csv文件 --> flume --> kafka -->ss / flink
    2. mysql / oracle --> maxwell / ogg
  • 大数据场景数据来源:

    1. 数据库:(关系型、非关系型)
    2. 文件:log文件,csv文件(方便程序之间转移的excel表格数据)

kafka 概述

kafka 官网:kafka.apache.org

Apache Kafka is an open-source distributed event streaming platform used by thousands of companies for high-performance data pipelines, streaming analytics, data integration, and mission-critical applications.
(distributed event streaming platform :分布式事件流平台 - -对标大数据流式组件 ss、flink、结构化流)

kafka 也不单纯做中间件,不甘心单单为ss \ flink 提供,也想有自己的流式平台streams,但很小众。

kafka 特点
  • HIGH THROUGHPUT : 高吞吐
  • SCALABLE : 可扩展
  • PERMANENT STORAGE : 持久化
  • HIGH AVAILABILITY :高可用
kafka 版本

下载:https://archive.apache.org/dist/kafka/

kafka 模式
  • 点对点模式
    一个生产者、一个消费者。消费者主动从Message Queue中拉取消息并消费,再发送确认给Message Queue,Message Queue收到消费者确认消费后会删除消息。
  • 发布/订阅模式
    可以有多个topic,且一个topic可以被多个消费者订阅并消费。消费者消费后不会删除消息(供其他消费者消费)。多个消费者互相独立。
架构
  • topic 主题,可以有多个主题。

  • partition 是topic的物理分组,代表进入topic的文件可以被切分,一个topic至少一个paitition,在partition中有序 。
    partition 的名称是以topic-编号组成。

  • replication 是备份的副本,防止每个partition的单点故障,每个partition(leader)个可以有多个follower。

    TopicA
    
    leader                follower
    TopicA-partition1     TopicA-repartition2
    TopicA-partition2     TopicA-repartition3
    TopicA-partition3     TopicA-repartition1
    

    生产和消费消息都只针对leader,只有leader故障时才将特定follower转换为leader。(如何找到leader,如何将follower转换为leader由zookeeper完成,(2.8.0以后可选不用ZK,kafka自己处理))

  • zookeeper 会保存两类数据:

    1. kafka集群中节点的在线情况
    leader是在ZK中以节点存在:
    /brokers/ids/[0,1,2]
    
    1. 所有leader与对应follower
    同时对每个partition还保存了哪些是leader,哪些是follower:
    /brokers/topics/first/partitions/0/state/
    "leader":0,"isr":[1,2]
    
  • acks
    acks 有三个值,分别对应3种处理方式
    acks = 0 : 生产者发送消息后不会等待kafka报告是否成功提交。
    acks = 1 :当主副本提交成功数据(记录到日志)就返回生产者,不关心其他节点成功与否。
    acks = all (等价 -1): 当主副本和所有备份副本都提交成功数据。最安全,但性能会有损耗。

部署使用

集群部署,三台机器
  1. 每台机器先配置hosts,如(hadoop001、hadoop002、hadoop003)

  2. 下载解压kafka后,进入 ./config 目录下,打开server.properties 做以下配置

    • 每一台机器是一个broker,通过指定 broker.id区分集群中每台机器。broker.id=0 (其余两台分别是1,2)

    • log.dirs=/tmp/kafka-logs (存储的是消息内容的数据,而不是kafka运行的日志。修改到非/tmp的目录)

    • log.retention.hours=168 [默认保留数据7天,按需修改]

    • zookeeper.connect=hadoop001:port,hadoop002:port,hadoop003:port/kafka (部署zookeeper集群的hostname:port) (/kafka 表示在三台ZK下创建一个/kafka目录统一存放)

    • 进kafka的数据,会经过压缩,默认保留7天

  3. 修改文件后,在 ./bin 目录找到启动命令

    kafka-server-start.sh [-daemon] 可选指定以后台进程的方法启动
    kafka-server-start.sh  -daemon  [../config/server.properties]  可选带配置文件启动
    

    启动后会有一个进程Kafka(zookeeper的进程是QuorumpeerMain),stop时先关闭kafka再关闭zk.

乱序

由于多个partition并行提交消息,不同partition之前的顺序不能保证全局有序的。(一个partition内是有序的)

解决乱序:

  1. 牺牲吞吐量,只设置一个partition,缺失了使用kafka的意义。
  2. 消费后先做全局排序,性能开销很大。
  3. 将部分有关联的,有顺序要求的数据指定到同一个Key,保证进入同一个partition。
    那么如何关联让partition认这个key呢:
    代码层面:send消息的时候指定key, 源码算法就是取这个key做hash运算以确定partition,key为空才取其他的内容做hash
    配置层面:如果使用maxwell,可以有参数 producer_partition_by 指定如按数据库主键为key等,保证对同一个主键数据的操作是按顺序的

047 kafka-04 J哥解决乱序的过程和配置,这套配置仍在使用

kafka.acks = all
producer_partition_by =  primary_key
kafka.retries = 100
max.in.flight.requests.per.connection = 1 

补充,如果仍出现数据差异,在业务低谷时,对比大数据和RDBMS,对有差异的数据多退少补。做补偿机制,

常用命令
topic
  • 创建topic
    ./kafka-topic.sh \
    --create \
    --zookeeper hostname:port,hostname:port,... \
    --topic test_topic \
    --partitions 3 \
    --replication-factor 3 
    
  1. 注意:如果kafka配置zookeeper.connect保持时指定了根目录/kafka,则这里–zookeeper 的内容也要指定到/kafka。也就是要和配置文件server.properties中zookeeper.connect保持一致。
    kafka-topics.sh \
    --create \
    --zookeeper localhost:2181/kafka \
    --replication-factor 1 \
    --partitions 1 \
    --topic test
    
  • 查看所有topic

    ./kafka-topic.sh \
    --list \
    --zookeeper hostname:port,hostname:port,...
    
  • 描述(也可验证topic是否正常创建)

    ./kafka-topic.sh \
    --describe \
    --zookeeper hostname:port,hostname:port,...
    
    描述中的内容代表的意义
    Partition: 0  代表分区的number
    Leader: 0  和 Repicas:0,1,2  代表当前分区所在的机器的broker.id
    
  • 修改topic (尽量一次创建好,不得已才修改)

    ./kafka-topic.sh \
    --alter \
    --zookeeper hostname:port,hostname:port,... \
    --topic test_topic \
    --partitions 3   // 不能往小了调
    

    建议值 partitions 8,replication-factor 3 。
    为什么要调整 partitions ,kafka partitions : spark partitions == 1:1; 临时加了机器。

  • 删除topic

    ./kafka-topics.sh \
    --delete \
    --zookeeper ruozedata001:2181,ruozedata002:2181,ruozedata003:2181/kafka \
    --topic test_topic
    

    删除时出现:
    Topic jj is marked for deletion. --仅仅时打了’删除’的标签
    Note: This will have no impact if delete.topic.enable is not set to true.

    delete.topic.enable=true 是受这个配置决定,(不要删除是最保险的,不打算用的话等着7天回收就行)

  • 迁移(机器、磁盘)
    反复验证后使用
    http://kafka.apache.org/documentation/#basic_ops_automigrate

    // 创建一个json文件
    cat topics-to-move.json
    {"topics": [{"topic": "foo1"}],
    "version":1
    }
    
    bin/kafka-reassign-partitions.sh \
    --zookeeper localhost:2181 \
    --topics-to-move-json-file topics-to-move.json \
    --broker-list "5,6" \
    --generate
    
    bin/kafka-reassign-partitions.sh \
    --zookeeper localhost:2181 \
    --reassignment-json-file expand-cluster-reassignment.json \
    --execute
    

关于topic创建:

  1. kafka topic名称规范: 英文字母小写
  2. 在建topic之前,名字想好了 真的想好了再建
  3. 不要轻易删除topic 就算生产上这个topic不用了 且 数据量较大, 也没关系 7天后数据会自己删除
  4. 不要有强迫症,不要随意修改、删除
生产/消费者
  • 创建生产者和消费者 (用于验证是否生产、消费)
    ./kafka-console-producer.sh \
    --zookeeper hostname:port,hostname:port,... \
    --topic test_topic 
    
    ./kafka-console-consumer.sh \
    --zookeeper hostname:port,hostname:port,... \
    --topic test_topic 
    

Kafka容错机制的理解

kafka为保证高可用做了很多处理,以副本机制在多个服务端节点上对每个主题分区的日志进行复制,副本的单位是按主题下的分区,即对每个主题的每个分区都有副本。
其中一个为主副本Leader,其余多个备份副本,主副本负责响应客户端的读写请求,备份副本则从主副本拉取数据,保持和主副本的同步。
基于多副本冗余设计,kafka就有了容错的保证。即当部分节点宕机时,仍然保证系统正常对外提供服务,且外界无感知。
当主副本宕机时,kafka会在备份副本中选择一个作为主副本,对客户端提供响应。
(为尽量保证主副本和备份副本不同时宕机,主副本应该均匀的分布在各个服务器上,且互相做备份副本,即一台机器做其中一个分区的主副本,同时还做另一分区的备份副本)
当一个备份副本宕机(没有和ZK节点保持会话)、或备份进度落后太多时,主副本就会将其从同步副本集合中移除,反之,如果备份副本重新赶上主副本,它就会加入到主副本的同步集合中。
(一组主副本和其备份副本,成为一组 In Sync Replicas 即ISR)

当然这样的设计会对数据的同步和可靠性增加管理难度。
当acks = all,一条消息只有被所有副本都运用到本地的日志文件,才会认为消息被成功提交到kafka。只有已经提交的消息才能被消费者消费。
当acks = all,对于生产者所发送的一条消息已经写入到主副本中,但是此时备份副本还没来及进行数据copy时,主副本就挂掉的情况,那么此时消息提交不成功,生产者需要重新发送该消息。

acks 有三个值,分别对应3种处理方式
acks = 0 : 生产者发送消息后不会等待kafka报告是否成功提交。
acks = 1 :当主副本提交成功数据(记录到日志)就返回生产者,不关心其他节点成功与否。
acks = all (等价 -1): 当主副本和所有备份副本都提交成功数据。最安全,但性能会有损耗。
生产环境会在 1 和 all 之间根据业务类型选择。
当 acks = all ,但Partition只有一个主副本Leader,没有任何Follower,则设置all与1并无区别,不能保证数据一定安全。
并且在有Follower情况下,如果副本放置不合理如一组ISR都在同一台机器导致全部宕机,也会丢失。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值