如何解决编年史队列 POC 返回了意外的延迟
我们的一个系统具有使用 Apache Kafka 作为服务总线的微服务架构。 低延迟是一个非常重要的因素,但可靠性和一致性(恰好一次)更为重要。
当我们执行一些负载测试时,我们注意到性能显着下降,所有调查都表明 Kafka 主题的生产者和消费者延迟大幅增加。无论我们更改多少配置或添加更多资源,我们都无法摆脱这些症状。
目前我们的需求是每秒处理 10 个事务 (TPS),负载测试执行 20 TPS,但随着系统的发展和添加更多功能,我们知道我们将达到需要 500TPS 的阶段,因此我们开始担心我们能否通过 Kafka 实现这一目标。
作为概念证明,我尝试切换到我们的一个微服务以使用编年史队列而不是 Kafka 主题。按照 avro 示例从 Chronicle-Queue-Demo git hub repo
开始迁移很容易public class MessageAppender {
private static final String MESSAGES = "/tmp/messages";
private final AvroHelper avroHelper;
private final ExcerptAppender messageAppender;
public MessageAppender() {
avroHelper = new AvroHelper();
messageAppender = SingleChronicleQueueBuilder.binary(MESSAGES).build().acquireAppender();
}
@SneakyThrows
public long append(Message message) {
try (var documentContext = messageAppender.writingDocument()) {
var paymentRecord = avroHelper.getGenericRecord();
paymentRecord.put("id",message.getId());
paymentRecord.put("workflow",message.getWorkflow());
paymentRecord.put("workflowStep",message.getWorkflowStep());
paymentRecord.put("securityClaims",message.getSecurityClaims());
paymentRecord.put("payload",message.getPayload());
paymentRecord.put("headers",message.getHeaders());
paymentRecord.put("status",message.getStatus());
avroHelper.writetoOutputStream(paymentRecord,documentContext.wire().bytes().outputStream());
return messageAppender.lastIndexAppended();
}
}
}
在配置完这个 appender 之后,我们运行了一个循环来向一个编年史队列生成 100_000 条消息。每条消息的大小相同,文件的最终大小为 621MB。处理写入所有消息需要 22 分 20 秒和 613 毫秒(~1341 秒),因此平均约为 75 条消息/秒。
这绝对不是我们所期望的,而且与编年史文档中宣传的延迟相去甚远,这让我相信我的方法不是正确的方法。我承认我们的消息不小,大约 6.36KB/条,但我毫不怀疑将它们存储在数据库中会更快,所以我仍然认为我做得不对。
重要的是我们的消息是一一处理的。
预先感谢您的意见和/或建议。
解决方法
每次手动构建 Avro 对象对我来说似乎有点代码味道。
您能否创建一个预定义的消息 -> avro 序列化程序并使用它来填充队列?
或者,只是为了测试,在循环外创建一个 avro 对象并将该对象多次送入队列。这样你就可以看到瓶颈是建筑物还是排队。
更一般的建议:
也许可以附加一个分析器,看看您是否进行了过多的对象分配。如果他们被提升到更高的世代,这尤其糟糕。
看看它们是你的对象还是 Chronicle Queue 的对象。
您的代码是否使您的 ram 或 cpu(或网络)最大化?
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。