我有一个服务器,它的存储类似于文件系统 - 它有文件,文件夹,你可以上传文件,下载文件,复制,移动,删除等。绝对没有办法修改服务器的界面(想象FTP)。文件名长度也有限制。
我有多个客户端需要同时使用此存储空间。他们进行通信的唯一方法是通过此文件系统界面。不允许使用自定义中央服务器进行同步或点对点。
如何使用此服务器的接口作为后端,从客户端实现远程键值存储,能够进行ACID事务?多个客户端可以同时访问/修改键值存储,并且只能使用公开的服务器文件系统接口来实现锁定机制。
我可以轻松地将该文件系统转换为自定义键值存储,因此我真正需要的是一些 C#/.NET
库,它将事务添加到任意键值存储。我不需要Facebook / Google风格的性能,键值存储将用于节省数十GB。
假设远程键值存储允许我string get(id)
,void put(id, string)
和delete(id)
条目。无法从服务器获取其他信息(即使没有异常也会引发错误)。鉴于访问该商店的唯一客户端将是我的,我应该如何实现它们,以便只有一个可以同时写入/删除(写锁定)?鉴于服务器接口非常有限,它甚至可能吗?我想这个解决方案需要一些非常好的加密技巧,但我还没有能够提出任何可行的方法。
答案 0 :(得分:1)
这只是一个粗略的想法,但您基本上需要实现“Copy on Write”功能,其中当您去修改文件时,您将文件复制到具有特殊扩展名的相同文件名,这将代表您编写更改的工作文件,也代表您的“锁定”。如果有人检测到存在“锁定文件”,则可以检查锁定文件的最后写入时间,如果上次写入时间超过预设超时,则可以假定锁定被放弃并删除锁定,如果最后一次write不会超过对文件的超时访问权限。
当客户端完成修改文件的复制版本时,它会将文件重命名为原始的“非锁定”文件名,在单个原子操作中覆盖未修改的原始副本。
这为您提供了ACID所需的一切,唯一的例外是 D 可用性,因为被废弃的锁会将超时时间段检测为已放弃。
如果您无法访问文件中的上次写入时间,您仍然可以使用此结构,但您需要添加第3个“元数据”文件来表示锁定而不是文件的“进行中”副本。该元数据文件只会将锁的创建时间戳作为其内容。