使用 GridFS 在 MongoDB 中存储图像是否有效?

Is it efficient to store images inside MongoDB using GridFS?

我知道怎么做了,不知道有没有效果。据我所知,MongoDB 拥有非常高效的集群,我可以灵活地控制集合及其驻留的服务器。唯一的问题是文件的大小和通过 MongoDB.

访问它们的速度

我应该探索类似 Apache Hadoop 的东西,还是如果我智能集群 MongoDB,我会得到类似的访问速度结果吗?

最好的做法是将图片上传到某个地方(您的服务器或云端),然后只将图片 url 存储在 MongoDB

GridFS 是为了方便而提供的,它并非旨在成为最终的二进制 blob 存储平台。

MongoDB 对其存储的每个文档施加 16 MB 的限制。例如,这不同于许多允许存储更大值的关系数据库。

由于许多应用程序处理大型二进制 blob,MongoDB 解决此问题的方法是 GridFS,其大致工作方式如下:

  • 对于每个要插入的 blob,元数据文档都会插入到元数据集合中。
  • 然后,实际的 blob 被分成 16 MB 的块,并作为文档序列上传到 blob 集合中。
  • MongoDB 驱动程序提供写入和读取 blob 和元数据的帮助程序。

因此,乍一看,问题已解决——应用程序可以直接存储任意大的 blob。然而,深入挖掘,GridFS 具有以下 issues/limitations:

  • 在服务器端,存储 blob 块的文档不会与其他文档分开存储。因此,它们与实际文档竞争缓存 space。同时具有内容文档和 blob 的数据库的性能可能比仅具有内容文档的数据库差。
  • 同时,由于 blob 块的存储方式与内容文档相同,因此存储它们通常 昂贵 。比如S3比EBS存储便宜很多,GridFS会把所有数据都放在EBS上。
  • 据我所知,不支持并行写入或并行读取 blob(writing/reading 同一 blob 的多个块)。这原则上可以在 MongoDB 驱动程序或应用程序中实现,但据我所知,任何驱动程序都没有开箱即用。当 blob 很大时,这会限制 I/O 性能。
  • 同样,如果读取或写入失败,则必须重新读取或重写整个 blob,而不是仅仅丢失的片段。

尽管存在这些问题,GridFS 对于许多用例来说可能是一个很好的解决方案:

  • 如果总体数据量不是很大,缓存的负面影响是有限的。
  • 如果大多数 blob 都可以放在一个文档中,那么它们的存储应该非常有效。
  • 对 blob 进行备份,并与数据库中的内容文档一起传输,提高数据一致性并降低数据风险 loss/inconsistencies。

无论如何,我做了一点调查。简短的结论是:如果你需要存储用户头像,你可以使用 MongoDB,但前提是它是单个头像(你不能在 MongoDB 中存储很多 blob)并且如果你需要存储视频或者只有很多大文件,那么你需要像 CephFS 这样的东西。

为什么我这么认为?问题是,当我在慢速实例上使用 MongoDB 和媒体文件进行测试时,重达 10mb(通常约为 1 兆字节)的文件返回时间长达 3000 毫秒。那是一段无法接受的漫长时间。当有很多文件(100+)时,它会变得很痛苦。真的很痛苦。

Ceph 专为存储文件而设计。存储数 PB 的信息。这就是需要的。

你如何在实际项目中实现这一点?如果您使用 MongoDB(Mongoose) 的 OOP 实现,您只需向访问 Ceph 的数据库对象添加方法并执行您需要的操作。您可以创建“加载文件”、“删除文件”、“计数数量”等方法,然后像往常一样将它们一起使用。不要忘记维护 Ceph,根据需要添加服务器,一切都会完美运行。文件本身应该只能通过您的网络服务器访问,而不是直接访问,即当用户需要提供文件时,网络服务器应该向 Ceph 发出请求,并且 return Ceph 对用户的响应。

我希望我帮助的不仅仅是我自己。我会将 Ceph 添加到我的标签中。祝你好运!

GridFS

Ceph File System

More Ceph