flink 根据时间消费kafka
经常遇到这样的场景,13点-14点的时候flink程序发生了故障,或者集群崩溃,导致实时程序挂掉1小时,程序恢复的时候想把程序倒回13点或者更前,重新消费kafka中的数据.
下面的代码就是根据指定时间戳(也可以换算成时间)开始消费数据,支持到这样就灵活了,可以在启动命令中加个参数,然后再配个守护程序来控制程序.
flink代码
import java.util.Properties
import org.apache.flink.streaming.api.scala._
import org.apache.flink.streaming.connectors.kafka.FlinkKafkaConsumer010
import org.apache.flink.streaming.connectors.kafka.internals.KafkaTopicPartition
import org.cdp.kafka.KafkaOffsetFind
object flinkkafka1 {
def main(args: Array[String]): Unit = {
/** ***************************************************************************************************************
* kafka info
*/
val zkCluster = "localhost:2181"
val kafkaCluster = "localhost:9092"
val topic = "cdp20"
val timestamp = 1519804800000L
/** ***************************************************************************************************************
* flink env
*/
val env = StreamExecutionEnvironment.getExecutionEnvironment
/** ***************************************************************************************************************
* create kafka stream
*/
val props = new Properties()
props.setProperty("bootstrap.servers", kafkaCluster)
props.setProperty("zookeeper.connect", zkCluster)
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
props.setProperty("group.id", "cdp20-c1")
/* ***********************************************************************************************************
* stream
*/
//找到时间戳对应偏移量
val offsetFinder = new KafkaOffsetFind[String]
val offset = offsetFinder.useTimestamp(timestamp,topic,props)
print(offset)
val kafkaOffsets = new java.util.HashMap[KafkaTopicPartition, java.lang.Long]
for (o <- offset) {
kafkaOffsets.put(new KafkaTopicPartition(topic, o._1), o._2)
}
//创建根据时间消费kafka的数据流
val kafkaTime = env
.addSource {
new FlinkKafkaConsumer010[String](topic,
new KeyedDeserializationSchemaWithKey(new DefaultStringDeserializer),
props)
.setStartFromSpecificOffsets(kafkaOffsets)
}
/** ***************************************************************************************************************
* exec
*/
kafkaTime.print()
/** ***************************************************************************************************************
* flink execute
*/
env.execute("flink-kafka")
}
}
kafka根据时间找偏移量代码
import java.util
import java.util.Properties
import org.apache.kafka.clients.consumer.KafkaConsumer
import org.apache.kafka.common.TopicPartition
import scala.collection.JavaConverters._
/* ***********************************************************************************************************
* 作者:陈大炮
* 时间:2018-02-28
* 内容:根据时间消费kafka
* 使用unix时间戳,查找kafka分区对应的偏移量
*/
class KafkaOffsetFind[T] {
//超时时间
val POLL_TIMEOUT = 2000
//使用时间查询
def useTimestamp(timestamp: Long, topic: String, kafkaProps: Properties): List[(Int, Long)] = {
//创建消费者,获得消费者分区
val consumer = createConsumer(kafkaProps)
consumer.subscribe(util.Arrays.asList(topic))
consumer.poll(POLL_TIMEOUT)
val partitions = consumer.assignment().asScala.toList
//拼出一个查询map
val findMap = new util.HashMap[TopicPartition, java.lang.Long]
partitions
.foreach {
c =>
findMap.put(new TopicPartition(topic, c.partition()), timestamp)
}
//使用查询map去获得偏移量
val offsetMap = consumer.offsetsForTimes(findMap)
//返回前关闭下消费者
consumer.close()
//返回分区号和对应的偏移量
partitions.map {
p =>
(p.partition(), offsetMap.get(new TopicPartition(topic, 0)).offset())
}
}
//创建消费者
protected def createConsumer(kafkaProps: Properties): KafkaConsumer[String, T] = {
val props = kafkaProps.clone().asInstanceOf[Properties]
props.put("enable.auto.commit", "false")
props.put("key.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
props.put("value.deserializer", "org.apache.kafka.common.serialization.StringDeserializer")
new KafkaConsumer[String, T](props)
}
}
注意事项(由漂泊的美好提供)
1.使用KafkaConsumer.offsetsForTimes要确认集群已开启log.message.timestamp.type参数
2.client端要使用0.10.*的客户端发送数据,使用低版本会造成数据格式不同问题
参考内容
http://blog.csdn.net/forrest_ou/article/details/78978575
https://github.com/noris-network/KafkaOffsetFinder
flink 根据时间消费kafka的更多相关文章
- Flink(五) 【消费kafka】
目录 0.目的 1.本地测试 2.线上测试 提交作业 0.目的 测试flink消费kafka的几种消费策略 kafkaSource.setStartFromEarliest() //从起始位置 kaf ...
- Flink消费Kafka到HDFS实现及详解
1.概述 最近有同学留言咨询,Flink消费Kafka的一些问题,今天笔者将用一个小案例来为大家介绍如何将Kafka中的数据,通过Flink任务来消费并存储到HDFS上. 2.内容 这里举个消费Kaf ...
- Flink消费Kafka数据并把实时计算的结果导入到Redis
1. 完成的场景 在很多大数据场景下,要求数据形成数据流的形式进行计算和存储.上篇博客介绍了Flink消费Kafka数据实现Wordcount计算,这篇博客需要完成的是将实时计算的结果写到redis. ...
- Flink消费kafka
Flink消费Kafka https://blog.csdn.net/boling_cavalry/article/details/85549434 https://www.cnblogs.com/s ...
- Spark Streaming消费Kafka Direct方式数据零丢失实现
使用场景 Spark Streaming实时消费kafka数据的时候,程序停止或者Kafka节点挂掉会导致数据丢失,Spark Streaming也没有设置CheckPoint(据说比较鸡肋,虽然可以 ...
- 17-Flink消费Kafka写入Mysql
戳更多文章: 1-Flink入门 2-本地环境搭建&构建第一个Flink应用 3-DataSet API 4-DataSteam API 5-集群部署 6-分布式缓存 7-重启策略 8-Fli ...
- Spark streaming消费Kafka的正确姿势
前言 在游戏项目中,需要对每天千万级的游戏评论信息进行词频统计,在生产者一端,我们将数据按照每天的拉取时间存入了Kafka当中,而在消费者一端,我们利用了spark streaming从kafka中不 ...
- 《从0到1学习Flink》—— Flink 写入数据到 Kafka
前言 之前文章 <从0到1学习Flink>-- Flink 写入数据到 ElasticSearch 写了如何将 Kafka 中的数据存储到 ElasticSearch 中,里面其实就已经用 ...
- Spark Streaming消费Kafka Direct保存offset到Redis,实现数据零丢失和exactly once
一.概述 上次写这篇文章文章的时候,Spark还是1.x,kafka还是0.8x版本,转眼间spark到了2.x,kafka也到了2.x,存储offset的方式也发生了改变,笔者根据上篇文章和网上文章 ...
随机推荐
- C# 数据类型转换 显式转型、隐式转型、强制转型
C# 的类型转换有 显式转型 和 隐式转型 两种方式. 显式转型:有可能引发异常.精确度丢失及其他问题的转换方式.需要使用手段进行转换操作. 隐式转型:不会改变原有数据精确度.引发异常,不会发生任何问 ...
- 4.GlusterFS 常见故障处理
一般硬盘也要备用几块,因为随着发展,可能这些型号的硬盘不好买到了,一般的事故不会在开始一两年出,在硬件老化的时候出故障的频率高. 4.1 硬盘故障 如果底层做了 RAID 配置,有硬件故障,直接更换硬 ...
- ios 性能优化概述
在开发IOS程序的时候,不止是简简单单的把代码堆砌起来,或者说有一个比较好的架构,程序就ok的.还需要在程序性能上进行优化.所谓优化,并非只是简单的优化几个算法,让程序看起来跑的更快.优化是有目标的, ...
- Java自带线程池和队列详解
Java线程池使用说明 一简介 线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后 ...
- 查看linux上面是否有安装redis,redis启动
1.检测是否有安装redis-cli和redis-server; [root@localhost bin]# whereis redis-cli redis-cli: /usr/bin/redis-c ...
- oracle exp 无法导出空表
oracle exp 无法导出空表 select 'alter table '|| a.table_name ||' allocate extent;' from user_tables a wh ...
- java BigDecimal解析及注意事项
BigDecimal简介 JDK文档(中文)中的解释如下: 不可变的.任意精度的有符号十进制数.BigDecimal 由任意精度的整数非标度值 和 32 位的整数标度 (scale) 组成.如果为零或 ...
- virtualbox+vagrant学习-4-Vagrantfile-7-WinRM Settings
WinRM Settings 配置命名空间config.winrm config.winrm配置与如何通过winrm配置vagrant访问你的Windows客户相关.与大多数vagrant设置一样,默 ...
- coco定义的小物体中物体大物体的尺寸
http://cocodataset.org/#detection-leaderboard
- SDOI2018 二轮培训划水记
\(\mathcal{Day -1}\) 嗯,虽然说\(rqy\)看我们这么懵O,并不建议我们去掺和这种神仙打架,但是为了逃文化课学习OI并参观膜拜各路神仙,我毅然决然地选择去参加这次培训-- 这次一 ...