Skip to content

Commit

Permalink
Dropbox with git may have problem
Browse files Browse the repository at this point in the history
  • Loading branch information
Jiang Xin committed Nov 19, 2010
1 parent 71ea50e commit 70e1e08
Showing 1 changed file with 20 additions and 11 deletions.
31 changes: 20 additions & 11 deletions 07-git-app/040-cloud-storage.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

通过云存储,将个人数据备份在网络上是非常吸引人的服务,比较著名的公司或产品有 dropbox, surgarsync, Live Mesh, Syncplicity 等。这些产品的特点是能够和操作系统的 shell 整合,例如和 Windows 的资源管理器或者 Linux 上的 nautilus,当本地有数据改动会自动的同步到远程的“云存储”上。用户可以在多个计算机或者手持设备上配置和同一个“云端”的帐号同步,从而实现在多个计算机或者多个手持设备上的数据同步。

我并未使用过上述服务,主要是支持 Linux 操作系统的云存储客户端比较少,或者即使有也因为某些原因而无法访问。但是通过相关文档,还是可以了解到其实现的机理。
我并未使用过上述服务,主要是支持 Linux 操作系统的云存储客户端比较少,或者即使有也因为某些原因 ;-) 而无法访问。但是通过相关文档,还是可以了解到其实现的机理。

* 仅支持对部分历史数据的备份。

Expand All @@ -15,32 +15,41 @@

Surgarsync 会将冲突的文件自动保存为多份,造成磁盘空间超出配额。其它有的产品在遇到冲突时停止同步,让用户决定选择哪个版本。

通过上述的功能描述,感觉部分产品在数据同步时使用的机理类似 rsync, unison 等 Linux 下的数据同步工具。至于这些产品在服务器端如何实现可能就五花八门了
我们在 Git 书里介绍云存储,是因为上述云存储实现和 Git 有关么?不是。实际上通过上面各个云存储软件特性的介绍,有经验的 Linux 用户会感觉这些产品在数据同步时和Linux 下的 rsync, unison 等数据同步工具非常类似,也许只是在服务器端增加了历史备份而已

我相信 Git 在这一领域内也可以大显身手。
已经有用户尝试将云存储和 Git 结合使用,就是将 Git 库本身放在本机的云存储同步区(例如 dropbox 的 Dropbox 目录下),Git 库被同步至云端。即用云存储作为二传手,实际上还是基于本地协议操作 Git。这样实际会有问题的。

* 如果两台机器包含不同步的提交,并且执行了 `git gc` 命令,云存储同步一定会引发冲突,这种冲突是难以解决的。

* 云端对 Git 的的每个文件都进行备份,这实际对于 Git 是不需要的,会浪费本来就有限的空间配额。

GitHub 是 Git 风格的云存储,但缺乏像前提到的云存储提供的傻瓜式服务,只有 Git 用户才能真正利用好,这大大限制了 Git 在云存储领域的推广。下面是我的一个预言:一个结合了 Git 和傻瓜式云存储的网络存储服务终将诞生。新的傻瓜式云存储有下列特征:

**差异同步传输**

对用户体验最为关键的是网络传输,如果用 Git 可以在同步时实现仅对文件差异进行数据传输,会大大提高同步效率。之所以现有的在线备份系统实现不了“差异同步传输”,是因为没有在本地对上一次同步时的数据做备份,只能通过时间绰或者文件的哈希值判断文件是否改变,而无法得出文件修改前后的差异。

可以很容易的测试云存储软件的网络传输性能。准备一个大的压缩包(使同步时压缩传输可以忽略),测试一下同步时间。再在该文件后面追加几个字节,然后检查同步时间。比较前后两个时间,就可以看出同步是否实现了仅对差异的同步传输。

**云端文件存储效率**
**可预测的本地及云端存储空间的占用**

很容易试验各种云存储解决方案的存储效率,在本地将一个大文件拷贝 N 份,然后执行同步,如果最终“云端”给出存储空间超出配额,就说明云端的数据存储实现上有问题
要想实现前面提到的差异同步传输,就必须在本地保存上一次同步时文件的备份。Subversion 是用一份冗余的本地拷贝实现的,这样本地存储是实际文件的两倍。Git 在本地是完全版本库,占用空间逐渐增加变得不可预测

Git 底层实现了一个对内容跟踪的文件系统,相同内容的文件即使文件名和目录不同,在 Git 看来都是一个对象并用一个文件存储(文件名是内容相关的 SHA1 哈希值)
使用 Git 实现云存储,就要解决在本地以及在服务器端空间占用不可预测的问题。对于服务器端,可以采用前面介绍的 Gistore 软件采用的重整版本库的方法,或者通过基于历史版本重建提交然后变基来实现提交数量的删减。对于客户端来说,只保留一个提交就够了,类似 Subversion 的文件原始拷贝,这就需要在客户端基于 Git 原理的重新实现

**自动的冲突解决**
**更高效的云端存储效率**

冲突解决是和文件同步相关的,只有通过“差异同步传输”解决了同步的性能瓶颈,才能为冲突解决打下基础。先将冲突的各个版本都同步到本地,然后进行自动冲突解决,如果解决不了,再提示用户手工冲突解决。如果在手工冲突解决是引入类似 kdiff3 一样的工具,对用户更有吸引力
现有的云存储效率不高,很有可能因为冗余备份而导致存储超过配额,即使服务提供商的配额计算是以最后一个版本计算的,实际的磁盘占用还是很可观

**存储空间的管理**
Git 底层实现了一个对内容跟踪的文件系统,相同内容的文件即使文件名和目录不同,在 Git 看来都是一个对象并用一个文件存储(文件名是内容相关的 SHA1 哈希值)。因此 Git 方式实现的云存储在空间的节省上有先天的优势。

使用 Git 实现云存储,可能遇到最主要的问题是服务器端以及客户端空间占用的问题,随着备份越来越多 Git 库的占用也越来越大。对于服务器端,可以采用前面介绍的 Gistore 软件采用的重整版本库的方法,或者通过基于历史版本重建提交然后变基来实现提交数量的删减。对于客户端来说,只保留一个提交就够了,这就需要在客户端基于 Git 原理的重新实现。
**自动的冲突解决**

冲突解决是和文件同步相关的,只有通过“差异同步传输”解决了同步的性能瓶颈,才能为冲突解决打下基础。先将冲突的各个版本都同步到本地,然后进行自动冲突解决,如果冲突无法自动解决,再提示用户手工解决冲突。还有,如果在手工冲突解决是引入类似 kdiff3 一样的工具,对用户更有吸引力。

**Git 提交中引入特殊标识**

上面提到通过变基实现备份数量的删减,就会遇到云端的提交和本地提交的合并问题,采用 Gerrit 类似的实现在提交说明中引入唯一标识是一个解决方案
上面提到通过变基实现备份数量的删减,就会在云端的提交和本地数据合并上产生问题。可以通过为提交引入特殊的唯一性标识,不随着 Git 变基而改变,就像在 Gerrit 中的 Change-Id 标签一样

我相信,基于 Git 的文件系统以及传输机理可以实现一个更好用的云存储服务。

0 comments on commit 70e1e08

Please sign in to comment.