NoSQL作为发布-订阅/多读取器队列的存储?

NoSQL作为发布-订阅/多读取器队列的存储?,nosql,Nosql,正在寻找针对以下问题的存储解决方案,最好具有一些类似NoSQL的速度和可扩展性: 事件。很多,每个事件的数据很少。这就是我们需要储存的东西 没有必要严格遵守事件发生的顺序 最好不要存储每个事件的多个副本(如在每个观察者的单独存储中) 观察员。其中一些(

正在寻找针对以下问题的存储解决方案,最好具有一些类似NoSQL的速度和可扩展性:

  • 事件。很多,每个事件的数据很少。这就是我们需要储存的东西

    • 没有必要严格遵守事件发生的顺序
最好不要存储每个事件的多个副本(如在每个观察者的单独存储中)

  • 观察员。其中一些(<50)需要阅读事件

    • 以自己的速度(拉动模式)

    • 最好使用“获取下一块未读事件”API

    • 每个观察者都需要读取每个事件(最终)

    • 无法保证他们多久会进行一次更改。在读取事件之前,可能需要存储大量事件

在RDBMS中,您可能只需按顺序对事件进行编号,并记住每个观察者的“上次读取否”。在用一些ACID换取速度和可伸缩性的同时,是否可以实现类似的功能


到目前为止,Redis的列表看起来不错——有更好的吗?

我认为Redis列表是一个不错的选择。不过,我会为每个观察者列出一个列表——这样你就可以用RPUSH/LPOP读写O(1),当所有观察者都收到事件时,事件就会自动从系统中消失

只需在每个列表中存储一个事件id,就可以减少每个观察者所需的存储空间,不过您需要为每个事件保留一个计数器,以确定何时可以将其从系统中删除

要使用单个列表实现,请设置一个计数器,该计数器在每次将事件添加到列表头时递增。还为每个客户端设置一个计数器,指示它们接收到的事件数。两者之间的区别是您需要从列表中获取的项目数


这种方法的缺点是,在检查计数器后,可以将新项目添加到列表中。您可以通过从列表的尾部开始计数来解决这个问题,但这是O(N)而不是O(1)。您可以通过修剪列表中接收到的事件并为尾部位置维护一个计数器来减少N—其效果如何取决于观察者脱机时可以累积多少事件

您可以通过一个Lua过程来查看Tarantool是如何实现的,它为事件保留了一个环形缓冲区:

谢谢。Redis列表看起来确实很合适。我对Redis唯一的怀疑是它在内存中的存储限制(RAM很便宜,但可能没有那么便宜:-)),Redis VM(或下一个版本中的DiskStore)解决了这个问题,尽管它是基于交换单个密钥的,所以如果只有一个密钥包含一个巨大的列表,那么它就不能很好地工作。当然,根据目前可用的内存量,在开始成为问题之前,您需要大约100万个项目,而在您真正需要查看分片之前,只需对设计进行一些小的更改,您就可以获得大约1亿个项目。