三款面向 Amazon S3 的开源文件同步工具之对比

2010/03/28 | 00:02 | 分类:Linux与开源 | 标签: | 4,026次阅读

  受 @Sisyphusliu 师兄的启发,我最近决定试用 Amazon S3 来做个人数据同步与备份。初步计算发现这很可能比之前使用 VPS 或 Web 主机的方案要节约成本。我对三款面向 Amazon S3 的开源文件同步工具进行了对比,将其中部分细节说明如下,供有相同需求的朋友参考。
  这三款工具分别是 jets3t、s3cmd 和 s3sync.rb。其主要特性和附加功能这里不再赘述,它们的官方主页都有详细说明。软件的稳定性还有待长时间使用的考验,但从网上没有发现用户反映太大的问题。我在这里强调它们存储文件元信息的差别,以及由此可能引发的问题。

  jets3t s3cmd s3sync.rb
打包大小 12M 50k 30k
开发语言 Java Python Ruby
官方主页 http://bitbucket.org/jmurty/jets3t/ http://s3tools.org/ http://s3sync.net/
最后更新 2010-3 2009-10 2008-6
功能定位 综合工具集+文件管理GUI 命令行工具集 命令行工具集
文件元信息 Content-Type
jets3t-original-file-date-iso8601
md5-hash
Content-Type
s3cmd-attrs
Content-Type
group
owner
permissions
目录元信息 Content-Type
jets3t-original-file-date-iso8601
Content-Type
group
owner
permissions

  由于 S3 基于 Key-Object 存储方式,与树型文件系统不同,因此如何将树型结构组织的文件及其元信息存储在 S3 中就是一个问题。这三款工具都将文件的全路径作为 Key,并把文件的元信息保存在 Object 的自定义属性中。
  这样有什么后果呢?首先看目录。稍稍想想就会发现,像“a/b/c”这样的 Key 无法直接判定“c”是一个目录还是一个文件。s3cmd 的处理最简单,它的任何一个 Object 都是文件,不把目录作为 Object 保存。这样消除了歧义,但导致了目录的元信息无从保留,同时也无法保存空目录。而 jets3t 和 s3sync.rb 会保存目录的 Object,并通过元信息中的 Content-Type 来区别文件与目录。这样就保留了目录元信息,也允许空目录存在,但这影响了工具之间的互操作性。下载另一个工具上传的文件时,工具彼此不认识对方的目录 Object,就会将它们保存成普通文件,从而造成同名的目录无法创建。
  再来看看文件的元信息。s3cmd 保存的 s3cmd-attrs 属性是一个包含了 uid、gid、uname、gname、mtime、atime、ctime 等信息的字符串,因此它保留了最完整的文件元信息。jets3t 只保存文件修改时间,无从得知属主与权限,不适合保存可执行程序的目录;s3sync.rb 只保存属主与权限,而且是数字 id 而非名字,在新系统中恢复数据时可能出现映射错误。
  我个人倾向于选择 s3cmd。其一,文件修改时间和权限对于个人程序、文档来说是比较重要的信息。当然这不是技术问题,修改 jets3t 和 s3sync.rb 肯定也能做到。其二,不使用自定义的目录 Object 就允许一定程度的互操作,例如使用 jets3t 和 s3sync.rb 可以直接下载 s3cmd 上传的文件与目录结构(元信息丢失)。而 s3cmd 设计造成的目录元信息缺失、空目录消失等问题,对一般应用和文档来说不太重要、相对容易恢复。当然也可以使用额外的机制来记录目录元信息,但考虑 KISS 原则,s3cmd 目前的设计还是有道理的。要想同时解决元信息与目录问题,容易想到的办法是将目录打包或压缩再上传,这比较适于长周期的文件归档备份场景,但对于细粒度、短周期的日常数据同步场景并不适合。
  至于云存储的信任问题,在现阶段我也只能选择折衷。一方面不要将鸡蛋放在一个篮子里,重要数据还是需要异地备份的。另一方面可以使用这些同步工具自带的安全机制,或自己稍加封装实现数据加密。
  最后提醒大家,务必看看 Joel 的备份观

从磁盘映像中挂载或提取指定的 LVM 逻辑卷

