如何在随机断电的机器上存储数据

Sev*_*vas 13 filesystems debian corruption

我有一台运行在物理机主机上的虚拟机 (Debian)。虚拟机充当它经常通过本地网络接收的数据的缓冲区(此数据的周期为 0.5 秒,因此吞吐量相当高)。收到的任何数据都存储在虚拟机上,并通过 UDP 重复转发到外部服务器。一旦外部服务器(通过 UDP)确认它收到了一个数据包,原始数据就会从虚拟机中删除,并且不会再次发送到外部服务器。连接 VM 和外部服务器的 Internet 连接不可靠,这意味着它可能一次关闭数天。

托管 VM 的物理机每天会随机断电数次。无法判断何时会发生这种情况,也无法向系统添加 UPS、电池或类似解决方案。

最初,数据存储在虚拟机上基于文件的 HSQLDB 数据库中。但是,频繁的断电最终导致数据库脚本文件损坏(不是在文件系统级别,即可读,但HSQLDB无法理解),这就引出了我的问题:

在断电可能并且确实经常发生的环境中,数据应该如何存储?

我能想到的一种选择是使用平面文件,将每个数据包保存为文件系统上的一个文件。这样,如果文件因断电而损坏,则可以忽略它,其余数据保持完整。然而,这会带来一些问题,主要与可能存储在虚拟机上的数据量有关。每条数据间隔 0.5 秒,10 天内将生成 1,728,000 个文件。这至少意味着使用具有更多 inode 的文件系统来存储这些数据(当前的文件系统设置在大约 250,000 条消息和 30% 的磁盘空间使用时耗尽了 inode)。此外,它很难(并非不可能)管理。

还有其他选择吗?是否有在 Debian 上运行的数据库引擎不会因断电而损坏?另外,应该为此使用什么文件系统?ext3 是目前​​使用的。

在虚拟机上运行的软件是使用 Java 6 编写的,因此希望该解决方案不会不兼容。

小智 23

老实说,您最好的方法是修复断电,或在更好的位置部署不同的系统。

是的,有诸如 redis 之类的系统会将数据存储在仅附加日志中以供重播,但是您可能会在较低级别面临损坏的风险 - 例如,如果您的文件系统被打乱,则磁盘上的数据可能存在风险。

我很感激任何改进都会对您有用,但实际上,鉴于您概述的情况,问题并不是可以解决的。

  • +1 正确答案是“不要那样做” (8认同)
  • +1 最终随机断电会损坏您的文件系统。电子设备在断电时会做一些奇怪的不可预测的事情。 (6认同)

Mar*_*agh 11

你的方法可行。让我建议对其进行一些改进。原子写入文件的堆栈溢出存在问题。本质上,您将每个数据包保存到一个临时文件中,然后将其重命名为它的最终名称。重命名是一种原子操作,可以避免电源故障。这样您就可以保证最终目的地中的所有文件都已正确保存而没有损坏。

那么你可以做些什么来处理拥有数百万个文件的问题。cron 是一项可能每小时运行一次的作业,它将所有旧文件超过一个小时,并再次使用原子文件操作将它们组合成一个大文件,以便该作业即使在电源故障期间也能安全运行,然后删除旧文件。有点像日志轮换。一个小时的文件大约有 7,200 个文件。因此,在任何时候,您的磁盘上都不应该有超过 20,000 个文件。

  • @HopelessN00b 新文件写入一半或损坏都没有关系。您拥有处于良好状态的旧文件。当您恢复系统时,您会破坏写了一半的文件。 (3认同)
  • @HopelessN00b 没错!可以说只有临时目录中的临时文件可以写一半。最终目标目录中的所有文件将始终未损坏且安全地存储在磁盘上 (2认同)

Hop*_*00b 7

您在系统中安装带有电池供电写入缓存的 UPS 或 RAID 卡,只需49.95 美元,您就可以完成仅靠软件无法完成的任务。

您声称以某种方式无法将这台服务器连接到 UPS 或电池上的说法是不可信的。

  • 官僚主义的愚蠢总是可信的。 (9认同)
  • @DanNeely`我的PHB不会让我把它连接到UPS/电池`与`不可能向系统添加UPS、电池或类似的解决方案是非常不同的。`不是得到太迂腐了,但这是一个重要的区别,因为它改变了可用的方法和解决方案。 (3认同)

Mik*_*eyB 5

以只读方式挂载整个系统,但存储所有数据的块设备除外。直接使用该块设备并使用该原始块设备实现您自己的数据存储机制。

  • ...并投资于一个电池供电的磁盘控制器卡,并确保磁盘上没有写缓存,否则你仍然被搞砸了。 (3认同)