消息队列系列之一Kafka

  • Post author:
  • Post category:其他




本质

kafka是个分布式的、支持多分区、多副本,基于zookeeper的分布式消息流平台,同时也是开源的基于发布订阅的消息引擎系统。



编程语言

基于java 和 scala



消息队列的作用

  • 解耦

    • 主要用于数据的动态传输,不同的接受者和不定的接受任务,用于减少主系统的复杂性。
  • 异步

    • 将一些不必及时响应的业务分发出去,减少主业务的执行时间并提升效率。
  • 削峰

    • 阻塞超量请求,限制任务量,防止数据库和机器过载,保证系统的稳健性。



kafka 的基本术语

  • 消息:kafka中的数据单元称为

    消息

    ,可看做数据表中某一行的记录
  • 批次:指一组消息。为了提升效率消息会分批次写入kafka。
  • 主题:就像是数据库中的表名,起到对消息分类的作用,一个主题(topic)代表一类消息。
  • 分区:提升kafka的伸缩性,主题可以被分为若干分区(partition),同一主题的分区可以不在一个机器上,可以部署在多个机器上,单一主题分区有序,但无法确定主题中所有的分区有序。
  • 生产者:产生消息的对象即生产者。在kafka中指向主题发布消息的应用程序。
  • 消费者;消耗消息的对象即消费者。在kafka中指从指定主题中获取消息的程序。
  • 消费者群组:

    消费者群组即一个或多个消费者组成的群体

  • 偏移量:本身元数据,不断递增的整数值;记录消费者发生重平衡的位置,以使用来恢复数据。
  • broker:一个独立的kafka服务器即broker,其功能接受生产者的消息,设置消息偏移量,提交消息并保存到磁盘。
  • broker:一个或多个broker组成,集群中的活跃成员将选举产生集群控制器,每一个集群中存在一个broker充当

    集群控制器

    的角色。
  • 副本:kafka中消息的备份即副本(Replica)。副本的数量是可以配置的,kafka定义了两类副本:领导者副本和追随者副本,前者对外提供服务,后者只是被动跟随。
  • 重平衡:Rebalance。消费者组内某个消费者实例挂掉后,其他消费者实例自动重新分配订阅主题分区的过程。



kafka的特点(设计原则)

  • 高吞吐、低延迟:kafka最大的特点就是收发消息非常快,kafka每秒可以处理几十万条消息,它的最低延迟只有几毫秒。
  • 高伸缩性:每个主题(topic)包含多个分区(partition),主题中的粪污可以分布在不同的主机(broker)中。
  • 持久性、可靠性:kafaka能允许数据的持久化存储,消息被持久化到磁盘,并支持数据备份方式数据丢失,kafka底层的数据存储是基于zookeeper 存储的,zookeeper我们知道它的数据能够持久存储。
  • 容错性:允许集群中的节点失败,某个节点宕机,kafka集群能够正常工作
  • 高并发:支持数千个客户端同时读写。



kafka的使用场景

  • 活动追踪:跟踪用户行为,比如淘宝的智能推荐,根据你的进入淘宝app的一步步都将记录并成为报告,最终生成你的智能推荐和购买喜好。
  • 传递消息:比如应用程序向用户发送通知就是通过传递消息实现的。这些应用组件可以生成消息,而需要关注消息的格式,也不需要关心小事是如何发送的。
  • 度量报告:经常用来记录运营监控数据。包括手机各种分布式应用的数据,生产各种操作的集中反馈,比如报警和报告。
  • 日志记录:可以将数据库的更新发送到kafka上,用来记录数据库的更新时间,通过kafka以同一接口服务的方式开放给各种consumer。比如hadoop,hbase,Solr等。
  • 流式处理:流式处理是有一个能够提供多种应用程序的领域。
  • 限流削峰:通过队列存储请求,通过空间换时间,延长请求间隔,避免直接请求后端程序导致服务崩溃。



