Kafka整合Spark Streaming之Direct模式

Kafka整合Spark Streaming之Direct模式

Kafka整合Spark Streaming的两种模式:Receiver模式Direct直连模式。现在在生产中,一般都会选择Direct直连模式来进行Kafka和Spark Streaming的整合,而在生产中,遇到最多的两个问题就是丢数据和重复读的问题。本篇将重点介绍Direct模式,讲述Direct模式的原理,以及Direct模式存在的问题和相关的解决办法。

1. 原理

Kafka整合Spark Streaming之Direct模式

任务执行中直接开启和Kafka partition数相等的tasks去拉取Kafka partition中的数据,整个过程partition和task是一一对应的关系。即一个task拉取Kafka中一个partition中的数据。

思考:怎么知道开启多少个task?

通过zk可以知道。从zk的/brokers/topics/topic_n/partitions/xxx中可以得知这个topic的partition的个数。

需要注意:

  • Kafka不维护消费者的偏移,由Spark自己维护,自己去实现 offset持久化(一般会记录在Zookeeper和Redis中)

    Spark task的偏移是放在内存中的,没有记录在Zookeeper中。所以如果Spark任务一旦挂掉,就要从头开始消费。所以要想用直连模式,就一定要自己写代码去维护这个位置信息。将位置信息写入到一个地方,可以是Zookeeper,Redis或HDFS。这样,一旦Spark任务挂掉,重新开启一个task,这个task先从Zookeeper中读取偏移,然后从Kafka中该偏移的位置开始读,就能避免上述问题。

  • offset持久化方式的选取

    • Zookeeper
      如果和Zookeeper交互频率不是特别高,一秒或两秒,用Zookeeper这样是没有什么问题的。
    • Redis
      如果在Zookeeper中交互频繁的话会对Zookeeper产生压力,存在Redis中可以避免这个问题。但是存Redis同样会存在其他问题,比如Redis有持久化和单点故障的问题。

2. 直连模式的优点

  • 简化数据处理流程。
  • 不用接收数据,自己去Kafka中拉取,获取数据*,Kafka相当于我们的备份数据,任务失败可以自己重新到Kafka中去拉取。

3. 直连模式的问题

Kafka整合Spark Streaming之Direct模式

  • 丢数据问题

    • 先写入Zookeeper可能会数据丢失,如果允许数据丢失的话,可以用这种方案。At most once(最多一次)

    • 模拟丢数据问题

      ① 每个partition中分别读取50条到Spark Streaming中

      ② Spark Streaming的偏移变为150,先将150的偏移写入Zookeeper

      ③ 在Spark Streaming中进行一些业务处理,处理一半挂掉了(这时ES中还没写入数据)

      ④ 当再次启动一个任务时重新读取时,从ZK中取到偏移为150,那么就从150之后开始读数据,但ES中0-150的数据还没有,即产生丢数据问题。

  • 重复读问题

    • 等数据全部处理成功之后再后写入zk可能会重复读取。At least once(最少一次消费)

    • 模拟重复读问题

      ① 每个partition中分别读取50条到Spark Streaming中

      ② 在Spark Streaming中进行一些业务处理,处理一半挂掉了(这时ES中写入了一半的数据,0-75已写入),但未记入ZK

      ③ 当再次启动一个任务时重新读取时,从ZK中取到偏移为0,那么就从头开始读数据,但ES中0-75的数据已经存在了,即产生重复读数据的问题。

    • 解决重复读问题:用幂等解决