3

我想用 node.js 制作一个包含数万个文件的库,存储在数据库(sqlite 或其他东西)中(类似于 Plex 对视频的处理方式)。这些文件将在本地可供 node.js 服务器或通过 NAS 或其他东西使用。处理文件后,有关文件(及其位置)的信息将存储在数据库中。我想制作一个扫描功能,可以扫描某个目录(以及该目录的子目录)以查找文件。我想跳过之前已经处理过的文件。跟踪哪些文件已被处理的最佳方法是什么?它需要处理数以万计的文件。我有几个想法:

  • 使用像fs.watchor之类的文件观察器chokidar。缺点是这个观察者总是需要运行以检测新文件,并且在服务器关闭时不会向后工作。
  • Cron 作业检查文件并在处理文件时将文件移动到新目录(首选我不需要移动文件的解决方案)
  • 基于内容散列:散列并存储已处理文件的内容,并检查新文件的散列是否已经在数据库中(需要对每个文件进行数据库调用,并且还必须检查每个文件的内容并对其进行散列文件,使性能变差)
  • 仅基于文件名:从数据库中获取所有已处理的文件名并遍历所有文件并检查它们是否在已处理的文件名列表中。当有很多文件时,性能可能会很差(既要遍历那么多文件,又要将数据库中所有已处理的文件名存储在一个对象中,从而使内存成为瓶颈)。

以上所有场景都存在性能问题,并且在要检查的文件很多时可能无法正常工作。我能想到的唯一高性能解决方案是每次从目录中抓取 10 个左右的文件needs-processing并将文件移动到processed目录中,但我想要一个无需移动文件的高性能解决方案。我想要一个可以上传所有文件的文件夹,当我上传新文件时,它要么定期检查新文件,要么我必须触发重新扫描库来检查新文件。

4

3 回答 3

1

将文件直接存储在数据库中,而不是它们的位置。使用Filestream是一种选择。然后,您只需添加某种标志,指示其是否已被处理。然后,您可以遍历所有文件并知道它们是否已被处理。只需确保更新已处理文件的表即可。根据处理过程,您还可以将处理限制在方便的时间。

例如)如果有可能文件不会被使用,但需要在使用前进行处理。然后,您可以在调用之前处理文件,避免经常或定期检查。

就性能而言,这甚至可能比文件系统在读写方面更快。从SQLite 网站

... 许多开发人员惊讶地发现,SQLite 可以从其数据库中读取和写入较小的 BLOB(大小小于约 100KB),这比从文件系统中作为单独文件读取或写入相同的 blob 更快。(有关更多信息,请参阅比文件系统和内部与外部 BLOB 快 35%。)操作关系数据库引擎会产生开销,但是不应假设直接文件 I/O 比 SQLite 数据库 I/O 快,因为通常不是。

于 2021-07-03T17:47:18.217 回答
1

选项 5:基于时间怎么样?如果您知道上次处理目录的时间是 timestamp x,那么接下来您可以跳过所有较旧x的文件,而不仅仅是查看文件统计信息。然后从这个较小的子集中,您可以使用散列来查找冲突。

编辑:似乎 arpit 和我同时输入了相同的一般想法。请注意,尽管他包含的链接中的排序方法将遍历所有 10k 个文件 3 次。你不需要对任何东西进行排序,你只需要遍历一次并处理符合要求的那些。

于 2021-07-08T13:00:19.720 回答
1

当您在 DB 中存储文件处理信息时,请在单个查询中从 DB 获取最后处理时间,并处理在该时间戳之后创建的所有文件。

通过时间戳过滤文件如何从Node JS中修改的目录排序日期读取文件

如果您可以控制目录结构而不是按日期时间和其他主/辅助键对文件进行分区。

于 2021-07-08T12:57:48.267 回答