Apache Kafka(一)- Kakfa 简介与术语

Apache Kafka

1. Kafka简介、优势、以及使用场景

Kafka的优势:

  1. 开源
  2. 分布式,弹性架构,fault tolerant
  3. 水平扩展:
    1. 可以扩展到100个brokers
    2. 可以扩展到每秒百万级条消息
    3. 高性能(延迟少于10ms)-- 实时

 

使用场景:

  1. 消息系统
  2. 活动追踪(Activity Tracking)
  3. 从各个不同的地点收集指标信息(IOT)
  4. 应用日志收集
  5. 流处理(使用Kafka Streams API 或 Spark 等)
  6. 系统依赖之间的解耦
  7. 与Spark,Flink,Storm,Hadoop以及许多其他Big Data技术集成

 

场景举例:

  1. Netflix使用Kafka做实时推荐(比如看节目的同时为你推荐节目)
  2. Uber使用Kafka收集用户,出租车以及路程的实时信息,并据此计算、预测车辆需求,以及计算实时的(加/减)价格
  3. LinkedIn使用Kafka防止spam,收集用户交互信息以做更好的实时connection recommendation

 

2. Kafka术语

2.1. Topics,partitions以及offsets

  • Topics:一个特定的数据流
    • 类似于一个数据库中的一个表(无约束的表)
    • 可以创建任意多个
    • 一个topic由它的名字作为识别
    • Topics被split成partitions
      • 每个partition都是有序的
      • 在一个partition中的每条消息都有一个递增id(incremental id),称为offset(可以增至到无限大)

 

例如:以下是一个Kafka Topic,包含三个Partitions(由创建时指定)。每个partitions中的messages都有一个递增id,即为消息的offset:

 

 

基于上图的Kafka Topic,需要注意以下几点:

  • Offset仅对一个特定的partition有意义
    • 也就是说,在partition 0 中的offset 3 与partition 1 中的 offset 3 并不是同样的消息
    • “有序”仅在partition中有保障(并不能跨paritions)
    • 数据仅被保留一定的时间(默认是一周),但是offset会一直增长
    • 一旦数据被写入到一个partition,它就不会被改变(例如update数据等)(immutability性质)
    • 除非给定了一个key,否则数据被随机的分配到一个partition中

 

2.2. Brokers 与 Topics

那topics 是由什么支持(hold)的呢?答案是brokers。

  • 一个Kafka 集群(cluster)由多个brokers(servers)组成。一个broker对应一个server
  • 每个broker由它的ID(Integer)作为标志符
  • 每个broker包含某些topic partitions。例如,一个topic的多个partitions分布在多个brokers中。
  • 在连接到任何一个broker(称为一个bootstrap broker)上后,客户端既连接到整个集群
  • 一般3个brokers是一个比较好的开始,不过一些大的集群有超过100个brokers

在接下来的例子中,我们会为brokers的id选择从100开始:

 

 

假设我们现在 Topic-A有3个partitions,Topic-B有2个partitions,则partitions的一种分布为:

 

 

 

Kafka会自动将partitions跨集群分布,所以在每个broker上,都会放置Topic-A的一个partition。对于Topic-B,它会任选两个brokers放置它的两个partitions。而若是有一个Topic-C有4个partitions,则其中一个broker会有两个partitions。

 

2.3. Topic Replication

Topic Replication的主要功能是为了防止一个broker宕机后,此broker上的数据仍可以在其他地方被访问。

 

Topic replication factor

Topics应配置一个 > 1的replication factor(一般为2或3),这样在一个broker宕机后,另一个broker可以仍提供这部分数据。下面是一个例子,Topic-A有两个partition,且replication factor配置为2:

 

 

 

假设我们此时丢失了broker 102:

 

 

 

可以看到Broker 101 与 Broker 103 仍可以提供Topic-A的所有partition数据。

 

Partitions中的leader

在topic replication中,任意时刻,对于一个给定的partition:

  • 仅有一个broker可以作为此partition的人leader
  • 仅此leader 可以接收此partition的数据并提供数据
  • 另外的brokers会同步数据

所以每个partition会有一个leader以及多个ISR(in-sync replica),例如:

 

 

 

谁决定leader与ISR?答案是zookeeper。

如果一个broker down,则会发生election(zookeeper)。假设broker 101 宕机,则broker 102 会变为Topic-A 中Parition 0的leader。之后若是broker 101 恢复,则它会在同步数据后再次尝试成为leader。Leader 与 ISR的角色是由zookeeper 决定的。

 

2.4. Producers

  • Producers写数据到(由partitions组成的)topics中
  • Producers可以自动了解到需要向哪个broker和partition写入数据,并不需要指定特定broker
  • 在broker failure时,producers会自动recover

下面是一个Producer例子:

 

 

 

若是未指定message的key,则producer会以轮询的方式向这些Partition写入消息。所以,在producer向kafka写入数据时,是以load balance 的方式写入的。

 

Producers可以选择是否为数据的写入接收ack,有以下几种ack的选项:

  • acks=0:producers不等待ack(可能会造成数据丢失)
  • acks=1:producers会等待leader 的ack(有限数据丢失)
  • acks=all:leader与replicas 的 ack(无数据丢失)

 

