将批量POST请求中的重复项处理到REST API

jgl*_*dev 5 rest concurrency mongodb node.js express

堆栈

  • Express.js API服务器,用于对数据进行CRUD操作。
  • MongoDB数据库。
  • MongoDB模式的Moongose接口。

探针

为了仅在一点上处理重复项,我想在唯一可能的入口点进行处理:API。

定义:重复

复制是数据库中已经存在的实体,因此新POST请求是具有完全相同数据的同一实体,或者是具有更新数据的同一实体。

API设计旨在处理新的http2协议。

大批进口商已被书面。该程序从给定的源获取数据,将数据转换为我们的特定格式,并发出POST请求进行保存。该导入程序旨在并行处理每个实体。

该API已经具有复制处理程序,当数据库中已存在给定实体时,该复制处理程序将非常有用。当批量导入器同时对同一实体发出多个POST请求并且该实体在数据库中尚不存在时,就会出现问题。

....POST/1 .databaseCheck.......DataBaseResult=false..........DatabaseWrite
......POST/2 .databaseCheck.......DataBaseResult=false..........DatabaseWrite
........POST/3 .databaseCheck.......DataBaseResult=false..........DatabaseWrite
.....................POST/N .databaseCheck.......DataBaseResult=false..........DatabaseWrite
Run Code Online (Sandbox Code Playgroud)

这种情况会多次创建相同的实体,因为在其余的POST请求到达时,数据库检查尚未完成。仅当POST请求的数量足够大时,第一个写操作才已经完成,并且第N个请求的databaseCheck将返回true。

解决这个问题的正确解决方案是什么?如果我没有记错的话,我要查找的是事务的名称,并且我不知道这是数据库默认情况下应该提供的东西,还是我必须实现的东西。

我已经考虑过的解决方案:

1.限制请求,每次仅限制一个。

这是最简单的解决方案,但是如果在批量导入程序发出多个请求时API仍然被阻止,那么前端客户端将变得非常慢,并且意味着它是快速的多人游戏。因此,这实际上不是解决方案。

2.每个实体的特殊批量API端点。

如果应用程序需要发出批量请求,则仅发出一个巨大的POST请求,并将所有数据作为正文请求。该解决方案不会阻塞API,并且可以很好地处理重复项,但是我不喜欢的是我会违反http2协议,因为在该协议中需要许多小的请求。

而且问题仍然存在,如果其他未来的客户没有注意到有可用的批量端点,则可能会遇到此问题。但这也许不是问题。

3.尝试使用可能的MongoDB事务实现

我已经阅读了一些有关此内容的信息,但我不知道是否可以使用MongoDB和Mongoose工具来解决此问题。我已经做了一些搜索,但是什么也没找到,因为在尝试插入许多文档之前,我需要为每个文档生成数据,并且这些数据都在每个POST请求中。

4.删除MongoDB并使用事务友好型数据库。

由于目前整个堆栈已经完成,并且我们即将推出,因此这会带来很大的成本。我们不害怕重构。但是我认为这里将应用第三种解决方案考虑因素。

5.在API级别上实现自己的交易?

我设计了一种适用于每种情况的解决方案,我称之为池流。

这是设计:在POST请求到达时,将启动固定毫秒数的计时器。该时间量足够大以捕获多个请求,并且足够短以便不引起明显的延迟。

在每个请求块中,对数据进行处理,以尝试在写入数据库之前合并重复项。因此,如果在块中捕获了n个请求,则会生成n-m个(其中m <= n)唯一的候选者。将哈希函数应用于每个候选对象,以便将哈希结果分配给每个请求-响应对。然后,并行执行对候选数据库的写操作,并且当前的重复处理程序将在写时为此工作。

当前块的写操作完成后,将响应发送到该块的每个请求-响应对,然后处理下一个块。当大块在队列中等待写操作时,可以执行唯一的候选过程,以加速整个过程。

你怎么看?谢谢。