仓库位置
日志生成:https://github.com/SmallScorpion/gmall-mock.git
日志服务器:https://github.com/SmallScorpion/gmall-spark-ch-es-realtime.git
手动提交偏移量
- 第一次读取会加载Redis数据,若是redis中没有数据那么将消费kafka起始数据,经过业务计算保存到redis中
- 中间循环过程是业务到redis保存数据的过程
- 若中途宕机,重启进程服务都会读取redis偏移量位置进行消费
OffsetManager
/**
* 把偏移量写入redis
* @param topicName
* @param groupId
* @param offsetRanges
*/
def saveOffset( topicName: String, groupId: String, offsetRanges: Array[OffsetRange] ): Unit = {
val offsetKey = "offset:" + topicName + ":" + groupId
// 转换结构 -> map
val offsetMap: util.Map[String, String] = new util.HashMap()
for (elem <- offsetRanges) {
val partition: Int = elem.partition
val untilOffset: Long = elem.untilOffset
offsetMap.put( partition + "", untilOffset + "" )
println( "写入分区:" + partition + ":" + elem.fromOffset + "--->" + elem.untilOffset )
}
// 写入redis
if( offsetMap != null && offsetMap.size() > 0){
val jedis: Jedis = RedisUtil.getJedisClient
jedis.hmset( offsetKey, offsetMap)
jedis.close()
}
}
业务代码
// 得到本批次的偏移量的结束位置,用于更新redis中的偏移量
var OffsetRanges: Array[OffsetRange] = Array.empty[OffsetRange]
val InputGetOffsetDstream: DStream[ConsumerRecord[String, String]] =
recordInputStream.transform { rdd =>
// driver 执行
OffsetRanges = rdd.asInstanceOf[HasOffsetRanges].offsetRanges
rdd
}
......
......
// TODO 提交偏移量
OffsetManager.saveOffset( topic, groupId, OffsetRanges )