Producers: Message keys

  • Producers在发送message时可以选择指定一个key,类型可以为string、number等
  • 如果key=null,则数据以轮询的方式发送(例如broker 101,然后broker 102,然后broker 103)
  • 如果一个key已经被发送,则所有具有相同key的message均会发送到同一个partition中
  • 使用key的基本场景是:对于一个特定的字段,消息需要有序

 

下面举个例子,以truck_id 为key:

 

 

truck_id_123 的数据会一直发送到partition 0(假设)

truck_id_234 的数据会一直发送到 partition 1(假设)

而key的分发是由hash决定的,根据hash值,然后对partitions的数量取模。

 

2.5. Consumers

  • Consumers从一个topic(以topic name作为识别)读数据
  • Consumers知道从哪个broker读数据
  • 在broker failure时,consumers知道如何recover
  • 在每个partition中,数据都是按顺序读取

下面是一个Consumer的示意图:

 

 

 

Consumer Groups

Consumers如何从所有的partition中读取数据?=> Consumer Groups

  • Consumers以consumer groups的方式读取数据
  • 在一个group中,每个consumer从一个独立的partition中读数据
  • 如果consumers的数目超过了partitions数目,则一些consumers会成为inactive

 

下面举个例子,我们有一个Topic-A,它包含3个partitions。如果consumer group 中有两个consumers(consumer-group-application-1),则其中一个consumer会从两个partition中读数据。

如果consumer group中有3个consumers(consumer-group-application-2),则每个consumer均会对应一个partition。如果consumer group中仅有一个consumer,则此consumer会从所有partition中读数据。如下图所示:

 

 

 

需要注意的是:Consumers会自动使用一个GroupCoordinator和一个ConsumerCoordinator,用于将一个consumer分配给一个partition。

 

如果有过多的consumers(比partition数目更多),则一些consumers会成为inactive状态:

 

 

 

2.6. Consumer Offsets

  • Kafka存储offsets,用于表示一个consumer group 已经读取到的位置
  • Committed offsets 存储在一个Kafka的topic中,名为__consumer_offsets
  • 当一个group中的一个consumer已经处理了从Kafka收到的数据后,它会committing the offsets
  • 如果一个consumer died,它可以在之后从committed offsets的地方继续读取数据并处理

 

下图是一个例子:

 

 

 

Delivery semantics for consumers

Consumer 决定何时commit offsets,这里有3中delivery 语义:

  • 最多一次(At most once):
    • 在message被接收后,立即commit offsets
    • 如果成功接收,但是处理失败,则message会丢失(不会再次读取此message并处理)
    • 至少一次(At least once)(优先选项):
      • 在message被应用处理后,再commit offsets
      • 如果处理失败,则message会重新再读取
      • 这个会导致messages的重复处理,需要确保处理逻辑是idempotent(再次处理messages并不会影响系统结果)
      • 精确一次(Exactly once):
        • 可以由Kafka => Kafka 的workflow 实现(使用Kafka Streams API)
        • 对于Kafka => 外部系统的workflow,建议使用idempotent consumer

 

2.7. Kafka Broker Discovery

  • 每个Kafka broker也被称为一个“bootstrap server”
  • 也就是说,仅需要连接到一个broker,即可连接到整个集群
  • 每个broker知道所有brokers,topics,以及partitions的信息(metadata)

 

如下图所示,broker discovery的流程如下:

  1. 客户端连接到一个bootstrap server,并请求metadata
  2. Bootstrap server 会返回所有brokers以及它们的ip地址
  3. 客户端连接需要的brokers

 

 

 

2.8. Zookeeper

  • Zookeeper 管理brokers(维护brokers的一个list)
  • 协助执行partition的leader election
  • Zookeeper向Kafka发送各种changes的提醒消息(例如,新topic,broker dies,broker comes up,delete topics,等等…)
  • Kafka 无法脱离zookeeper 工作
  • Zookeeper一般会有单数个数的servers(3,5,7等)
  • Zookeeper有一个leader(处理写),其余servers为followers(处理读)
  • 在Kafka > v0.10 的版本中,zookeeper不再存储consumer的 offsets

 

下面是一个例子:

不同的brokers可以连接到不同的zookeeper,但是仅有leader zookeeper处理写,follower zookeeper仅处理读。Zookeeper 会向kafka通知集群中的变化(例如新的broker,broker 宕机等)

 

 

 

Kafka Guarantees

Kafka可以保证以下场景:

  • Messages按照它们被发送的顺序添加到一个topic-partition中
  • Consumers按序读取一个topic-partition中的messages
  • 指定replication factor 为N,则producers与consumers可以容忍最多N-1个brokers 宕机。一般指定replication factor 为3:
    • 允许一个broker临时下线做维护
    • 同时也允许另一个broker意外宕机
    • 只要一个topic的partition数目是一定的(没有新的partitions),则同样key的message会永远发送到同一个partition中

 

3. 总结

下面是对Kafka中术语的一个总结,可以对比此图再熟悉一下Kafka中的各个术语:

 

 

posted @ 2019-08-06 17:45  ZacksTang  阅读(686)  评论(1编辑  收藏  举报