Apache kafka KStreams-如何处理一个主题的消息延迟
我有一个基于Spring boot的KStreams应用程序,我在其中跨多个主题连接数据。当一个主题出现延迟时,处理这种情况的最佳做法是什么?我读过诸如和其他的链接 下面是我的示例代码(SpringBoot应用程序),用于生成员工和财务两个主题的模拟数据。员工主题代码如下:Apache kafka KStreams-如何处理一个主题的消息延迟,apache-kafka,apache-kafka-streams,Apache Kafka,Apache Kafka Streams,我有一个基于Spring boot的KStreams应用程序,我在其中跨多个主题连接数据。当一个主题出现延迟时,处理这种情况的最佳做法是什么?我读过诸如和其他的链接 下面是我的示例代码(SpringBoot应用程序),用于生成员工和财务两个主题的模拟数据。员工主题代码如下: private void sendEmpData() { IntStream.range(0, 1).forEach(index -> { EmployeeKey key = new Emplo
private void sendEmpData() {
IntStream.range(0, 1).forEach(index -> {
EmployeeKey key = new EmployeeKey();
key.setEmployeeId(1);
Employee employee = new Employee();
employee.setDepartmentId(1000);
employee.setEmployeeFirstName("John);
employee.setEmployeeId(1);
employee.setEmployeeLastName("Doe");
kafkaTemplateForEmp.send(EMP_TOPIC, key, employee);
});
}
同样,对于财务主题:
private void sendFinanceData() {
IntStream.range(0, 1).forEach(index -> {
FinanceKey key = new FinanceKey();
key.setEmployeeId(1);
key.setDepartmentId(1000);
Finance finance = new Finance();
finance.setDepartmentId(1000);
finance.setEmployeeId(1);
finance.setSalary(2000);
kafkaTemplateForFinance.send(FINANCE_TOPIC, key, finance);
});
}
与这些记录相关联的时间戳类型为时间戳类型。创建\u TIME,我假设它与流中的事件时间相同
我有一个简单的KStreams应用程序,它重新设置财务主题的密钥,使财务流密钥与员工流密钥匹配,然后按如下方式进行连接:
employeeKStream.join(reKeyedStream,
(employee, finance) -> new EmployeeFinance(employee.getEmployeeId(),
employee.getEmployeeFirstName(),
employee.getEmployeeLastName(),
employee.getDepartmentId(),
finance.getSalary(),
finance.getSalaryGrade()),
JoinWindows.of(windowRetentionTimeMs), //30 seconds
Joined.with(
employeeKeySerde,
employeeSerde,
financeSerde)).to(outputTopic, Produced.with(employeeKeySerde, employeeFinanceSerde));
如果具有匹配密钥的记录在finance主题中延迟30秒以上到达,则不会发生加入。任何关于如何解决这一问题的见解都会有所帮助。先谢谢你
附:这些数据是虚构的。如果它与您的部门Id/工资相匹配,这只是巧合。:)
如果具有匹配密钥的记录在finance主题中延迟30秒以上到达,则不会发生加入
默认情况下,Kafka Streams使用24小时的宽限期,因此,即使存在滞后或无序数据,您的连接也应该有效。请注意,卡夫卡中的滞后总是指读取路径
超过30秒后到达财务主题
但是,我认为您并不是真的意味着您有延迟(在您回退读取的意义上),而是您的上游写入被延迟了——在这种情况下,事件时间可能分配不正确:
请注意,在写入卡夫卡主题时,如果您没有明确指定时间戳,则生产者将在调用send()
时分配时间戳,而不是在创建ProducerRecord
实例时分配时间戳。如果要在创建ProducerRecord
时分配时间戳,则需要将要分配的时间戳手动传递到构造函数中(不确定Spring boot是否允许您这样做)
作为替代方案(如果无法显式设置记录时间戳),可以将时间戳嵌入值中(当然,这需要您更改员工
和财务
类。使用Kafka流处理此数据时,您可以在自定义时间戳提取器
中使用以获取自定义时间戳,而不是记录时间戳
如果具有匹配密钥的记录在finance主题中延迟30秒以上到达,则不会发生加入
默认情况下,Kafka Streams使用24小时的宽限期,因此,即使存在滞后或无序数据,您的连接也应该可以工作。请注意,Kafka中的滞后始终指的是读取路径
超过30秒后到达财务主题
但是,我认为您并不是真的意味着您有延迟(在您回退读取的意义上),而是您的上游写入被延迟了——在这种情况下,事件时间可能分配不正确:
请注意,在写入卡夫卡主题时,如果您没有明确指定时间戳,则制作人将在send()时分配时间戳
被调用——而不是在创建ProducerRecord
实例时调用。如果要在创建ProducerRecord
时分配时间戳,则需要手动将要分配的时间戳传递到构造函数中(不确定Spring boot是否允许这样做)
作为替代方案(如果无法显式设置记录时间戳),可以将时间戳嵌入值中(当然,这需要您更改
员工
和财务
类。使用卡夫卡流处理此数据时,您可以在自定义时间戳提取器
中使用,以获取自定义时间戳,而不是记录时间戳。感谢您的回复。这非常有用。感谢您的回复。T他的建议真的很有帮助。