【问题标题】:Is it efficient to store images inside MongoDB using GridFS?使用 GridFS 在 MongoDB 中存储图像是否有效?
【发布时间】:2021-07-29 04:35:36
【问题描述】:

我知道怎么做,但我想知道它是否有效。据我所知,MongoDB 有非常高效的集群,我可以灵活地控制集合和它们所在的服务器。唯一的问题是文件的大小和通过 MongoDB 访问它们的速度。

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

【问题讨论】:

    标签: mongodb hadoop file-upload store ceph


    【解决方案1】:

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

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

    Ceph 专为存储文件而设计。存储 PB 级信息。这正是我们所需要的。

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

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

    GridFS

    Ceph File System

    More Ceph

    【讨论】:

      【解决方案2】:

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

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

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

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

      因此,乍一看,问题就解决了——应用程序可以直接存储任意大的 blob。然而,深入挖掘,GridFS 存在以下问题/限制:

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

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

      • 如果整体数据量不是很大,缓存的负面影响是有限的。
      • 如果大多数 blob 都适合单个文档,那么它们的存储效率应该很高。
      • 备份 blob 并以其他方式与数据库中的内容文档一起传输,从而提高数据一致性并降低数据丢失/不一致的风险。

      【讨论】:

      • 这似乎是真的,但基本问题仍然存在。好吧,答案没有考虑到一些事情。如果集合 2 有用户和指向集合 1 中文件的链接,而集合 1 有文件本身,我可以解决缓存问题吗?然后我会让其他数据库实例负责这些文件,就像这些实例有不同的缓存一样。 Image 图片不是想法的全部。
      【解决方案3】:

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

      【讨论】:

      • 你能辩解吗?我只是想找出真相。
      • 想象一下,以后项目会变得非常大,例如,我将不得不存储 PB。我能否快速将服务器连接到集群?
      猜你喜欢
      • 2012-02-06
      • 2014-05-11
      • 1970-01-01
      • 2012-04-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-13
      • 2011-12-07
      相关资源
      最近更新 更多