Web应用的文件存储:文件系统vs数据库vs NoSQL引擎

34

我有一个Web应用程序,存储了大量的用户生成的文件。目前所有这些文件都存储在服务器文件系统上,这对我有几个不利影响:

  • 当我们移动“文件夹”(由我们的应用程序定义)时,我们也必须移动磁盘上的文件(尽管这更多是由于原始开发人员奇怪的设计决策而不是存储在文件系统中的要求)。
  • 很难为文件系统操作编写测试;我有一个模拟文件系统类,记录像移动、删除等操作,而不执行它们,这差不多可以完成工作,但我对测试没有100%的信心。
  • 我将添加一些其他任务,需要从其他服务访问文件以执行其他任务(例如,在Solr中索引、生成缩略图、电影格式转换),因此我需要远程访问文件。通过网络共享实现这一点似乎不太可靠...
  • 处理文件系统权限有时会给我们带来问题,尽管现在我们已经转移到纯Linux环境,这应该不再是问题。

所以,我的主要问题是:

  • 在MySQL中将文件存储为BLOB的缺点是什么?
  • NoSQL系统(如Cassandra)是否存在同样的问题?
  • 是否有其他建议可能是合适的,例如MogileFS等?
4个回答

9

这不是直接的答案,而是一些指向非常有趣且相似的问题的指针(是关于blob和图像的,但在我看来是可比较的)。

在MySQL中将文件存储为BLOB的缺点是什么?

NoSQL系统(如Cassandra)是否存在同样的问题?

PS: 我不想成为扫兴者,但我认为任何NoSQL解决方案都不能解决你的问题(对于大多数企业来说,NoSQL都是无关紧要的)。


谢谢,看起来这是一组非常有用的链接。存储各种类型的图像/二进制大对象正是我所需要的(我们正在存储各种东西)。 - El Yobo
谢谢,你给的链接很棒。显然在提问之前我需要更努力地搜索 :)总之,避免使用数据库似乎是正确的选择。我只需要在一定程度上将应用程序与文件系统解耦,这样就不那么痛苦了... - El Yobo
很高兴你觉得它们有用。我也赞同这个结论。 - Pascal Thivent

4

也许是一种混合解决方案。

使用数据库存储有关每个文件的元数据 - 并使用文件系统实际存储文件。

任何“文件夹”的重组都可以在数据库中建模,并从实际的操作系统位置取消引用。


这是我们目前的做法;文件夹的重构应该理想地完全与实际的文件系统位置无关,但旧的开发人员却费尽心思将其链接起来...所以我面临着某种程度上的重写,我想知道是否有一种适当的方法可以完全避免使用文件系统。 - El Yobo
如何从操作系统位置取消引用? - Erik
解除引用在这里意味着文件系统位置可能固定在某个目录中,但数据库有另一种标记位置的方式,可能看起来像文件夹层次结构,但与物理位置不同 - 然后这些被链接,就像一些正常的FK关系。 - Randy

2

通过将文件分割成1MB的列或者更小的,您可以在Cassandra中轻松地存储高达2GB的文件。这是相当常见的做法。

您也可以将其作为一个大列进行存储,但是在访问时需要将整个文件读入内存。


0

如果操作系统或应用程序不需要访问文件,则没有必要将文件存储在文件系统中。如果您想在备份数据库的同时备份文件,则将它们存储在数据库外部的好处就会减少。因此,将文件存储在数据库中可能是一种有效的解决方案。

另一个缺点是,在数据库中处理文件比在文件系统级别处理文件需要更多的开销。但是,只要优势大于劣势,并且在您的情况下似乎是这样,您可以尝试一下。

我的主要关注点是管理磁盘存储。随着数据库文件变得越来越大,管理整个数据库变得更加复杂。您不希望从锅里跳到火里。


我对磁盘空间并不太担心;现在的价格非常便宜,如果需要的话,我可以添加更多的驱动器并进行RAID。我对MySQL的关注主要与缓存有关;如果我运行一个返回BLOB的查询,似乎会占用大量的缓存空间,清除其他更有用的数据。我怀疑还可能存在其他问题,否则更多的人会这样做,但我不确定具体是什么问题。 - El Yobo
我已经在这个主题上读了很多资料,没有人将查询缓存问题作为不将文件存储在数据库中的原因。在MySQL中,您可以设置query_cache_limit值,该值表示要缓存的最大结果集大小。默认值为1 MB。作为另一种替代解决方案,可能可以解决您遇到的文件系统问题,您还可以查看NFS(文件服务器)。您可以在数据库中存储文件的引用。 - Marcus Adams
真的,限制要存储在查询缓存中的东西的大小可能会减少我在这里担心的问题。存储文件系统引用仍然很麻烦,但看起来这是最好的方法。 - El Yobo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接