![如何在随机断电的机器上存储数据](https://linux22.com/image/600089/%E5%A6%82%E4%BD%95%E5%9C%A8%E9%9A%8F%E6%9C%BA%E6%96%AD%E7%94%B5%E7%9A%84%E6%9C%BA%E5%99%A8%E4%B8%8A%E5%AD%98%E5%82%A8%E6%95%B0%E6%8D%AE.png)
我在物理机主机上运行了一台虚拟机 (Debian)。虚拟机充当其通过本地网络频繁接收的数据的缓冲区(此数据的周期为 0.5 秒,因此吞吐量相当高)。收到的任何数据都存储在虚拟机上,并通过 UDP 反复转发到外部服务器。一旦外部服务器确认(通过 UDP)已收到数据包,原始数据将从虚拟机中删除,并且不会再次发送到外部服务器。连接虚拟机和外部服务器的互联网连接不可靠,这意味着它可能一次中断数天。
托管虚拟机的物理机每天会随机断电数次。无法判断何时会发生这种情况,也无法为系统添加 UPS、电池或类似解决方案。
本来数据是存放在虚拟机上基于文件的HSQLDB数据库上的,但是频繁断电最终导致数据库脚本文件损坏(不是文件系统级别的,也就是说可以读取,但是HSQLDB无法读取),这就引出了我的问题:
在经常发生断电的环境中,应该如何存储数据?
我能想到的一个选项是使用平面文件,将每个数据包保存为文件系统上的文件。这样,如果某个文件因断电而损坏,则可以忽略它,其余数据仍保持完整。但这会带来一些问题,主要与虚拟机上可能存储的数据量有关。每条数据之间间隔 0.5 秒,10 天内将生成 1,728,000 个文件。这至少意味着使用具有更多 inode 的文件系统来存储这些数据(当前文件系统设置在约 250,000 条消息和 30% 的磁盘空间使用量时 inode 用尽)。此外,管理起来很困难(并非不可能)。
还有其他选择吗?是否有在 Debian 上运行且不会因断电而损坏的数据库引擎?此外,应该使用什么文件系统?目前使用的是 ext3。
虚拟机上运行的软件是使用 Java 6 编写的,因此希望解决方案不会不兼容。
答案1
老实说,最好的方法是修复断电问题,或在更好的位置部署不同的系统。
是的,有些系统(例如 redis)会将数据存储在仅追加日志中以供重放,但这样做会面临较低级别的损坏风险 - 例如,如果您的文件系统被打乱,那么磁盘上的数据就可能存在风险。
我知道任何改进对你来说都是有用的,但事实上这个问题不是根据你所概述的情况就能解决的。
答案2
你的方法可行。我建议对其进行一些改进。stack overflow 上有一个问题原子写入文件。本质上,您将每个数据包保存到一个临时文件中,然后将其重命名为最终名称。重命名是一种原子操作,不会因电源故障而受到影响。这样,您就可以保证最终目的地中的所有文件都已正确保存且没有损坏。
那么,您可以做些什么来解决拥有数百万个文件的问题呢? cron 是一个每小时运行一次的作业,它会将所有超过一小时的文件合并为一个大文件,再次使用原子文件操作,以便此作业即使在电源故障期间也能安全运行,然后删除旧文件。有点像日志轮换。一小时的文件大约有 7,200 个文件。因此,在任何时候,磁盘上的文件都不应超过 20,000 个。
答案3
你在系统中安装了 UPS 或带有电池备份写缓存的 RAID 卡,最低仅需 49.95 美元,您就可以完成仅靠软件根本无法完成的事情。
您声称无法将该服务器连接到 UPS 或电池……这简直令人难以置信。
答案4
将整个系统挂载为只读,除了存储所有数据的块设备。直接使用该块设备并使用该原始块设备实现您自己的数据存储机制。