2009/10/19 | 13:40 | 分类:Linux与开源 | 标签: | 5,034次阅读

  前面提到了如何从磁盘映像中挂载或提取指定分区,现在我们再看看如何从含有 LVM 分区的映像中挂载或提取指定的逻辑卷(LV)。由于 LVM 分区内部有自己的盘区(PE)分配方法,因此逻辑卷在映像中并不一定是物理连续的,不能通过找到其偏移地址直接挂载。不过只要本地系统安装了 LVM 支持,就可以使用 LVM 自带的实用工具完成硬盘映像中逻辑卷的挂载。
  首先查看一下本地系统已经挂载过的物理卷(PV)、卷组(VG)和逻辑卷。我们看到,系统已经安装并激活了 VolGroup01 卷组。事实上 VolGroup01 中的 LogVol00 是本地系统的根分区,LogVol01 是交换分区。

  1. [root@centos CentOS]# pvscan
  2.   PV /dev/sda2   VG VolGroup01   lvm2 [136.00 GB / 0    free]
  3.   Total: 1 [136.00 GB] / in use: 1 [136.00 GB] / in no VG: 0 [0   ]
  4. [root@centos CentOS]# vgscan
  5.   Reading all physical volumes.  This may take a while...
  6.   Found volume group "VolGroup01" using metadata type lvm2
  7. [root@centos CentOS]# lvscan
  8.   ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  9.   ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

  实验使用的 centos5-2-gnome.img 是一个安装了 CentOS 并通过 LVM 管理磁盘的映像文件。使用 fdisk 命令查看其分区结构,其中 centos5-2-gnome.img2 是 LVM 分区,fdisk 不能提供 LVM 的详细信息。

  1. [root@centos CentOS]# fdisk -l -u centos5-2-gnome.img
  2. last_lba(): I don't know how to handle files with mode 81a4
  3. You must set cylinders.
  4. You can do this from the extra functions menu.
  5.  
  6. Disk centos5-2-gnome.img: 0 MB, 0 bytes
  7. 255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
  8. Units = sectors of 1 * 512 = 512 bytes
  9.  
  10.               Device Boot      Start         End      Blocks   Id  System
  11. centos5-2-gnome.img1   *          63      208844      104391   83  Linux
  12. centos5-2-gnome.img2          208845     8385929     4088542+  8e  Linux LVM

  使用 Linux 的 loop 设备控制命令——losetup:首先用 -f 参数查找一个空闲的 loop 节点;然后通过 -o 参数指定 LVM 分区在映像中的偏移量(参考 fdisk 的输出),将其挂载在空闲的 loop 节点上;最后使用 -a 参数确认挂载成功。

  1. [root@centos CentOS]# losetup -f
  2. /dev/loop4
  3. [root@centos CentOS]# losetup -o $((208845*512)) /dev/loop4 centos5-2-gnome.img
  4. [root@centos CentOS]# losetup -a
  5. ...
  6. /dev/loop4: [fd00]:26706086 (centos5-2-gnome.img), offset 106928640

  再一次查看系统中存在的 LVM 设施。我们看到,映像中的 VolGroup00 卷组已被扫描到,其中有 LogVol00、LogVol01 两个未激活的分区。

  1. [root@centos CentOS]# pvscan
  2.   PV /dev/loop4   VG VolGroup00   lvm2 [3.88 GB / 0    free]
  3.   PV /dev/sda2    VG VolGroup01   lvm2 [136.00 GB / 0    free]
  4.   Total: 2 [139.88 GB] / in use: 2 [139.88 GB] / in no VG: 0 [0   ]
  5. [root@centos CentOS]# vgscan
  6.   Reading all physical volumes.  This may take a while...
  7.   Found volume group "VolGroup00" using metadata type lvm2
  8.   Found volume group "VolGroup01" using metadata type lvm2
  9. [root@centos CentOS]# lvscan
  10.   inactive          '/dev/VolGroup00/LogVol00' [2.91 GB] inherit
  11.   inactive          '/dev/VolGroup00/LogVol01' [992.00 MB] inherit
  12.   ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  13.   ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

  这个例子中,映像中的卷组与本地已挂载的卷组名称不同,不会出现歧义。但如果映像中的卷组恰与本地已挂载的卷组重名,则可以使用 vgrename 命令修改映像中的卷组名称。

  1. [root@centos CentOS]# vgrename --help
  2.   vgrename: Rename a volume group
  3.  
  4. vgrename
  5.         [-A|--autobackup y|n]
  6.         [-d|--debug]
  7.         [-h|--help]
  8.         [-t|--test]
  9.         [-v|--verbose]
  10.         [--version]
  11.         OldVolumeGroupPath NewVolumeGroupPath |
  12.         OldVolumeGroupName NewVolumeGroupName

  使用 vgchange 命令激活 VolGroup00 卷组,再次查看逻辑卷的状态,LogVol00、LogVol01 已经可用。

  1. [root@centos CentOS]# vgchange -ay VolGroup00
  2.   2 logical volume(s) in volume group "VolGroup00" now active
  3. [root@centos CentOS]# lvscan
  4.   ACTIVE            '/dev/VolGroup00/LogVol00' [2.91 GB] inherit
  5.   ACTIVE            '/dev/VolGroup00/LogVol01' [992.00 MB] inherit
  6.   ACTIVE            '/dev/VolGroup01/LogVol00' [134.06 GB] inherit
  7.   ACTIVE            '/dev/VolGroup01/LogVol01' [1.94 GB] inherit

  现在便可以使用 lvscan 输出的逻辑卷设备文件名来挂载对应的文件系统了。

  1. [root@centos CentOS]# mount /dev/VolGroup00/LogVol00 ./part/
  2. [root@centos CentOS]# ls ./part/
  3. bin  boot  dev  etc  home  lib  lost+found  media  misc  mnt
  4. net  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
  5. [root@centos CentOS]# umount ./part/

  如果要提取其中的分区,也可以直接对逻辑卷设备文件或 /dev/mapper/ 下对应的设备文件操作。

  1. [root@centos CentOS]# dd if=/dev/VolGroup00/LogVol00 of=LogVol00.img
  2. 6094848+0 records in
  3. 6094848+0 records out
  4. 3120562176 bytes (3.1 GB) copied, 113.93 seconds, 27.4 MB/s

  试挂载提取出来的分区。

  1. [root@centos CentOS]# mount -o loop LogVol00.img ./part/
  2. [root@centos CentOS]# ls ./part/
  3. bin  boot  dev  etc  home  lib  lost+found  media  misc  mnt
  4. net  opt  proc  root  sbin  selinux  srv  sys  tmp  usr  var
  5. [root@centos CentOS]# umount ./part/

  卸载文件系统之后,别忘了卸载卷组和 loop 节点。

  1. [root@centos CentOS]# vgchange -an VolGroup00
  2.   0 logical volume(s) in volume group "VolGroup00" now active
  3. [root@centos CentOS]# losetup -d /dev/loop4

