Rethinkdb 2.2 更改源 include_initial

Rethinkdb 2.2 changefeeds with include_initial

举个最简单的例子,假设我正在向所有订阅者推送我最喜欢的食物列表。

r.table('food').changes().run(conn, (err, cursor) => {
  cursor.each((err, change) => {
    io.emit('NEW_FAVORITE', change);
  })
})

现在假设有 500 人在积极观看我添加我最喜欢的食物。 500 人订阅 500 个变更提要,每个人都有 include_initial,或者 500 个初始查询推送给这些人,然后 500 人观看 1 个变更提要,这会更高效吗?解释原因加分!

您不能让多个客户阅读一个 changefeed,因此让 500 人观看一个 changefeed 的唯一方法是让一个客户阅读该 changefeed,然后推送给 500 人。

如果多个客户端订阅了同一个 table,RethinkDB 会在集群内删除重复的 changefeed 消息,因此就网络流量而言,这与拥有 500 个打开的 changefeeds 并没有什么不同。服务器将使用更多内存,因为它正在跟踪哪些变更源具有哪些消息,但如果您有一个客户端从变更源读取信息并将其推送给 500 人,那么它也必须跟踪这一点。

使用 include_initial 的真正原因是它可以防止竞争。如果您先阅读然后打开更改源,则可能会在阅读结束和更改源开始之间发生更改。 include_initial 通过自动从读取切换到传递更改来防止这种情况发生。

(一个复杂的情况是,您在机器 A 上有 500 个进程想要从机器 B 上的 RethinkDB 服务器读取数据。在这种情况下,两种解决方案之间的网络流量存在差异,因为如果您将一个客户端在机器 A 上,从更改源读取并推送到进程,每个更改从 B 发送到 A 一次,然后传输到本地进程,而在另一种情况下,每个更改通过网络发送 500 次。如果之间的网络连接与机器 A 上进程之间的传输时间相比,A 和 B 很慢,这很重要。解决这个问题的最佳方法是在机器 A 上添加一个代理节点,并在该节点上打开 500 个 changefeed,因为 RethinkDB 将重复数据删除发送给代理节点的消息。)