Jac*_*cob 5 queue cql cassandra cql3
是否可以在cassandra中使用一个表作为队列,我不认为我在mysql中使用的策略是有效的,即给定此表:
create table message_queue(id integer, message varchar(4000), retries int, sending boolean);
Run Code Online (Sandbox Code Playgroud)
我们有一个事务将行标记为"发送",尝试发送,然后删除该行,或增加重试次数.该事务确保在任何时候只有一个服务器将尝试从message_queue处理项目.
有一篇关于数据共享的文章描述了陷阱以及如何绕过它,但是我不确定周围有很多墓碑的影响是什么,它们需要多长时间?
The*_*heo 17
不要这样做.除非你非常非常小心,否则Cassandra作为队列后端是一个糟糕的选择.您可以在Jonathan Ellis博客文章"Cassandra反模式:队列和类似队列的数据集"(可能是您提到的帖子)中阅读更多原因.MySQL也不是支持队列的绝佳选择,我们是像RabbitMQ这样的真正的队列产品,它非常好用且非常容易使用.
使用Cassandra作为队列存储的问题是:每次删除消息时,都要为该消息编写逻辑删除.每当您查询下一条消息时,Cassandra将不得不浏览这些墓碑并删除消息并尝试确定少数尚未删除的消息.对于任何类型的吞吐量,读取值的数量与实际实时消息的数量将是数十万比一.
调整GC宽限和其他参数将无济于事,因为这仅适用于压缩后墓碑会在多长时间内停留,即使您专注于CPU仅运行压缩,您仍然会死于数万或更多的生活口粮.在某些情况下,即使有一个GC优雅的零墓碑也会在压缩之后徘徊.
有一些方法可以减轻这些影响,Jonathan的帖子中概述了这些,但这里有一个摘要(我不写这个来鼓励你使用Cassandra作为队列后端,但是因为它解释了更多关于Cassandra的工作,并应该帮助你理解为什么它不适合这个问题):
为了避免使用墓碑问题,你不能继续使用同一个队列,因为它会比拼写更快地填充用于墓碑的upp,并且你的性能将直接进入砖墙.如果向主键添加一个确定性且依赖于时间的列可以避免一些性能问题,因为较少的逻辑删除有时间构建,Cassandra将能够完全删除旧行及其所有逻辑删除.
每个队列使用一行也会创建一个热点.单个节点必须处理该队列,其余节点将处于空闲状态.你可能有很多队列,但很有可能其中一个会看到比其他队列更多的流量,这意味着你得到一个热点.通过向主键添加第二列,在多个节点上对队列进行分片.它可以是消息的哈希值(例如,crc32(message) % 60将创建60个分片,不要使用太小的数字).当您想要查找从所有分片中读取的下一条消息并选择其中一条结果时,忽略其他分片.理想情况下,您会找到一种方法将其与依赖于时间的内容相结合,以便您在处理此问题时也可以解决该问题.
如果您在到达时间之后对消息进行排序(例如使用TIMEUUID群集密钥)并且可以以某种方式跟踪已传递的最新消息,则可以执行查询以查找该消息之后的所有消息.这意味着Cassandra的墓碑会越来越少,但它并不是灵丹妙药.
然后是确认问题.我不确定它们对你是否重要,但看起来你的架构中有某种锁定机制(我正在考虑retries和sending列).这不行.在Cassandra 2.0及其比较和交换功能之前,没有办法使其正常工作.要实现锁定,您需要读取列的值,检查它是否未锁定,然后写入它现在应该被锁定.即使具有一致性级别,ALL另一个应用程序节点也可以同时执行相同的操作,并且最终都认为它们锁定了消息.使用Cassandra 2.0中的CAS,可以原子地进行,但代价是性能.
在StackOverflow上有关于Cassandra和队列的更多答案,请阅读它们(从这开始:带有大量写入的表和Cassandra中的一些读取.主键搜索需要30秒.
| 归档时间: |
|
| 查看次数: |
4348 次 |
| 最近记录: |