从磁盘映像中挂载或提取指定分区

2009/10/11 | 22:48 | 分类:Linux与开源 | 标签: | 3,770次阅读

  最近在做虚拟机相关的事,需要处理一些磁盘和分区的映像文件。如何从一个磁盘映像中挂载指定的分区到本地 Linux 文件系统呢?理论上说,可以用 dd 把该分区从磁盘映像中提取出来再挂载,不过 mount 提供了针对 loop 设备的偏移量参数,方便直接从磁盘映像中挂载指定分区。笔记如下:
  演示用的磁盘映像使用 qemu-img 制作。我们使用原生的 raw 格式,等价于磁盘上的原始数据流,保证它在任何 Linux 系统上都可以直接挂载。使用 Windows PE 工具盘启动该 qemu 虚拟机,创建一系列不同格式的分区并在其中建立几个文件。

  1. root@lj-laptop:/opt/vm# qemu-img create -f raw vmtest.img 5G
  2. root@lj-laptop:/opt/vm# qemu -hda ./vmtest.img -cdrom /dev/cdrom -boot d -m 256M -localtime

  磁盘分区结构如截图:
从磁盘映像中挂载或提取指定分区
  回到宿主系统,使用 fdisk 的 -l、-u 参数查看磁盘映像。其中 -u 表示以扇区为单位显示分区起止位置,方便后续计算。

  1. root@lj-laptop:/opt/vm# fdisk -l -u vmtest.img
  2. You must set cylinders.
  3. You can do this from the extra functions menu.
  4.  
  5. Disk vmtest.img: 0 MB, 0 bytes
  6. 255 heads, 63 sectors/track, 0 cylinders, total 0 sectors
  7. Units = sectors of 1 * 512 = 512 bytes
  8. Disk identifier: 0xbd86bd86
  9.  
  10.      Device Boot      Start         End      Blocks   Id  System
  11. vmtest.img1              63     8193149     4096543+  83  Linux
  12. vmtest.img2         8193150    10249469     1028160    5  Extended
  13. vmtest.img3        10249470    10474379      112455    6  FAT16
  14. vmtest.img5         8193213     8610839      208813+  83  Linux
  15. vmtest.img6         8610903     9028529      208813+  82  Linux swap / Solaris
  16. vmtest.img7         9028593    10249469      610438+   b  W95 FAT32

  这时我们只需要为 mount 添加 offset 参数,指定分区在磁盘映像中的逻辑地址,即可挂载这一分区。注意 offset 的单位是字节,通常一个扇区是 512 字节,因此需要用 fdisk 输出的 Start 乘以 512。以 vmtest.img3 分区为例。

  1. root@lj-laptop:/opt/vm# mount -o loop,offset=$((10249470*512)) vmtest.img ./part/
  2. root@lj-laptop:/opt/vm# ls ./part/
  3. InFAT16.txt
  4. root@lj-laptop:/opt/vm# umount ./part/

  如果有必要,我们可以将特定的分区从硬盘映像中提取出来,方便单独使用。通过 dd 可以完成提取,简便起见使用扇区大小 512 字节作为 bs 参数,这样 skip、count 参数很容易从 fdisk 的输出中计算出来。下面提取 vmtest.img5。

  1. root@lj-laptop:/opt/vm# dd if=vmtest.img of=linux2.img bs=512 skip=8193213 count=$((8610839-8193213+1))
  2. 417627+0 records in
  3. 417627+0 records out
  4. 213825024 bytes (214 MB) copied, 4.67434 s, 45.7 MB/s
  5. root@lj-laptop:/opt/vm# mount -o loop linux2.img ./part/
  6. root@lj-laptop:/opt/vm# ls ./part/
  7. InLinux2.txt  lost+found
  8. root@lj-laptop:/opt/vm# umount ./part/

  到这一步,我们已经实现了从磁盘映像中挂载或提取指定分区。其中 fdisk 帮我们完成了磁盘映像的分析,直接将分区的逻辑地址显示给了我们。现在我们再借机复习一下磁盘分区表的格式,试试手工计算相关地址。这里推荐大家阅读网上这篇《解读 Windows 操作系统分区表的秘密》,其中详解过的概念这里不再赘述,下面的内容权当对这篇文章在 Linux 平台下的补充。
  首先查看磁盘映像的主引导扇区,其中分区表位于 0x1be 开始的 64 字节。

  1. root@lj-laptop:/opt/vm# cat vmtest.img | xxd | head -32
  2. ...
  3. 00001b0: 0000 0000 0000 0000 86bd 86bd 0000 0001  ................
  4. 00001c0: 0100 83fe 7ffd 3f00 0000 3f04 7d00 0000  ......?...?.}...
  5. 00001d0: 41fe 05fe bf7d 7e04 7d00 8060 1f00 0000  A....}~.}..`....
  6. 00001e0: 817e 06fe bf8b fe64 9c00 8e6e 0300 0000  .~.....d...n....
  7. 00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

  对于 vmtest.img1 和 vmtest.img3 这两个主分区,我们读出它们的起始逻辑地址分别为 0x3f 和 0x9c64fe(注意在分区表中以 Little-endian 存储),换算成十进制与 fdisk 输出的一致。bash 的算术表达式支持十六进制字面值,挂载方式同上。

  1. root@lj-laptop:/opt/vm# mount -o loop,offset=$((0x3f*512)) vmtest.img ./part/
  2. root@lj-laptop:/opt/vm# ls ./part/
  3. InLinux.txt  lost+found
  4. root@lj-laptop:/opt/vm# umount ./part/
  5. root@lj-laptop:/opt/vm# mount -o loop,offset=$((0x9c64fe*512)) vmtest.img ./part/
  6. root@lj-laptop:/opt/vm# ls ./part/
  7. InFAT16.txt
  8. root@lj-laptop:/opt/vm# umount ./part/

  对于扩展分区 vmtest.img2,我们通过 dd 定位到它所指向的第一个逻辑分区 vmtest.img5 前面的卷引导记录,查看逻辑分区的链式分区表。

  1. root@lj-laptop:/opt/vm# dd if=vmtest.img bs=512 skip=$((0x7d047e)) | xxd | head -32
  2. ...
  3. 00001b0: 0000 0000 0000 0000 0000 0000 0000 0001  ................
  4. 00001c0: 41fe 83fe bf17 3f00 0000 5b5f 0600 0000  A.....?...[_....
  5. 00001d0: 8118 05fe bf31 9a5f 0600 9a5f 0600 0000  .....1._..._....
  6. 00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
  7. 00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

  vmtest.img5 相对于 vmtest.img2 的偏移量为 0x3f,按此地址挂载。

  1. root@lj-laptop:/opt/vm# mount -o loop,offset=$(((0x7d047e+0x3f)*512)) vmtest.img ./part/
  2. root@lj-laptop:/opt/vm# ls ./part/
  3. InLinux2.txt  lost+found
  4. root@lj-laptop:/opt/vm# umount ./part/

  沿着链式分区表的第二条记录(即链表指针)指示的偏移量,我们可以找到第二、第三个逻辑分区(vmtest.img6、vmtest.img7)前面的卷引导记录以及这两个分区的逻辑地址。

  1. root@lj-laptop:/opt/vm# dd if=vmtest.img bs=512 skip=$((0x7d047e+0x65f9a)) | xxd | head -32
  2. ...
  3. 00001b0: 0000 0000 0000 0000 0000 0000 0000 0001  ................
  4. 00001c0: 8118 82fe bf31 3f00 0000 5b5f 0600 0000  .....1?...[_....
  5. 00001d0: 8132 05fe bf7d 34bf 0c00 4ca1 1200 0000  .2...}4...L.....
  6. 00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
  7. 00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.
  8. root@lj-laptop:/opt/vm# dd if=vmtest.img bs=512 skip=$((0x7d047e+0xcbf34)) | xxd | head -32
  9. ...
  10. 00001b0: 0000 0000 0000 0000 0000 0000 0000 0001  ................
  11. 00001c0: 8132 0bfe bf7d 3f00 0000 0da1 1200 0000  .2...}?.........
  12. 00001d0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
  13. 00001e0: 0000 0000 0000 0000 0000 0000 0000 0000  ................
  14. 00001f0: 0000 0000 0000 0000 0000 0000 0000 55aa  ..............U.

  取得了相应的地址,挂载或提取分区当然是轻而易举的。下面挂载了 vmtest.img7、提取了 vmtest.img5。

  1. root@lj-laptop:/opt/vm# mount -o loop,offset=$(((0x7d047e+0xcbf34+0x3f)*512)) vmtest.img ./part/
  2. root@lj-laptop:/opt/vm# ls ./part/
  3. InFAT32.txt
  4. root@lj-laptop:/opt/vm# umount ./part/
  5. root@lj-laptop:/opt/vm# dd if=vmtest.img of=linux2.img bs=512 skip=$((0x7d047e+0x3f)) count=$((0x65f5b))
  6. 417627+0 records in
  7. 417627+0 records out
  8. 213825024 bytes (214 MB) copied, 4.65149 s, 46.0 MB/s
  9. root@lj-laptop:/opt/vm# mount -o loop ./linux2.img ./part/
  10. root@lj-laptop:/opt/vm# ls ./part/
  11. InLinux2.txt  lost+found
  12. root@lj-laptop:/opt/vm# umount ./part/

解决 Ubuntu 9.04 下启动 Dropbox 出错的问题

2009/08/02 | 16:36 | 分类:Linux与开源 | 标签: | 3,043次阅读

  尽管我对云存储还不是那么放心,但这类服务确实给广域网上的文件传输、共享和同步带来了方便。今天在朋友的推荐下试用了 Dropbox,感觉还不错,比较有用的特性便是它提供了多平台的客户端(Windows、Linux、Mac)以及与本地文件管理器(Explorer、Nautilus)的集成,不像我以前试用过的微软的 Sync 服务只支持 Windows 和 Mac。免费版的空间是 2G,对于完成非敏感文件的临时性传输、共享以及文档在跨域计算机间的同步是足够的。特别是它还提供了版本管理功能(基于 web,比较简单,不能做 diff、merge 等),解决了在公网上自行搭建 SVN 服务器的不便——这些就是我决定使用它的理由。而如果要作为备份平台,一方面恐怕需要自己再做一级文件级的加密才放心;另一方面,我还是倾向于自己管理备份文件的版本,对需要备份的文件在特定时间点做整体的归档,而版本管理工具并不是我期望的模型。
  我在 Ubuntu 9.04(Jaunty)上安装 Dropbox 后,启动时出现以下错误:

  1. lj@lj-laptop:~$ The program 'dropbox' received an X Window System error.
  2. This probably reflects a bug in the program.
  3. The error was 'BadIDChoice (invalid resource ID chosen for this connection)'.
  4.   (Details: serial 733 error_code 14 request_code 53 minor_code 0)
  5.   (Note to programmers: normally, X errors are reported asynchronously;
  6.    that is, you will receive the error a while after causing it.
  7.    To debug your program, run it with the --sync command line
  8.    option to change this behavior. You can then get a meaningful
  9.    backtrace from your debugger if you break on the gdk_x_error() function.)

  Google 得到的答案 [1]、[2] 大多是通过安装 Dropbox 的 experimental build 或所谓非 Nautilus 版本来解决。不过我还是找到了一个更简单的解决方案在安装 Dropbox 及其 daemon 之后断开网络连接,然后启动 Dropbox,现在它的设置对话框便可以正常弹出并报告网络连接错误。这时只需要恢复网络连接,并点击“Reconnect”按钮,Dropbox 就进入了正常工作状态。重新启动计算机之后也没有问题。
  顺便广告一下,目前邀请朋友注册 Dropbox,邀请方和被邀请方都可以得到额外的 256M 空间,累计最多可升至 5G 免费空间。如果有兴趣,不妨通过我的推荐链接来注册,双方都受益。

浅谈存储系统的信任边界

2009/06/02 | 15:02 | 分类:IT杂谈 | 标签: | 3,680次阅读

  云计算这两年炒得风风火火,云存储作为其重要组成部分也被商家吹嘘得神乎其神。我赞同云存储在可扩展性、可用性方面的优势,但仍对这类技术缺乏信任感。我所谓的不信任,不只是说数据托管、网络传输在安全性、可靠性等方面存在隐患,更主要的是对这种高度透明的接口背后隐藏的复杂的、不透明的实现机制的不信任。
  开发者采用先进的技术是在增强人们对系统的信任度,还是在减弱人们的信任感呢?我想多数负责任的开发人员的主观目的是要让系统更加安全可靠,增强人们对系统的信任。但客观上,越来越复杂的实现往往会超越当时用户的理解和可控范围,冲击用户的心理接受能力。用户由这种无知、少知导致恐惧,进而对复杂的、难以琢磨其运行机理的系统产生抵制情绪。

浅谈存储系统的信任边界

  早期纸带和磁带上线性存储的文件系统的表示格式是容易理解的,但它也是脆弱易损的。各种校验机制的加入恰如其分,它们既提高了数据的可靠性,同时算法复杂度低,不仅对机器来说开销小,更重要的是大多数技术人员能够轻易地学习和理解其实现。因此,用户(当年主要是有一定技术能力的专业人员)对这种存储系统的信任是平衡、对等的。现代的NTFS、ext3、ZFS等文件系统采用了复杂的数据结构、日志、快照等机制进一步提高了数据的可靠性和安全性,尽管大众用户对此一无所知,程序员人群中能讲清楚一个现代文件系统细节的远比会算校验和的要少,但这些技术毕竟是公开(或事实上公开)的,在渐进的发展过程中已经被广泛使用,经受了研究人员与竞争对手的检验。对一般用户来说,对这些系统的信任来自于第三方权威或公信。然而多数云存储系统对用户来说都是一个黑盒,这不是它的缺陷,而是它的特性。云计算本来就强调虚拟化,对用户屏蔽其内部实现是理所当然的。但是由于各自为政的局面没有打破,业界缺乏统一的技术标准,针对云存储的权威或公信力量也许比针对本地存储系统的更难建立。
  Windows 7也是最近的一个热门话题。Windows 7中会不会集成WinFS?现在不同途径的消息不一。其实我挺期待这样一套方便结构化组织与检索数据的存储方案,但WinFS能否满足用户的信任需求?WinFS的部分API已经在.Net Framework中公布,按照微软近期的风格,WinFS技术完全开源也不是没有可能的,但它的复杂程度应该不低。有耐心的技术人员也许可以深入理解它的实现机制,但理解并不等于可控。WinFS要达到高度语义化的组织与检索,势必使得数据的元信息处于动态变化中,同时要允许第三方软件操作数据的元信息及其关联。也就是说,尽管WinFS有可能是一个白盒,但状态空间的急剧膨胀有可能使得它超出用户的可视、可控范围,变得与黑盒无异;多种第三方机制的介入能否保证系统最初定义的原则不被破坏,会不会引发一系列误用或滥用问题?这些都难以定论。
  公开的技术和统一的标准可以增强系统的公信支持程度,进而让用户对系统的实际心理信任有所提升、信任边界得以扩展。不仅仅存储系统应该如此,一切基于新的复杂技术的服务都应该保证不触及用户的心理认知底线,否则就会陷入“Big Brother”的尴尬境地。