游龙战神|「事件驱动架构」何时使用RabbitMQ或 Kafka?( 三 )


Kafka为分区中的每条消息维护一个偏移量 。 提交的位置是保存的最后一个偏移量 。 如果进程失败并重新启动 , 这是它将恢复到的偏移量吗?Kafka中的使用者既可以定期地自动提交偏移量 , 也可以选择手动控制提交的位置 。
在不同版本的Apache Kafka中 , Kafka是如何记录哪些被使用了 , 哪些没有被使用的 。 在早期版本中 , 使用者跟踪偏移量 。
当RabbitMQ客户端不能处理消息时 , 它也可以nack(否定确认)消息 。 消息将被返回到它来自的队列中 , 就像它是一个新消息一样;这在客户端出现临时故障时非常有用 。
如何处理队列?RabbitMQ的队列在空的时候是最快的 , 而Kafka被设计用来保存和分发大量的消息 。 Kafka用很少的开销保留大量的数据 。
尝试RabbitMQ的人可能没有意识到惰性队列的特性 。 惰性队列是将消息自动存储到磁盘的队列 , 从而最大限度地减少RAM的使用 , 但延长了吞吐量时间 。 根据我们的经验 , 惰性队列创建了更稳定的集群 , 具有更好的预测性能 。 如果你要一次发送很多消息(例如处理批处理任务) , 或者你认为你的用户跟不上发布者的速度 , 我们建议你启用惰性队列 。
扩展扩展是指增加或减少系统容量的过程 。 RabbitMQ和Kafka可以以不同的方式伸缩 , 你可以调整消费者的数量 , 代理的能力或者向系统中添加更多的节点 。
消费者扩展如果发布速度更快 , 那么就可以使用RabbitMQ , 那么队列将开始增长 , 最终可能会产生数百万条消息 , 最终导致RabbitMQ耗尽内存 。 在这种情况下 , 您可以扩展处理(消费)您的消息的消费者数量 。 RabbitMQ中的每个队列可以有许多使用者 , 而这些使用者都可以“竞争”使用来自队列的消息 。 消息处理分布在所有活动的使用者中 , 因此在RabbitMQ中通过简单地添加和删除使用者就可以实现上下伸缩 。
在Kafka中 , 分配使用者的方法是使用主题分区 , 其中组中的每个使用者专用于一个或多个分区 。 您可以使用分区机制按业务键(例如 , 按用户id、位置等)向每个分区发送不同的消息集 。
扩展代理我在stackoverflow的回答中写道;“Kafka是基于水平扩展(添加更多机器)的想法而建立的 , 而RabbitMQ主要是为垂直扩展(添加更多功能)而设计的 。 ”答案的这一部分是提供有关运行Kafka或RabbitMQ的机器的信息 。
在RabbitMQ中 , 水平伸缩并不总是提供更好的性能 。 通过垂直扩展(添加更多Power)可以获得最佳性能级别 。 在RabbitMQ中可以进行水平伸缩 , 但这意味着必须在节点之间建立集群 , 这可能会降低设置的速度 。
在Kafka中 , 您可以通过向集群添加更多节点或向主题添加更多分区来扩展 。 这有时比像在RabbitMQ中那样在现有的机器中添加CPU或内存更容易 。
许多人和博客 , 包括Confluent , 都在谈论Kafka在缩放方面有多棒 。 当然 , 卡夫卡可以比RabbitMQ扩展得更远 , 因为对于你能买到的机器的强度总是有限制的 。 但是 , 在这种情况下 , 我们需要记住使用代理的原因 。 你可能有一个Kafka和RabbitMQ都可以支持的消息量 , 而没有任何问题 , 我们大多数人不会处理RabbitMQ耗尽空间的规模 。
日志压缩值得一提的是 , 在Apache Kafka中 , RabbitMQ中不存在的一个特性是日志压缩策略 。 日志压缩确保Kafka始终保留单个主题分区队列中每个消息键的最后已知值 。 Kafka只是简单地保留消息的最新版本 , 并用相同的密钥删除旧版本 。
日志压缩可以看作是使用Kafka作为数据库的一种方式 。 您可以将保留期设置为“永久” , 或者对某个主题启用日志压缩 , 这样数据就会永久存储 。
使用日志压缩的一个示例是 , 在数千个正在运行的集群中显示一个集群的最新状态 。 我们存储最终状态 , 而不是存储集群是否一直在响应 。 可以立即获得最新信息 , 比如队列中当前有多少条消息 。