我想用node.js创建一个由数万个文件组成的库,存储在数据库(sqlite或其他什么(中(类似于Plex对视频的处理方式(。这些文件将在本地提供给node.js服务器,或通过NAS或其他方式提供。处理文件后,有关文件(及其位置(的信息将存储在数据库中。我想做一个扫描功能,可以扫描某个目录(以及该目录的子目录(中的文件。我想跳过以前已经处理过的文件。跟踪哪些文件已被处理的最佳方法是什么?它需要为成千上万的文件工作。我有几个想法:
- 使用类似
fs.watch
或chokidar
的文件观察程序。不利的一面是,这个观察程序总是需要运行以检测新文件,并且在服务器关闭时不会向后工作 - Cron作业,在处理文件时检查文件并将文件移动到新目录(更喜欢不需要移动文件的解决方案(
- 基于内容散列:散列并存储处理过的文件的内容,并检查新文件的散列是否已经在DB中(需要对每个文件进行DB调用,而且必须对每个文件的内容进行检查和散列,这会降低性能(
- 仅基于文件名:从数据库中获取所有处理过的文件名,并循环所有文件,检查它们是否在已处理的文件名列表中。当有很多文件时,性能可能会很差(既要处理那么多文件,又要将数据库中所有处理过的文件名存储在一个对象中,从而使内存成为瓶颈(
以上所有场景都存在性能问题,当有许多文件要检查时,这些场景可能无法工作。我能想到的唯一高性能解决方案是每次从needs-processing
目录中抓取10个左右的文件,并将文件移动到processed
目录,但我想要一个不必移动文件的高性能解决方法。我想要一个可以上传所有文件的文件夹,当我上传新文件时,它会定期检查新文件,或者我必须触发重新扫描库来检查新文件。
将文件直接存储在数据库中,而不是它们的位置。使用Filestream是一种选择。然后,您只需添加某种标志,指示它是否已被处理。然后,您可以循环查看所有文件,并知道它们是否已被处理。只需确保更新已处理文件的表。根据处理情况,您还可以将处理时间限制在方便的时间内。
Ex.(如果有可能不使用文件,但在使用之前需要对其进行处理。然后,您可以在调用之前处理文件,避免经常或定期检查。
在读写方面,这甚至可能比文件系统更快。来自SQLite网站:
。。。许多开发人员惊讶地发现,SQLite可以从其数据库中读取和写入较小的BLOB(大小小于100KB(,比从文件系统中读取或写入相同的BLOB更快。(有关更多信息,请参阅比文件系统快35%和内部与外部BLOB。(操作关系数据库引擎会带来开销,但不应认为直接文件I/O比SQLite数据库I/O快,因为通常情况并非如此。
当您在DB中存储文件处理信息时,请在单个查询中从DB中获取最后一次处理时间,并处理在该时间戳之后创建的所有文件。
用于通过时间戳过滤文件如何从Node JS 中修改的目录排序日期读取文件
如果您可以控制目录结构,则可以通过日期时间和其他主键/辅键对文件进行分区。
选项5如何:基于时间?如果您知道上一次处理目录的时间戳是x
,那么在下一次遍历中,只需查看文件统计信息,就可以跳过所有早于x
的文件。然后,从这个较小的子集中,您可以使用哈希来查找冲突。
编辑:似乎arbit和我在同一时间输入了相同的总体想法。请注意,他包含的链接中的排序方法将对所有10k个文件进行3次迭代。你不需要对任何东西进行排序,只需要迭代一次,然后处理符合要求的内容。