Kafka基础

由来

  • Kafka是由Apache软件基金会开发的一个开源流处理平台,由Scala和Java编写。该项目的目标是为处理实时数据提供一个统一、高吞吐、低延迟的平台。其持久化层本质上是一个“按照分布式事务日志架构的大规模发布/订阅消息队列”,这使它作为企业级基础设施来处理流式数据非常有价值。此外,Kafka可以通过Kafka Connect连接到外部系统(用于数据输入/输出),并提供了Kafka Streams——一个Java流式处理库。

结构

  • Kafka的整体架构非常简单,是显式分布式架构,producer、broker(kafka)和consumer都可以有多个。Producer,consumer实现Kafka注册的接口,数据从producer发送到broker,broker承担一个中间缓存和分发的作用。broker分发注册到系统中的consumer。broker的作用类似于缓存,即活跃的数据和离线处理系统之间的缓存。客户端和服务器端的通信,是基于简单,高性能,且与编程语言无关的TCP协议

特点

  • 同时为发布和订阅提供高吞吐量,即使在一台普通的服务器上既可以达到 10W/s 的吞吐速率
  • 可进行持久化操作。将消息持久化到磁盘,因此可用于批量消费,例如ETL,以及实时应用程序。通过将数据持久化到硬盘以及replication防止数据丢失
  • 分布式系统,易于向外扩展。所有的producer、broker和consumer都会有多个,均为分布式的。无需停机即可扩展机器
  • 消息被处理的状态是在consumer端维护,而不是由server端维护。当失败时能自动平衡
  • 支持online和offline的场景

