Apache kafka 卡夫卡时差最后两条记录,KSQL还是其他?
所以我在评估卡夫卡。在我们的用例中,必须创建包含从一个事件到下一个事件的“时间流逝”的新主题,本质上是因为传感器会向卡夫卡报告“开”或“关”。因此,有了时间戳、传感器名称和状态,就可以创建持续时间为“开”和“关”状态的新主题Apache kafka 卡夫卡时差最后两条记录,KSQL还是其他?,apache-kafka,apache-kafka-streams,ksqldb,Apache Kafka,Apache Kafka Streams,Ksqldb,所以我在评估卡夫卡。在我们的用例中,必须创建包含从一个事件到下一个事件的“时间流逝”的新主题,本质上是因为传感器会向卡夫卡报告“开”或“关”。因此,有了时间戳、传感器名称和状态,就可以创建持续时间为“开”和“关”状态的新主题 这在KSQL中可行吗?如何实现 还是真的应该让消费者或流处理器来解决这个问题 我的数据是这样的: { 2019:02:15 00:00:00, sensor1, off} { 2019:02:15 00:00:30, sensor1, on} 结果 { 2019:02:
{ 2019:02:15 00:00:00, sensor1, off}
{ 2019:02:15 00:00:30, sensor1, on}
结果
{ 2019:02:15 00:30:00, sensor1, off, 30sec }.
基本上必须组合多个传感器的状态,以确定机器的组合状态。工厂里有成百上千个传感器这在卡夫卡流中非常容易,所以我会选择2个 首先,您必须正确地为输入数据建模。您的示例使用本地时间,这使得无法计算两个时间戳之间的持续时间。喜欢 从源数据模型开始,如
接口传感器状态{
字符串getId();
即时获取时间();
State getState();
枚举状态{
关
在…上
}
}
以及
接口传感器状态与持续时间x{
SensorState getEvent();
Duration getDuration();
}
现在您已经定义了输入和输出流(但请参见“”),只需通过定义一个变量来转换值(“”)
它必须做两件事:
class DurationProcessor实现ValueTransformer{
键值存储;
@抑制警告(“未选中”)
公共void init(ProcessorContext上下文){
this.store=(KeyValueStore)context.getStateStore(“SensorStates”);
}
具有持续时间转换的公共SensorState(SensorState SensorState){
//无事可做
如果(sensorState==null){
返回null;
}
//检查以前的状态,必要时更新
var oldState=checkAndUpdateSensorState(sensorState);
//当我们有历史数据时,返回到目前为止的持续时间。否则返回null
返回oldState.map(state->addDuration(state,sensorState)).orElse(null);
}
公共void close(){}
/**
*根据传感器ID检查状态存储的历史状态,必要时进行更新。
*
*@param sensorState新传感器状态
*@返回旧的传感器状态
*/
可选检查和更新传感器状态(传感器状态传感器状态){
//传感器ID是我们的索引
var index=sensorState.getId();
//获取历史状态(可能为空)
var oldState=store.get(索引);
if(NEETOTUPDATE(旧状态、传感器状态)){
//将状态存储更新为新状态
store.put(索引、传感器状态);
}
返回可选的。不可用的(oldState);
}
/**
*检查是否需要更新状态存储中的状态。
*
*要么我们没有历史数据,要么国家发生了变化。
*
*@param oldState旧传感器状态
*@param sensorState新传感器状态
*@return标志是否需要更新
*/
布尔值neetToUpdate(传感器状态oldState、传感器状态SensorState){
返回oldState==null | | oldState.getState()!=sensorState.getState();
}
/**
*用持续时间包装旧状态,并记录其持续时间。
*
*@param oldState到目前为止传感器的状态
*@param sensorState传感器的新状态
*@return-Wrapped旧状态,持续时间
*/
SensorState WithDuration addDuration(SensorState oldState、SensorState SensorState){
var duration=duration.between(oldState.getTime(),sensorState.getTime());
返回SensorStateWithDuration.builder().setEvent(oldState).setDuration(duration.build());
}
}
以简单的方式将所有内容组合在一起(“”):
var builder=newstreamsbuilder();
//我们的国营商店
var存储生成器=
Stores.keyValueStoreBuilder(
Stores.persistentKeyValueStore(“传感器状态”),
Serdes.String(),
storeSerde);
//注册商店建设者
builder.addStateStore(storeBuilder);
stream(“输入主题”,consumered.with(Serdes.String(),inputSerde))
.transformValues(DurationProcessor::新建,DurationProcessor.SENSOR_状态)
.to(“结果主题”,生成的.with(Serdes.String(),resultSerde));
var topology=builder.build();
完整的应用程序位于。继使用自连接的想法之后,我提出了以下解决方案:
#卡夫卡主题--引导服务器localhost:9092--删除--主题诱惑测试
echo“{”temp:3.0,“counter:1}”| kafkacat-b localhost-t test
echo“{”temp:4.0,“counter:2}”| kafkacat-b localhost-t test
echo“{”temp:6.0,“counter:3}”| kafkacat-b localhost-t test
echo“{”temp:3.0,“counter:4}”| kafkacat-b localhost-t test
echo“{”temp:3.1,“counter:6}”| kafkacat-b localhost-t test
echo“{”temp:3.1,“counter:5}”| kafkacat-b localhost-t test
这里我们假设连续事件已经具有计数器属性。这样的计数器也可以通过简单地聚合一段时间内的事件计数与ksql一起添加
——将主题导入到ksql中
使用(kafka_topic='tellest',value_format='json',KEY='counter')创建流temp_json(ingesttime BIGINT,row VARCHAR,temp DOUBLE,counter INTEGER);
---将格式更改为avro并重新分区
创建流temp,使用(VALUE_FORMAT='AVRO')作为选择temp、counter、CAST(counter作为VARCHAR)作为计数器键,从temp_json分区按计数器键创建;
---使用移位计数器创建第二个流
创建流temp\u shift作为SELECT temp,counter作为counter\u orig,counter+1作为temp分区中的计数器;
--加入b组
ksql> SELECT * FROM temp_diff LIMIT 4;
1574321370281 | 1 | null | 3.0 | null | 1
1574321372307 | 2 | -1.0 | 4.0 | 3.0 | 2
1574321372319 | 3 | -2.0 | 6.0 | 4.0 | 3
1574321372331 | 4 | 3.0 | 3.0 | 6.0 | 4