【问题标题】:Client-side generated document sequences with Node.js使用 Node.js 生成的客户端文档序列
【发布时间】:2017-11-22 07:17:48
【问题描述】:

我们想要构建一个 Node.js API,将无模式文档存储在 MongoDB 集合中。每个文档都应该有一个键“no”,按顺序排列它们:

[
   { "no": 1, ... }, 
   { "no": 2, ... }, 
   { "no": 3, ... }, 
   { "no": 4, ... }, 
   ...
]

我们有以下限制:

  • 排序(包括其他参数)需要加密签名。因此,服务器无法设置客户端在签名和发送数据之前不知道的序列号。
  • no 必须是唯一的(不允许:1 -> 1 -> 2 -> 3)
  • 排序中不能有任何间隙(不允许:1 -> 2 -> 4 -> 5)
  • API 是复制的,所以会有很多针对 MongoDB 的并发请求。
  • API 客户端不是浏览器应用程序,它实际上也是一个 Node.js 应用程序。将有只有一个 API 客户端

我们的出发点是让 API 在每个存储请求上都返回下一个序列号。

POST /collection { "no": 1, ...}
returns {"next": 2}

这行得通吗?

在客户端,可能是这样的伪代码:

let next

module.exports.create = (document, cb) => {
   if (!next) next = 1 // here it is probably better to sync the initial no with the db instead always starting with 1
   document.no = next
   return post('/collection', document, (err, res) => {
       if (err) ...
       next = res.next
       return cb(...)
   }
}

如果客户端的create被多个并发调用者调用,会不会出现两个或多个create请求重复no的情况?

【问题讨论】:

  • 如果有多个客户端,您返回下一个序列号的方案在竞争条件下是不安全的。通常,客户端只要求在列表末尾添加一个新文档,服务器会以一种不受竞争条件影响的方式分配下一个序列号(只有服务器才能以安全的方式执行此操作)。
  • 添加几个粗体字并不能改变这样不安全的事实。如果意图是存储在服务器上,那么排序应该来自那里。我们可以告诉你创建一个本地存储数据库来保持顺序,但这里的用例仍然很不清楚。您是否坚持可能与“重新排序列表”有关的“客户”责任?如果是这样,那么可能会有其他选择。最重要的是,这目前既不清楚又广泛,因为您过于关注证明您的案例的合理性,而不是提出要解决的实际问题。
  • 当您不清晰和广泛时,您会得到与刚刚得到的答案一样的答案。所以最好只描述用例并问“如何解决它”。
  • 我已经更新了帖子。除其他输入外,该序列将被加密签名。因此,在将序列号保存到数据库之前,客户端需要知道序列号。

标签: javascript node.js mongodb architecture


【解决方案1】:

当您有并发 API 调用并且客户端有权确定顺序时,如果客户端拥有确定顺序的全部权利,您几乎不可能实现您想要实现的目标。

但是,如果sequence no之间不能有任何间隙,而且必须是连续的,那么为什么客户端必须是提供sequence no的人呢?您可以轻松地就排序模式达成一致(例如 1、2、3、4 或 AB1、AB2、AB3 等),并让服务器端根据哪个请求来插入 sequence no在第一。使用findAndModify创建一个生成流水号的集合,然后让服务器将序列号更新到数据库中。

【讨论】:

  • 嗨,我已经更新了帖子。客户端需要事先知道序列号,因为它(而不仅仅是序列号)将由客户端签名。
  • 假设你有一个平均值来确定序列号是连续的,你可能有一个单行的集合来跟踪你最后一个有效的序列号,再次使用findAndModify。如果客户端调用您的 API 并提供无效的序列号,则抛出 HTTP 状态 400。如果他们为您提供了有效的,请继续插入。请注意,findAndModify 不适用于分片集合,iirc
猜你喜欢
  • 2017-12-28
  • 2016-12-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-11
  • 1970-01-01
  • 2019-10-13
相关资源
最近更新 更多