通过云存储,将个人数据备份在网络上是非常吸引人的服务,比较著名的公司或产品有dropbox、surgarsync、Live Mesh、Syncplicity等。这些产品的特点是能够和操作系统的shell整合,例如和Windows的资源管理器或者Linux上的nautilus,当本地有数据改动会自动的同步到远程的“云存储”上。用户可以在多个计算机或者手持设备上配置和同一个“云端”的帐号同步,从而实现在多个计算机或者多个手持设备上的数据同步。
遗憾的是我并未使用过上述云存储服务,主要是支持Linux操作系统的云存储客户端比较少,或者即使有也因为网络的局限而无法访问。但是通过相关文档,还是可以了解到其实现的机理。
仅支持对部分历史数据的备份。
dropbox支持30天数据备份,surgarsync每个文件仅保留5个备份(付费用户),对于免费用户仅2个备份。
数据同步对网络带宽依赖比较高。
“云端”被多个设备共享,冲突解决比较困难。
Surgarsync会将冲突的文件自动保存为多份,造成磁盘空间超出配额。其他有的产品在遇到冲突时停止同步,让用户决定选择哪个版本。
在Git书里介绍云存储,是因为上述云存储实现和Git有关么?不是。实际上通过上面各个云存储软件特性的介绍,有经验的Linux用户会感觉这些产品在数据同步时和Linux下的rsync、unison等数据同步工具非常类似,也许只是在服务器端增加了历史备份而已。
已经有用户尝试将云存储和Git结合使用,就是将Git库本身放在本机的云存储同步区(例如dropbox的Dropbox目录下),Git库被同步至云端。即用云存储作为二传手,实际上还是基于本地协议操作Git。这样实际会有问题的。
GitHub是Git风格的云存储,但缺乏像前提到的云存储提供的傻瓜式服务,只有Git用户才能真正利用好,这大大限制了Git在云存储领域的推广。下面是我的一个预言:一个结合了Git和傻瓜式云存储的网络存储服务终将诞生。新的傻瓜式云存储有下列特征:
差异同步传输
对用户体验最为关键的是网络传输,如果用Git可以在同步时实现仅对文件差异进行数据传输,会大大提高同步效率。之所以现有的在线备份系统实现不了“差异同步传输”,是因为没有在本地对上一次同步时的数据做备份,只能通过时间戳或者文件的哈希值判断文件是否改变,而无法得出文件修改前后的差异。
可以很容易的测试云存储软件的网络传输性能。准备一个大的压缩包(使同步时压缩传输可以忽略),测试一下同步时间。再在该文件后面追加几个字节,然后检查同步时间。比较前后两个时间,就可以看出同步是否实现了仅对差异的同步传输。
可预测的本地及云端存储空间的占用
要想实现前面提到的差异同步传输,就必须在本地保存上一次同步时文件的备份。Subversion是用一份冗余的本地拷贝实现的,这样本地存储是实际文件的两倍。Git在本地是完全版本库,占用空间逐渐增加变得不可预测。
使用Git实现云存储,就要解决在本地以及在服务器端空间占用不可预测的问题。对于服务器端,可以采用前面介绍的Gistore软件采用的重整版本库的方法,或者通过基于历史版本重建提交然后变基来实现提交数量的删减。对于客户端来说,只保留一个提交就够了,类似Subversion的文件原始拷贝,这就需要在客户端基于Git原理的重新实现。
更高效的云端存储效率
现有的云存储效率不高,很有可能因为冗余备份而导致存储超过配额,即使服务提供商的配额计算是以最后一个版本计算的,实际的磁盘占用还是很可观。
Git底层实现了一个对内容跟踪的文件系统,相同内容的文件即使文件名和目录不同,在Git看来都是一个对象并用一个文件存储(文件名是内容相关的SHA1哈希值)。因此Git方式实现的云存储在空间的节省上有先天的优势。
自动的冲突解决
冲突解决是和文件同步相关的,只有通过“差异同步传输”解决了同步的性能瓶颈,才能为冲突解决打下基础。先将冲突的各个版本都同步到本地,然后进行自动冲突解决,如果冲突无法自动解决,再提示用户手工解决冲突。还有,如果在手工冲突解决是引入类似kdiff3一样的工具,对用户更有吸引力。
Git提交中引入特殊标识
如果使用变基或其他技术实现备份提交数量的删减,就会在云端的提交和本地数据合并上产生问题。可以通过为提交引入特殊的唯一性标识,不随着Git变基而改变,就像在Gerrit中的Change-Id标签一样。
我相信,基于Git的文件系统以及传输机理可以实现一个更好用的云存储服务。