我正在创建一个在插入特定 USB 密钥时运行的 Windows 服务。它的作用很简单:联系 FTP 服务器,下载一些文件,并将它们存储在 USB 上的(加密)存档中。可以使用提供给客户端的工具以只读方式打开存档(但这与我的问题无关)。
该服务用于使 USB 与主服务器保持同步(很像 Dropbox,但只有下载和同步文件夹位于可移动媒体上)。存档可以增长到几 GB。大约 1GB 的文件每周在大约 400 个用户的密钥上更新。
由于整个更新过程对用户来说是透明的,当数据被写入存档时,他们拔掉USB的可能性是不可忽略的(即使我发出了某种尖叫、华而不实的警告:不要拔掉)。损坏存档需要重新完整下载,这意味着在已经加载的服务器上浪费了大量带宽。
所以基本上我需要对存档的写入进行交易。如果他们失败了也没关系,只要他们不让容器处于不一致的状态。该文件要么完全写入,要么不是. 如果容器实际上没有“看到”文件,则文件被部分写入也没关系。
问题就在这里: 如何始终保证数据的一致性?具体来说,如何使 IO 操作作为事务工作?你有什么建议?我应该自己实现一些东西吗?还是已经有提供这种功能的容器?
这是我到目前为止所得到的:
- 创建一个新存档,在提交时重命名:不可能,存档太大。
- Zip / Tar / 7z:不合适,写入失败会损坏存档
- Truecrypt:不合适,因为它需要文件系统驱动程序(用户没有的管理员权限)。
- 任何需要将文件系统映射到文件的事情:不合适,很确定如果没有管理员身份就无法做到这一点,但如果可能的话,那就太好了。
- 将文件存储在 SQLite DB 中:它是 ACID,因此这确实是一个解决方案。但是,由于 SQLite 的 BLOB 容量有限,因此需要拆分文件。不是很优雅,但我准备好了。SQLite 的事务日志在存储大 blob 时也会变得非常大。
- 自己实施:我宁愿尽可能避免这样做,但我不害怕这样做。我只是觉得这个话题很复杂。
如果这个问题太笼统,请将其移至 SU 或其他地方。