云存储 ****** 通过云存储,将个人数据备份在网络上是非常吸引人的服务,比较著名的公司或产\ 品有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。这样实际会有问题的。 * 如果两台机器各自进行了提交,云存储同步一定会引发冲突,这种冲突是难以\ 解决的。 * 云端对Git的的每个文件都进行备份,包括执行\ :command:`git gc`\ 命令打包\ 后丢弃掉的松散对象。这实际对于Git是不需要的,会浪费本来就有限的空间配额。 * 因为版本库周期性的执行\ :command:`git gc --auto`\ 会导致即使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的文件系统以及传输机理可以实现一个更好用的云存储服务。