我试图围绕我最近遇到的一个问题,我希望有人能够将我指向解决方案的最合理方向。
我正在使用RIAK KV商店并从事CRDT数据,在该数据中,我在数据库中存储的每个CRDT项目中都有某种计数器。
我有一个兔子队列,其中每条消息都是增加或减少一定数量上述计数器的请求。
最后,我有一组服务工人,可以在队列上倾听,并且对于每个请求,请尝试相应地更改计数器数量。
我遇到的问题如下:虽然一个工人正在处理请求,但它可能会在数据库的写操作上陷入困境 - 假设三个计数器的第二个更改中的三个。它与RabbitMQ的联系丢失(超时),因此消息引用重回队列(我负担不起一个)。然后由第二个工人捡起,这开始了所有处理。但是,第一个工人完成了其工作,结果我已经处理了两次消息。
我可以将这些增量分为单个动作,但这仍然使我陷入困境 - 如果某些工人长时间陷入了写作操作,仍然可以两次更改计数器的价值。
我没有可能使Riak KV CRDT写作更快的速度,我也不能接受错过消息引用。我需要实施一些以前是否已经处理过请求的方法。我最初的想法是使用一些替代,快速的KV商店来存储RabbitMQ消息ID,如果它们正在处理。这样,其他工人可以判断他们是否没有开始处理已经在其他地方解析的消息。我可以对我可以阅读的材料使用任何帮助和指针。
您不能完全具有"一个传递"语义。您可以减少双重消息或错过的交货,因此决定哪种行为不便是最不便的。
首先,您确定CRDT太慢了吗?您是否在地图中使用简单的计数器或计数器?根据我的经验,它们的速度非常快,尽管比KV慢。您可以尝试: - 具有简单的crdt(无地图)和更多的crdt对象,以降低压力(您可以将计数器分成两分吗?) - 不使用CRDT,而是在客户端使用良好的旧同胞分辨率,以简单的密钥/值使用。 - 累积计数更新订单并批量应用它们,但是随后您接受延迟的增加,因此等同于增加超时。
您可以提供一些指标吗?就像更新需要多长时间,您期望什么数字,如果您的更新很少或更新等等,等等