保持数据库与文件系统上的图片同步[PHP/Postgresql/Linux]

问题描述 投票:0回答:3

背景故事

我维护并正在重新设计几个基于 PHP 的 Web 应用程序,并且有一个主题我还没有找到一个优雅的解决方案,所以我正在寻找一些输入,这可能会引导我找到更好的方法去做。

当前状态

我的几个应用程序允许用户除了大量数据之外还存储图像。所有数据最终都存储在 PostgreSQL 集群中,但是出于性能和可维护性的考虑,我选择不将图像本身存储在数据库中。图像将其元数据存储在数据库中(例如原始文件名、宽度/高度等),一旦数据库事务成功,我将文件系统上的图像移动到图像目录中(存储为 .jpg)。

问题

所有这些功能都很好,但是由于应用程序被大量使用,并且由多人同时通过互联网使用,并且 PHP 的错误/异常处理并不是在所有情况下都是最可靠的,我偶尔会担心不能够将图像(在文件系统上)存储在数据库事务中(因为它发生在文件系统上)。我还担心,因为如果文件系统上的图像文件被损坏/更改/删除,数据库的记录将无法正确更新(没有引用完整性)。

解决方案

到目前为止我想到的是:

选项 A)将实际图像(不仅仅是元数据,而是整个二进制文件)存储在数据库中。 -- 我不喜欢这个,因为目前数据库虽然相当复杂,但仍然很小(不超过 60MB 左右)。相关图像总共有很多 GB,因此它会大量增加我的 PostgreSQL 安装的占用空间。此外,它会使我的数据库备份和复制场景变得复杂。

选项 B)保留当前设计(文件系统上的图像,postgres 中的数据),并尝试在应用程序级别的每个使用点上解释损坏的数据。 -- 它使应用程序更加复杂且容易出错。

选项 C)我发现了一个名为 Flourishlib 的 PHP ORM 框架,它包含一个模拟文件系统事务的文件系统类(基本上,如果您调用 $file->rename() ,它会检查是否可能,但实际上不会重命名,直到您调用提交事务)——这是迄今为止我发现的最好的解决方案,但是我已经在使用另一个 ORM 框架(Propel),对于这种规模的项目我更喜欢它,所以我需要 2 个很大程度上重叠的框架功能。

所以,我想这里的许多其他人之前也会遇到同样的“问题”,而且我确信有些人想出了一些我还没有想到的解决方案。感谢任何指点、建议或批评。

php postgresql transactions filesystems data-storage
3个回答
1
投票

这是我对选项 D 的建议:

  1. 将实际图像及其元数据和哈希存储在数据库(整个二进制文件)中(请参阅图像哈希的用途是什么?)。

  2. 构建一个微服务,负责将二进制图像从数据库转换到文件系统或 CDN。 通过比较哈希值,该微服务可以检查图像完整性。它甚至可以负责存储以前的版本和日志。交易完成后,可以删除数据库中的二进制数据以保持轻量级。

  3. 设计消息队列架构(例如使用Amazon SQS)来启动和管理此微服务。它将独立于您的主应用程序运行,并准备好处理故障、数据库维护、错误等。

希望这会有所帮助,即使是在 8 年后。


1
投票

在我看来,这是两个不同的问题。

第一个:如何保证完整性,这个问题你已经以某种方式解决了。我唯一要考虑的是在数据库事务期间执行文件系统操作,并在出现问题时回滚。这里的权衡是性能,因为文件系统操作相当慢,但也不是那么慢;) 你可以试试...

第二个:外部文件操作后如何保持完整性。在这里我建议使用 php PHPInotify 来看看 inotofy。它允许您实现观察者模式,以便在文件系统发生更改时收到通知。


0
投票

您随时可以从高级下载页面获取 Flourish 的子集。只需选择 fFile,它就会选择依赖项。不幸的是,随着时间的推移,自动依赖性检测变得有点不准确(因此它将包括实际上可选的 fEmail),但您可以删除它,留下一些文件系统类和一些核心/异常内容。

© www.soinside.com 2019 - 2024. All rights reserved.