4

我正在使用视频服务器,我想使用数据库来保存视频文件。由于我只需要存储带有元数据的简单视频文件,因此我尝试在 Java 中使用 MongoDB,通过其GridFS机制来存储视频文件及其元数据。

但是,我需要两个主要功能,而我无法使用 MongoDB 来管理:

  1. 我希望能够添加到以前保存的视频中,因为保存视频可能会分块执行。我不想删除到目前为止的二进制文件,只需在项目末尾附加字节即可。
  2. 我希望能够在写入视频项目时读取它。“线程 A”将更新视频项目,添加越来越多的字节,而“线程 B”将从项目中读取,一旦写入/刷新,就会接收“线程 A”写入的所有字节。

我尝试编写简单的代码来做到这一点,但它失败了。似乎 MongoDB 不允许对二进制文件进行多线程访问(即使一个线程正在执行所有写入操作),我也找不到添加到二进制文件的方法 - Java GridFS API 仅提供来自已经现有的 GridFSDBFile,我无法让 OutputStream 写入它。

  • 这是否可以通过 MongoDB 实现,如果可以,如何实现?
  • 如果没有,您是否知道任何其他可能允许这样做的数据库(最好不要太复杂,例如完整的关系数据库)?
  • 我最好使用MongoDB只保留视频文件的元数据,并手动处理文件系统中的二进制数据的读写,这样我就可以自己实现上述要求了吗?

谢谢,

4

1 回答 1

7

我使用 mongo gridfs 来存储我们使用 Mongo 构建的消息传递系统的媒体文件,这样我就可以分享我们遇到的问题。

因此,在我针对您的用例场景进行讨论之前,我建议不要使用 GridFS,而实际上使用 Amazon S3 之类的东西(具有出色的用于分段上传的 rest apis)并将元数据存储在 Mongo 中。这是我们在首次使用 GridFS 实施后在项目中确定的方法。并不是说 GridFS 不好,只是不太适合分块/附加和重写小部分文件。有关更多信息,这里简要介绍了 GridFS 的优点和缺点:

http://www.mongodb.org/display/DOCS/When+to+use+GridFS

现在,如果您一心想要使用 GridFS,您需要了解驱动程序和读/写并发的工作原理。

在 mongo (2.2) 中,每个模式/数据库都有一个编写器线程。因此,这意味着当您编写代码时,您基本上无法让另一个线程执行操作。在现实生活中,这是非常快的,因为在写入块(256k)时锁会产生,因此您的阅读器线程可以获取一些信息。请查看此并发视频/演示文稿以获取更多详细信息:

http://www.10gen.com/presentations/concurrency-internals-mongodb-2-2

因此,如果您基本上看我的两个链接,我们可以说问题 2 得到了回答。您还应该了解一点关于 Mongo 如何编写大型数据集以及页面错误如何为读取器线程提供获取信息的方式。

现在让我们解决您的第一个问题。Mongo 驱动程序不提供将数据附加到 GridFS 的方法。它意味着是一个触发/忘记原子类型的操作。但是,如果您了解数据如何以块的形式存储以及如何计算校验和,那么您可以使用 fs.files 和 fs.chunks 方法手动执行此操作,如此海报所述:

将数据附加到现有的 gridfs 文件

因此,通过这些您可以看到可以做您想做的事情,但我的一般建议是使用专为此类交互设计的服务(例如 Amazon S3),而不是尝试做额外的工作来使 Mongo 适合您的需求。当然,您也可以直接访问文件系统,这将是穷人的选择,但您会失去使用 GridFS 或 S3 获得的冗余、分片、复制等。

希望有帮助。

-普拉西斯

于 2012-10-22T16:00:30.640 回答