Kafka整合Spark Streaming之Direct模式
Kafka整合Spark Streaming之Direct模式
Kafka整合Spark Streaming的两种模式:Receiver模式和Direct直连模式。现在在生产中,一般都会选择Direct直连模式来进行Kafka和Spark Streaming的整合,而在生产中,遇到最多的两个问题就是丢数据和重复读的问题。本篇将重点介绍Direct模式,讲述Direct模式的原理,以及Direct模式存在的问题和相关的解决办法。
1. 原理
任务执行中直接开启和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有持久化和单点故障的问题。
-
Zookeeper
2. 直连模式的优点
- 简化数据处理流程。
- 不用接收数据,自己去Kafka中拉取,获取数据*,Kafka相当于我们的备份数据,任务失败可以自己重新到Kafka中去拉取。
3. 直连模式的问题
-
丢数据问题
-
先写入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的数据已经存在了,即产生重复读数据的问题。
-
解决重复读问题:用幂等解决
-