基本概念

  • Broker
    • 缓存代理,Kafka集群中的一台或多台服务器,这种服务器称为broker,一个 Broker 可以是一台物理机,也可以是一个集群
    • broker数量是在整个kafka集群在搭建时就确定的,是跟集群级相关的参数
    • kafka 集群中replication备份的数量受限制于broker的数量,如果一个Topic配置了复制因子( replication facto)为N, 那么可以允许N-1服务器当掉而不丢失任何已经增加的消息
    • Broker数量 跟 partition数量 没有必然关系
    • Kafka 支持水平扩展,一般 broker 数量越多,集群吞吐率越高
  • Zookeeper
    • Kafka 通过 Zookeeper 管理集群配置,选举 leader,以及在 Consumer Group 发生变化时进行 rebalance
  • Topic
    • 特指Kafka处理的消息源(feeds of messages)的不同分类
    • topic在逻辑上可以被认为是一个queue,为了使kafka的吞吐率可以线性提高,可以把topic分成多个partition
    • 物理上不同 Topic 的消息分开存储
    • 逻辑上一个 Topic 的消息虽然保存于一个或多个 broker 上但用户只需指定消息的 Topic 即可生产或消费数据而不必关心数据存于何处
    • Kafka 在概念上将一个 Topic 分成了多个 Partition,写入 topic 的消息会被(平均)分配到其中一个 Partition。Partition 中会为消息保存一个 Partition 内唯一的 ID ,一般称为偏移量(offset)。这样当性能/存储不足时 Kafka 就可以通过增加 Partition 实现横向扩展
  • Partition
    • 是物理上的概念,Topic物理上的分组,一个topic可以分为多个partition
    • 单个partition是kafka中并行操作的最小单元,每个partition可以独立接收推送的消息以及被consumer消费,相当于topic的一个子通道
    • 每个partition是一个有序的队列,partition中的每条消息都会被分配一个有序的id(offset)
    • 每个 Partition 在物理上对应一个文件夹,该文件夹下存储这个 Partition 的所有消息和索引文件
    • 每个 Partition 最终都需要存储在物理机器上,在 Kafka 中一般把这样的物理机器称为 Broker
    • kafka 的每个 topic 都可以创建多个 partition,partition 的数量无上限,并不会像replication一样受限于broker的数量,因此partition的数量可以随心所欲的设置,那确定partition的数量就需要思考一些权衡因素
      • https://www.jianshu.com/p/cdfc3df9e4c6
    • 消费者数要是多于partition数,多出来的消费者只能闲置
      • partition数:为保证在brokers上均匀分配,一般为20、40、60、80,流量高的业务可以更多
    • kafka 文件存储机制
      • https://wiki.bytedance.net/pages/viewpage.action?pageId=205498540
  • Consumer Group:每个consumer属于一个特定的Consumer Group(可为每个Consumer指定 group name,若不指定 group name 则属于默认的 group
    • 通常来讲,消息模型可以分为两种, 队列和发布-订阅式
      • 队列的处理方式是 一组消费者从服务器读取消息,一条消息只有其中的一个消费者来处理。
      • 在发布-订阅模型中,消息被广播给所有的消费者,接收到消息的消费者都可以处理此消息。
    • Kafka为这两种模型提供了单一的消费者抽象模型: 消费者组 (consumer group)
  • Message:消息,是通信的基本单位,每个producer可以向一个topic(主题)发布一些消息
  • Producers:消息和数据生产者,向Kafka的一个topic发布消息的过程叫做producers
    • 生产者往某个Topic上发布消息。生产者也负责选择发布到这此Topic上的哪一个分区。最简单的方式从分区列表中轮流选择。也可以根据某种算法依照权重选择分区。开发者负责如何选择分区的算法
  • Consumers:
    • 消息和数据消费者,订阅topics并处理其发布的消息的过程叫做consumers
    • 假如所有的消费者都在一个组中,那么这就变成了queue模型。
    • 假如所有的消费者都在不同的组中,那么就完全变成了发布-订阅模型。

消息的生命周期

  • 对于传统的消息队列而言,一般会删除已经被消费的消息,而Kafka集群会保留所有的消息,无论其被消费与否。当然,因为磁盘限制,不可能永久保留所有数据(实际上也没必要),因此Kafka提供两种策略删除旧数据。一是基于时间,二是基于Partition文件大小

可扩展性

  • 当需要增加broker结点时,新增的broker会向zookeeper注册,而producer及consumer会根据注册在zookeeper上的watcher感知这些变化,并及时作出调整

设计

  • 吞吐量
    • 高吞吐是kafka需要实现的核心目标之一,为此kafka做了以下一些设计:
      • 数据磁盘持久化:消息不在内存中cache,直接写入到磁盘,充分利用磁盘的顺序读写性能
      • zero-copy:减少IO操作步骤
      • 数据批量发送
      • 数据压缩
      • Topic划分为多个partition,提高parallelism
  • 负载均衡
  • producer根据用户指定的算法,将消息发送到指定的partition
  • 存在多个partiiton,每个partition有自己的replica,每个replica分布在不同的Broker节点上
  • 多个partition需要选取出lead partition,lead partition负责读写,并由zookeeper负责fail over
  • 通过zookeeper管理broker与consumer的动态加入与离开

技术要点 (待跟进)

  • cache
    • kafka不(显式的)使用内存,而是借助于linux内核的Page Cache,来高效换粗数据
    • page cache
      • linux系统总会把还没被应用使用的内存挪来给page cache使用
      • page cache中,每个文件是一个Radix树(基树),节点由4K大小的Page组成,可以通过文件的偏移量快速定位Page
      • 当写操作发生时,将数据直接写入page cache中,并将该页置dirty标志
      • 当读操作发生时,会首先在page cache中查找,如果有就直接返回,如果没有就从磁盘里读入page cache中,然后再读取数据
      • 因此只要生产者与消费者的速度相差不大,且内存足够,消费者会直接读取之前生产者写入page cacha中的数据,大家在内存中完成接力,根本没有磁盘访问,(因此也就没有其他同类软件的要同时维护内存中数据和持久化数据的烦恼),因此能保证较快的IO吞吐
    • 既然操作系统有page cache,为什么应用还要引入应用缓存?
      • page cache是针对文件系统,特点是顺序和4K,但是应用层的缓存大多缓存的是红箭结果,是经过算或裁剪组合后的,所以这是操作系统不知业务应用,提供的方法论级别的设计
    • kafka 使用 page cache还有另外一个好处,就是page cache不需要GC,hi操作系统级别的缓存,即使kafka重启了,page cache的缓存依然还在,相应的操作系统的crash,那些还没被真正写入磁盘的数据会丢失,真正写盘的是内核的flusher线程,由OS管理。这也说明,想高效实用kafka的话,单机部署server端,调整做系统的page cache相关参数是可以调优的
    • kafka消息的写入,写入会在log文件的尾部添加,文件的写入是利用的操作系统的page缓存的批量刷盘,所以kafka服务器的操作系统底层要支持,这是kafka吞吐量高的原因之一,写入文件还有两个参数,消息达到指定数目M,时间超时S秒,这是broker端的控制
    • https://www.linuxidc.com/Linux/2015-05/117022.htm
  • Zero-Copy
    • 采用linux Zero-Copy提高发送性能。传统的数据发送需要发送4次上下文切换,采用sendfile系统调用之后,数据直接在内核态交换,系统上下文切换减少为2次。根据测试结果,可以提高60%的数据发送性能。Zero-Copy详细的技术细节可以参考
  • O(1) 存取
    • 数据在磁盘上存取代价为O(1)。kafka以topic来进行消息管理,每个topic包含多个part(ition),每个part对应一个逻辑log,有多个segment组成。每个segment中存储多条消息(见下图),消息id由其逻辑位置决定,即从消息id可直接定位到消息的存储位置,避免id到位置的额外映射。每个part在内存中对应一个index,记录每个segment中的第一条消息偏移。发布者发到某个topic的消息会被均匀的分布到多个part上(随机或根据用户指定的回调函数进行分布),broker收到发布消息往对应part的最后一个segment上添加该消息,当某个segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息订阅者才能订阅到,segment达到一定的大小后将不会再往该segment写数据,broker会创建新的segment
  • 显式分布式
    • 即所有的producer、broker和consumer都会有多个,均为分布式的。Producer和broker之间没有负载均衡机制。broker和consumer之间利用zookeeper进行负载均衡。所有broker和consumer都会在zookeeper中进行注册,且zookeeper会保存他们的一些元数据信息。如果某个broker和consumer发生了变化,所有其他的broker和consumer都会得到通知

应用场景

  • 消息队列
    • 比起大多数的消息系统来说,Kafka有更好的吞吐量,内置的分区,冗余及容错性,这让Kafka成为了一个很好的大规模消息处理应用的解决方案。消息系统一般吞吐量相对较低,但是需要更小的端到端延时,并常常依赖于Kafka提供的强大的持久性保障。在这个领域,Kafka足以媲美传统消息系统,如ActiveMR或RabbitMQ
  • 行为跟踪
    • Kafka的另一个应用场景是跟踪用户浏览页面、搜索及其他行为,以发布-订阅的模式实时记录到对应的topic里。那么这些结果被订阅者拿到后,就可以做进一步的实时处理,或实时监控,或放到hadoop/离线数据仓库里处理
  • 元信息监控
    • 作为操作记录的监控模块来使用,即汇集记录一些操作信息,可以理解为运维性质的数据监控吧
  • 日志收集
    • 日志收集方面,其实开源产品有很多,包括Scribe、Apache Flume。很多人使用Kafka代替日志聚合(log aggregation)。日志聚合一般来说是从服务器上收集日志文件,然后放到一个集中的位置(文件服务器或HDFS)进行处理。然而Kafka忽略掉文件的细节,将其更清晰地抽象成一个个日志或事件的消息流。这就让Kafka处理过程延迟更低,更容易支持多数据源和分布式数据处理。比起以日志为中心的系统比如Scribe或者Flume来说,Kafka提供同样高效的性能和因为复制导致的更高的耐用性保证,以及更低的端到端延迟。
  • 流处理
    • 这个场景可能比较多,也很好理解。保存收集流数据,以提供之后对接的Storm或其他流式计算框架进行处理。很多用户会将那些从原始topic来的数据进行阶段性处理,汇总,扩充或者以其他的方式转换到新的topic下再继续后面的处理。例如一个文章推荐的处理流程,可能是先从RSS数据源中抓取文章的内容,然后将其丢入一个叫做“文章”的topic中;后续操作可能是需要对这个内容进行清理,比如回复正常数据或者删除重复数据,最后再将内容匹配的结果返还给用户。这就在一个独立的topic之外,产生了一系列的实时数据处理的流程。Strom和Samza是非常著名的实现这种类型数据转换的框架
  • 事件源
    • 事件源是一种应用程序设计的方式,该方式的状态转移被记录为按时间顺序排序的记录序列。Kafka可以存储大量的日志数据,这使得它成为一个对这种方式的应用来说绝佳的后台。比如动态汇总(News feed)
  • 持久性日志(commit log)
    • Kafka可以为一种外部的持久性日志的分布式系统提供服务。这种日志可以在节点间备份数据,并为故障节点数据回复提供一种重新同步的机制。Kafka中日志压缩功能为这种用法提供了条件。在这种用法中,Kafka类似于Apache BookKeeper项目
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值