kafka的消息队列

  • kafka的消息队里一般分为两种模式:点对点模式和发布订阅模式。
  • 点对点模式

    • 图示

    :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}

    Producer

    message Broker

    Consumer

  • 发布订阅模式

    • 图示

    :root { --mermaid-font-family: "trebuchet ms", verdana, arial;}

    Producer

    message Broker

    Producer

    Consumer

    Consumer

    一个典型的 Kafka 集群中包含若干Producer,若干broker,若干Consumer Group,以及一个Zookeeper集群。Kafka通过Zookeeper管理集群配置,选举leader,以及在Consumer Group发生变化时进行rebalance。Producer使用push模式将消息发布到broker,Consumer使用pull模式从broker订阅并消费消息。



核心 API

kafka 有四个核心API,它们分别是

  • Producer API,它允许应用程序向一个或多个topics上发送消息记录
  • Consumer API,它允许应用程序订阅一个或多个topics并处理为其生成的记录流。
  • Streams API,

    它允许应用程序作为流处理器,从一个或多个主题中消费输入流并为其生成输出流,有效的将输入流转换成输出流。
  • Connector API,它允许构建和运行将kafka主题链接到现在应用程序或数据系统的可用生产者和消费者。



kafka 为何如此之快

kafka实现

零拷贝

原理来快速移动数据,避免了内核之间的切换。kafka可以将数据记录

分批发送

,从生产者到文件系统到消费者,可以端到端的查看这些批次的数据。

批处理能够进行更有效的

数据压缩

并减少I/O延迟,kafka采用

顺序写入磁盘

的方式,避免了随机磁盘寻址的时间浪费。



spark与kafka整合(版本差异)

  • kafka 0.8+ spark 2.2
  • 实现方式:receiver +direct两种模式
  • receiver 主要问题是偏移量的提交不是基于数据处理而是基于receiver对数据的的接收,当接受到数据kafka就认为数据已经消费。这样会造成数据丢失,比如当偏移量提交给zookeeper后,只对应了数据落地,但没有具体的executor对数据的消费处理情况,当还没有处理数据,dirver进程挂掉,那么数据实际上处理多少有没有处理完都是未知,下次重启spark时候,从zookeeper读取偏移量,这部分数据就可以算丢失了。那如何解决数据丢失问题呢,通过writerAheadLog(WAL)机制,就是将每次的数据保存到hdfs上备份一下,( spark.streaming.receiver.writeAheadLog.enable = true),这样保存文件必将带来一个重复消费和效率低(hdfs存储特性高延迟)下的问题,其中重复消费即你在dirver失效前的计算,都将重新计算。那么这将是个吃力不讨好的方案,所以要根据自己的业务需求来进行选择。基本上的receiver模式接受数据的持久化级别为M_A_D_S_2。
  • receiver 数据堆积问题 通过先消费
  • recever 参数配置

    • WAL 机制
    • 接收速率 spark.streaming.receiver.maxRate
    • 并行度调整 spark.streaming.blockinterval

      • 根据batchinterval 和 blockInterval的差值得出最大并行度,实际计算并行度还得根据数据密度决定
    • 槽点:调整非常不灵活
  • direct 模式

    • 并行度

      • 与kafka中对应topic主题partition个数对应
      • 可以在后续代码中repartition进行调整
    • 端到端的一致性
    • offset

      • 消费者自身管理

        • checkpoint
        • 外存

          • hasoffsetrange
          • 在操作链的头部获取

            • kafkaUtils.createDirectStream
  • kafka 0.10和 spark 2.2

    • kafka中移除receiver并进行了direct升级,完全体现在kafka的升级其中动态主题订阅
    • sparkapi的也进行了升级,创建流的时候,位置策略(preferConsistent),偏向一值,preferBrokers,当计算节点和数据节点一致时使用,preferFixed 指定host和topicPartition的对应关系,其后消费策略(subscribe、subscribePattern、assign),offset(checkpoint,kafka,外存)
    • kafka010+spark2.3之后可以手动提交偏移量

      • CanCommitOffset 最开始的流



版权声明:本文为weixin_43813200原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。