[译文]Ext4新进展:bigalloc, inline data, 和元数据校验和

February 4th, 2012 by gnawux No comments »

原文:http://lwn.net/Articles/469805/
原作者:Jonathan Corbet
原文发布时间:November 29, 2011
译者:王旭 ( @gnawux ;  http://wangxu.me/blog/ )
翻译时间:2012年2月3日

ext4是一个刚刚发布一两年的文件系统。不过,这个坚实稳定的系统是基于一个很古老的设计演化而来的。对于一些被作为“下一代文件系统”开发的 FS,比如 btrfs,本文要提到的一些特性可能都已经具备了。然而,btrfs这样的文件系统还需要相当长的时间,才能在更广泛的用户群中获得足够的信心,同时,日益增长的 ext4 用户对这些特性同样心仪已久。近来提交的一些补丁就让我们看到,虽然 ext4 在很久以前就已经进入一个相对稳定的阶段了,但新特性的开发也并未停止。

Bigalloc

在 Linux 早期,磁盘的大小还是MB级的,文件系统的块大小也只是 1KB 到 4KB。而在本文写作的时候,TB级的硬盘虽然在最近涨了一点价,但无碍一个事实——硬盘已经变大太多了,存储在上面的文件也是如此。但 ext4 文件系统仍然以 4KB 为单位来管理数据。其结果就是要管理的块数太多了,相关联的位图大小必然随之增长,管理这些块的开销也就极具增大。

在内核中增加文件系统的块大小会对内存管理、page cache 等产生深远影响,因此是件很恐怖的工作。所以大家都不愿意一下子触及这么多地方,但这并不能阻止文件系统被放在越来越大的磁盘上。在 3.2 内核中,ext4 将可以解决这个问题。“bigalloc”补丁给文件系统引入了一个“块簇(block cluster)”的概念,这样,在一个更大的块组中进行分配时,将一次分配一个块簇而不是一个单独的块。在内核中,这些更大的块和原始的4KB块的映射关系由文件系统负责维护。

簇的大小由管理员在创建文件系统时确定(使用 e2fsprogs 的一个开发版本),不过这个值必须是 2 的整数次幂。在很多情况下,64KB 是个合适的值,对于那些只存放大文件的文件系统,1MB 的簇大小可能是更佳选择。必须指出的是,如果文件系统专用于存放小文件,那么指定一个过大的簇大小回造成很多空间浪费。

使用簇可以减少块位图和其他管理用数据结构的开销。但是,根据 Ted Ts’o 在 7 月份给出的数据。因为这个特性可以降低磁盘的碎片化,对文件IO的性能同样有改进。这个特性预计会成为 3.2 内核(以及 e2fsprogs 1.42)对很多用户的一个杀手级特性。

inline data

inode 是文件系统中用于描述一个文件的数据结构。对于大多数文件系统而言,有两类 inode:文件系统无关的内核数据结构(struct inode),以及文件系统相关的 on-disk 版本。常规地说,如果内核没有一份 inode 的副本的话,就根本无法操作一个文件。所以,本质上说,inode 是很多 block I/O 的关键入口点。

在 ext4 文件系统中,磁盘上的 inode 尺寸可以在文件系统创建时指定,缺省是 256 字节。不过,磁盘数据结构(struct ext4_inode) 只需要大概一般的空间。ext4_inode 结构之后剩下的空间通常用于存储扩展属性。比如 SELinux label 就存放在这里。在没大量使用扩展属性的系统中,磁盘 inode 结构的空余空间就直接浪费掉了。

同时,文件数据的空间分配是以文件系统块为单位的,与 inode 彼此独立。如果一个文件非常小(即使在现在的文件系统中,还是有很多小文件),用于存放这个文件的块就浪费了很多空间。如果文件系统使用了上面提到的块簇,那么浪费的空间还会更多,这里,用户可能就会开始抱怨了。

马涛(@淘伯瑜)同学的 ext4 inline data 补丁将会改变这一局面。这个想法非常简单:很小的数据可以直接存放在 inode 之间的空余空间里,根本无需单独分配数据块。对于使用 256个字节的 inode 的文件系统,全部空余空间将会被用于存放这些小文件。如果文件系统使用更大的 inode,只有一半的剩余空间会用于存储文件,剩下的空间留给后面可能要添加的扩展属性,否则的话,这些扩展属性就不得不存放在 inode 之外了。

涛哥提到,在使用了这个补丁的情况下,用于存放内核源码的空间会减少大约 1%,而 /usr 会减少大约 3%。当启用簇之后,节省的空间应该会更多,但这也不能保证对所有情况都能减少。仍然有些细节问题没有完全完成——包括 e2fsck 支持以及扩展属性存放在 inode 之外带来的开销——所以,这个特性最早要在 3.4 kernel 中才会出现。

元数据校验和

存储设备并不总是像我们期望的那样可靠的,由于硬件原因造成的数据损坏案例屡见不鲜。正因为如此,关心数据安全的人们使用了 RAID 这样的技术,或者像 Btrfs 这样的文件系统可以保存数据和元数据的校验和,以确保内容不被硬件弄丢。不过,ext4 文件系统没有这一能力。

Darrick Wong 的校验和补丁并没有解决全部问题。实际上,它似乎进一步印证了那个老笑话——文件系统开发者并不真的关心他们存储数据的正确性,只要文件系统的元数据没错就行了。这组补丁通过给 ext4 文件系统的各个数据结构加上校验和,包括 superblock、bitmap、inode、dir index、extent tree 等,并在读取时检验校验和,以保证元数据的正确性。校验和失败可能导致文件系统失败,如果这发生在一个挂载着的文件系统上,会把它变为只读,并在系统日志中输出一些相关信息。

Darrick并未提及任何给用户数据添加校验和的计划。给数据添加校验会是一个更宏大的工程——为已有的元数据数据结构添加一个校验字段相对简单,但要存储数据块的校验和就得给文件系统增加全新的数据结构了。而且,全数据校验的性能损失也会更高。所以,尽管未来可能有人会来介入这个问题,但迄今为止还没有这个动向。

即使只是元数据的校验和,对文件系统的改变仍然是很大的,不过相当一部分工作是属于 e2fsprogs 的。特别的,e2fsck 将具有检查元数据校验和的功能,并在某些校验和出错时进行修复。校验和可以在 mke2fs 时打开,或是通过 tune2fs 开启。总的说,这是个很大的工作,但确实可以帮助用户增加对文件系统结构的信心。根据 Darrick 的介绍,计算和检验校验和的开销在大部分情况下是可以忽略不计的。这个特性目前还没有收到很多反馈,或许已经接近被接纳进内核,但还不清楚什么时候会进来。

回忆2011

January 3rd, 2012 by gnawux 2 comments »

总得在什么地方记录一下自己的一年吧,呵呵,这里似乎蛮清净的。嗯,没什么条理,想到哪写哪。

2011年对我来说还是有很多重要意义的——3月份儿子三岁上幼儿园了,回来和我们一起住了;5月离职换工作了,人生第一次;6-7月在上海过的,动不动穿梭在京沪之间,还坐了几次京沪高铁;10月份在QConHangzhou 主持了云计算的 Track,结识了不少技术圈的前辈和大牛⋯⋯

一年的跨度实在是挺大了,我都回忆不起来斯屹刚刚从爷爷奶奶家搬回到爹妈家是什么状态了,但他的幼儿园生活似乎还是挺顺利的,他喜欢幼儿园的生活,也喜欢和父母在一起,长大了不少,虽然还是个不怎么懂事的小屁孩,可也还是我们的心肝宝贝儿。希望他慢点长大,被孩子依赖的感觉,让人觉得活得很真实、很有味道,很舍不得他长大。

换工作给我的影响太大了,以至于我总觉得这就是这一年的主题,而且对一幕幕记忆犹新。我不想再祥林嫂一样重复换工作前后的那些苦逼或者狗血的对话,只想回顾一些真实的感受。

盛大不论如何也不算是个“最佳雇主”,而前单位“中国移动”倒确实是很多人心目中的最佳雇主,但是,我必须承认,我的跳槽,当然不是出于什么“社会责任”(某同事的玩笑),待遇之外,还有一点就是我没能力也不喜欢去做一个以领导为中心的工作,我觉得那样对不起自己;我愿意做我喜欢的——技术有关的工作。

很荣幸,这边的老大是个比较直率的人,而且给了我很多的信任,不仅让我重新回到技术工作之中,更给了我参加QCon等会议的机会,让我和技术圈中的大牛们有更多的接触机会。

说到遗憾,一方面,我对完全的开发工作其实还是爱很多,但不完全熟练,毕竟读博几年加上前单位的环境让我有些生疏了,我需要更加努力;另一方面,离开做了很长时间的Hadoop也有点不舍。

虽然目前的工作也时常有不理想的地方,但并没有超出我的预想,我在跳槽的时候也没有期望到一个完全理想的地方,总的来说还是满意的。希望今年的工作做得更有力,做出点东西来,至于更远的下一步,还没有太多考虑。

如果恶魔城之前给我offer的话,很难说我现在在什么地方,唉,难掩对那个前几天拿到恶魔城 offer 的同学的羡慕嫉妒恨啊。

2011年带给我的另一个感受是,家中的老人都在真实地衰老,衰老得自然而然却又让人不愿面对,希望2012他们都健康。

2011年最后一次版聚小记

December 12th, 2011 by gnawux No comments »

感谢彭涛(bergwolf)、李凯(郁白)、朱延海和 Coly 的到场,这次版聚虽然只有一个主话题,但是由于有这么多到场者的深度参与,变得很有趣、很有收获。特别感谢 bergwolf 熬夜准备片子,还有李凯为每个环节配上小故事。

按:之前由于各种苦逼原因,版聚一度中断两个月之久,在此危急存亡的时刻,hzmangel 同学挺身而出组织了这次盛会,我很荣幸地帮助预定了盛大创新院(北京)的会议室,bergwolf 贡献了 aio 的 topic,至此本年度12月版聚得以正常举行。

到场同学

具体到场同学就不一一点名了,大家可以看邮件列表,值得一提的是,这些同学有千丝万缕的联系:

  • 有四个人是互为同学来的
  • 有两个人是同一个组的
  • 有两个人是同事
  • 有一个人和上面同一个组的人不是同一个组的,和上面两个同事的五个同事或前同事是前同事
  • 有一个人和上面四个同学中的一个是同学

同学们,你们明白了么?

序曲:async/sync vs. blocking/non-blocking

这个话题被认为上次在 SNDA 会议室已经搞清楚了,可实际情况是——

当 Coly 出现后,问题再次变得混乱起来,

好吧,我们承认,这两对概念的两两组合足以让人抓狂,结论是:大家要记好了,名字叫 non-blocking 的就是 non-blocking,名字叫 async 的就是 async,嗯。

这个争论的价值是:

  • Coly: 对于用户程序,不论是否有 NON_BLOCKING 标志,都必须检查 read 的返回值是否达到了请求值,也就是说,即使 read 返回了 >0 的值,也可能会小于请求值,如果没有,需要循环请求,直到全部读完。
  • Bergwolf: 对于文件系统的实现者,对于 buffered IO,在没有信号中断的情况下,read 请求如果不失败,返回值不应该小于请求值。如果小于请求,应该视为一个 Bug。

感谢 coly 和 bergwolf 从不同角度对这个问题的阐述。

插曲:郁白的DIO故事

事实上,本次版聚是由李凯同学来主持的,每一段他都有一个小故事。对于这里,郁白同学介绍——

他曾经使用 DIO 模拟 append,这时,如果超出 512B 的块大小,需要补齐再 truncate 回来,有时会发生 EIO,求解答

经过 coly、bergwolf、朱延海等同学的合议,认为这个问题有可能是 journal 的 bug,因为郁白同学仗着自己使用了很好的 raid 卡,对 journal 区域进行了疯狂的操作,在一次 append 中,最差情况可能有 5 次 io,而且由于他经常 sync,还丧失了合并日志操作的机会,在这种极端情况下,可能会触发 journal 的某个深藏的 bug。

正文上半场:POSIX AIO

简单地说,POSIX AIO ( aio(7) )是由 glibc 使用 pthread 在用户空间实现的,由于实现的比较粗糙,没有线程池等机制,这一实现的性能比较低劣——说到这里,有几位同学灰心地苦笑了一下。

本日出镜最高的郁白同学介绍——Linux 中的 POSIX AIO 实现没有线程池,而且有可能有锁冲突,还可能有其他bug,所以导致性能低下,大约为 pread/pwrite 的 1/3;如果自己妥善地实现一个用户空间 AIO 的话,性能和同步 IO 的性能应该是基本一致的,当然,上下文切换可能是不可避免的。

朱延海这里有一个想法,是否可以用非阻塞读写和 select/epoll 来做一个更好的 AIO,殷宇辉同学表示 libeio 可能已经这么做了。

正文下半场:Native AIO

kernel 态的 Native AIO 性能上没有什么问题,但是,它有一些限制——

  • 只支持 AIO-DIO
  • 不支持 fsync/fdatasync
  • 不支持 socket/pipe

并且,bergwolf 表示,据他前一晚上写片子时看代码,ext4 的 aio 似乎没有用上,coly 和朱延海对此不太相信,大家表示后面会再继续研究一下。

郁白同学此时又有提问:有时 get events 的时候 get 不到,这时内存中用于 io 的 buffer 是否可以安全释放?经过一段讨论,结论大致是这样的:

  • 首先,IO 用的 page 是 lock 住的,实际不会被释放掉;
  • 其次,libc 中,free 并不一定会还给内核,而可能会重复给其他进程用;
  • 这时,如果内存我们还给 libc,libc 又分给其他 malloc 用,在 IO 完成时可能回冲掉这块内存,从而造成了后一个 malloc 不安全

所以,这时的内存释放和管理需要谨慎。

总结 by 郁白

作为每个环节都有话说的李凯同学,这时给了一个总结:

他比较喜欢用户态的实现,如果有个靠谱的用户空间库,他不太喜欢使用 native 的实现。

版聚笔记到此为止,linuxfb 2012 见。

看展台的烦心事

November 18th, 2011 by gnawux No comments »

话说最近有两件事很郁闷,一是云计算这个概念从总体上讲继续不靠谱,而且没有变靠谱的趋势,这件事不是最郁闷的,最郁闷的是第二件——我得跟别人说,我是做云计算的。只希望云计算赶快退热,让那些浮云被风吹走吧。

先声明啊,我不是在攻击同行啊,不指责同行是我的一个个人准则,更不是说自己的公司不靠谱,不靠谱还做什么呢。

前不久在 QCon杭州主持了云计算的 Track,那时候看到的是——BigData 与云计算的概念逐步分离,云计算成功实践已然浮现,技术圈对云计算的看法趋于冷静、理智,找到了适于和不适于云计算的场景,对于追捧、炒作、质疑都或泰然处之、或辨清曲直、或接受面对。似乎“大家”都可以好好做事、为用户服务了。

然而,我忽视了一个事实——那个小小的技术圈还算不上“大家”,技术人员对社会的影响力是很小而且不直接的。

这两天在高交会看展台,满眼政务云、医疗云、安全云、物流云⋯⋯依然是不知所云、人云亦云。各路政府、机构、厂商,有的本来就对概念一知半解,有的为了自己的利益故意混淆是非,让本来已经逐渐清晰化的概念又在模糊起来了。更残酷的事实是,正是这些宣传在影响着更多的人,而不是我们技术小圈子的共识,现在,那些花50块钱进来看展览的叔叔阿姨们也知道了有这么多朵云了,知道所有东西都可以是云了⋯⋯对我来说,痛心疾首啊,我只想,让云赶快退烧,我们换一个技术名词吧。

好了,说了这么多,我来给云下王氏定义了:

不计自称为云的 SaaS 模式(此模式由来已久、变化不大、仅是在名词上划为了云,我们不评论它,这里的讨论也不涉及它,我更没有能力和兴趣来界定它),过去几年谈的云已经划分为了两个主流的概念:

  • 用大规模系统、服务大规模用户,这样的服务还叫云,其外在的特征表现为快速弹性(快速扩展与收缩服务能力)、用量计费(按照精确的消耗时长、空间、和流量)、按需自助服务(通过页面或API自助服务),而其内在特征则是细粒度、高效率、高可靠、自动化的资源池;【此定义参考了米国国家标准学会的定义,搞了很久无厘头的云计算标准化,这方面还是有点积累的,呵呵】
  • 用大规模系统、处理大规模数据,这样的应用现在叫BigData,其核心竞争力在于利用PC级硬件集群,存储海量数据,在适当建模的基础上,进行大规模分布式处理,高效的任务分解与调度,提供较以往的数据库或数据仓库类产品更高的容量和更强大的处理能力。

当然,你完全不必接受我的定义,这是我在自己的博客上的闲言碎语,也不打算在这里争概念,有不同见解的,请另找地方发表高见,我不支持你在本文后面的评论里写你的简介,唯一的原因就是——我觉得闹心。

我的愿望很简单,剩下的这部分最好也别叫云了,咱要么叫原来的名字,Utility Computing,好不好?至于那些在云或“类云系统”(请允许我这么称呼那些功能不全、规模不大的小型平台)上工作的服务,咱们也别叫XX云了吧。

嗯,就这样,我的简单的愿望不知道哪天才能实现啊⋯⋯

[译文] SCSI Target 之双城记

November 18th, 2011 by gnawux No comments »
作者:Goldwyn Rodrigues
原文发布日期:January 22, 2011
来源:http://lwn.net/Articles/424004/
译者:王旭( http://wangxu.me , @gnawux )
翻译时间:2011年11月17日

按:上次翻译 LWN 的文章似乎还是 两年前翻译空指针的乐趣的事呢,时间好快,这次来深圳高交会看展台,晚上无聊,就翻译了这个。作为这个故事的结局,LIO已经在 2.6.38 进入 kernel 了。

2010年底,LIO 项目获选成为新的内核态的 SCSI target,取代原有的用户态的 STGT 项目。当时有两个主要的竞争项目(LIO和SCST),都在努力将代码并入主线内核。本文将比较着两个项目,并尽力描述他们都提供了什么东西。

什么是 SCSI Target?

SCSI 子系统使用了一种客户机-服务器(C/S)模型。通常,一台计算机是这个模型中的客户机,称为 initiator(发起者),想 target (目标)发起块操作请求,这个 target 通常是一个存储设备。SCSI Target 子系统可以让一台计算机作为一台 SCSI 存储设备来工作,响应其他 SCSI initiator 节点的存储请求。这样就可以定制 SCSI 存储设备,并让存储设备工作得更加“智能”了。

一个智能 SCSI Target 的例子是Data Domain的在线备份设备,它具有数据排重的功能,可以节约空间。这个设备从功能上说是个 SCSI target,但它实际是一台智能的计算机,它只存储那些还没有的数据块,对于已经存在的数据,只是增加引用计数,这样只写入那些上次备份之后有变动的块。而在 SCSI 连接的另一边,initiator 看到的设备就是一个普通的、共享的 SCSI 存储设备,只要使用任意的备份软件,将备份写向这个 target就行了。

最常见的 SCSI target 子系统的实现是 iSCSI 服务器,它使用标准的 TCP/IP 来封装 SCSI 指令,通过网络来提供一个 SCSI 设备。大多数 SCSI target 项目在最初都会先支持 iSCSI 协议。这事因为 iSCSI initiator 和 iSCSI target 之间只需要一个网络连接,差不多所有计算机都可以使用,对它的支持不需要任何特殊硬件。不过,大部分的 SCSI target 还能支持已有的 initiator 卡,所以,如果你又一个光纤通道、SAS 或并行 SCSI 卡,可能某个 SCSI target 项目可以支持这些特定设备的 SCSI 总线。

当前状态

当前 Linux 内核的 SCSI 子系统使用 STGT 来实现 SCSI target 功能;STGT 是在 2006 年末,由 Fujita Tomonori 引入的。它在内核中有一个库,来配合内核中的 target 驱动工作。而所有的 target 处理都在用户空间完成,这可能回带来一些性能瓶颈。

有两个还没有并入内核的 SCSI target 实现尅考虑用来替换 STGT:LIO SCST。SCST 至少在2008年就试图推入 Linux 内核。当时认为 STGT 项目海可以为内核服务稍长一段时间。但随着时间的推移,STGT 的设计局限被发现,并且有了一个可用的替换方案。替换 SCSI target 子系统的主要条件是由 James Bottomley 确定的,他是 SCSI 的维护者,条件如下:

  1. 它将更换掉已有的 STGT,因为只能有一个 SCSI target 基础设施。
  2. 要使用现代的、基于 sysfs 的控制与配置方式。
  3. 代码要被仔细审查,确定足够干净、可以进入内核。

第一个条件被证实太过于严苛了,会不可避免地破坏整个 ABI。所以,当前的目标变成了寻找一种方法,来让 STGT 用户平滑地过渡到新接口上来。

LIO 替代 STGT 的项目开始于 2010 年的 Linux 存储与文件系统峰会(LSF 2010)。Cristoph Hellwig 志愿来审阅并清理代码,他尽力将代码缩减到一万行以内,使之可以被并入内核。

对比

两个项目都在他们的官方网站(LIO 和 SCST)上提供了他们的特性对比图表。不过,在探讨它们的不同之前,先来看一下相似性吧。两个项目都实现了一个内核态的 SCSI target 核心。他们都提供了类似 loop device 的本地 SCSI target,这让使用他们的 target 创建虚拟设备变得很方便。两个项目都支持 iSCSI,这是他们的项目的最初的也是最主要的动机。

两个项目的后端存储管理都可以在内核空间或是用户控件进行。后端存储管理器让 target 的管理员可以控制设备如何输出服务给 initiator。比如,pass-through 后端允许将一个 SCSI 硬件直接提供给用户,而不屏蔽掉这个设备的任何细节;而 virtual-disk 后端则允许将一个文件作为虚拟磁盘来输出给 initiator。

两个项目都支持永久性预留(Persistent Reservation, PR);这是一个用于高可用集群中的存储设备的 I/O 隔离与存储设备故障切换、接管的特性。通过使用 PR 命令,initiator 可以在一个 target 上建立、抢占、查询、重置预留策略。在故障接管过程中,新的虚拟资源可以重置老的虚拟资源的预留策略,从而让故障切换更快、更容易地进行。

SCST

SCSI target 子系统的主要用户是提供存储解决方案的存储公司。大部分这些存储解决方案都提供了即插即用的设备,可以只进行很少的配置,甚至是无需配置,就被加入到一个存储网络。SCST 拥有更广泛的用户群,这可能是因为它们支持更多的传输方式。

SCST 支持 Qlogic 和 Emulex 的光纤通道卡,而 LIO 目前只支持 Qlogic 的 target 驱动,并且这个驱动也还在 beta 测试截断。SCST 支持 SCSI RDMA 协议(SRP),并宣称对于以太网传输的光纤通道协议(FCoE)、LSI 的并行 SCSI 光纤通道以及串行 SCSI(SAS)等协议的的开发也处于领先地位。目前,它已经对 IBM pSeries 的虚拟 SCSI 提供了支持。目前,Scalable Informatics、Storewize、Open-e 等公司都基于 SCST target 开发了它们的即插即用设备。

SCST 可以使用异步事件通知(AEN)来通告会话状态的变更。AEN 是一个 SCSI target 用来向 initiator 进行 target 端的事件告知的协议特性,即使在没有服务请求的时候也可以进行。于是 initiator 就可以在 target 端发生事件时,如设备插入、移除、调整尺寸或更换介质时,可以得到通知。这让 initiator 可以以即插即用的方式看到 target 的变化。

SCST 的开发者声称,它们的设计在健壮性和安全性方面更加符合 SCSI 标准。SCSI 协议要求,如果一个 initiator 要清除另一个 initiator 的预留资源时,预留者必须要得到清除通知,否则,多个 initiator 都可能来改变预留数据,就可能会破坏数据。SCST 可以实现安全的预留、释放操作,避免类似事情发生。

依照 SCSI 协议,initiator 和 target 可以协商决定传输尺寸。一个 initiator 端错误的传输尺寸通信可能会导致 target 设备端的锁死或是崩溃。SCST 的安全保障机制可以在传输尺寸或方向出错时避免这个问题。他们的代码中具有良好的内存管理策略来避免内存耗尽的情况。还可以限制介入 target 的 initiator 的数量,避免过多连接占用资源。SCST 还支持每个 portal 的可见性管理,也就是说,可以让一个 target 只对一组 initiator 可见。

LIO

LIO 项目最初是以 iSCSI 作为核心目标的,创建了一个支持 iSCSI 的通用 SCSI target 子系统。简单性是项目的一个重要设计目标,因此,LIO 也更容易理解。除此之外,LIO 的开发者表现得更乐于和内核开发者合作,正如 James 对 SCST 的维护者 Vladislav Bolkhovitin 所指出的:

来,让我们把事情说得简单一点:在这个社区里,不是让你直接把菜上到桌上就行了,你需要加入到这个社区当中来,称为 linux 内核社区的一部分。更广泛的社区焦炉是开源项目成功的必要条件。你曾经有过这样的机会了:我们在其他地方已经使用了 sysfs,但在 STGT 这里,你就说了一句——这事我们的接口,用它好了。而 LIO 则问了他们所需要的东西,并设法来使用 sysfs 接口。事已至此,你为什么还会对 STGT 的人更倾向于 LIO 而表示大惊小怪呢?

LIO 项目还提供了一些 SCST 没有或刚刚开始开发的特性。比如,LIO 支持非对称逻辑卷分配(ALUA)。ALUA 允许 target 管理员来管理 target 的访问状态和路径属性。这让多路径路由机制可以选择最好的路径,从而根据 target 的访问状态,优化带宽的使用。换句话说,在多路径环境下,target 管理员可以通过改变访问状态来调整 initiator 的路径。

LIO 海支持管理信息数据库(MIB),会让管理 SCSI 设备更简单。SCSI target 设备可以按照 RFC4455 SCSI MIB 的描述方式来输出管理信息,这些信息会被 SNMP agent 收集起来。这个特性扩展了 iSCSI 设备,在管理有很多 SCSI 的存储网络时好处会更加明显。

iSCSI 连接的错误可能会发生在三个层面上:会话、校验或是连接层。错误恢复工作也可以在这三个层面开始进行,这样就可以在当前的层面开始进行恢复,不会让错误到达下一个层面。错误恢复首先是检查断开的连接。在这种情况下,iSCSI initiator 驱动会主动建立新的到 target 的 TCP 连接它会告诉 target,SCSI 指令路径已经变到新的连接上了。这样 target 就可以在新的连接上处理 SCSI 命令了。这时,上层的 SCSI 驱动对新的连接已经建立、控制信息已经通过新连接传输的事还是毫无知觉的。iSCSI 会话在这期间会保持正常,不会重新变换状态。LIO 支持的最大错误恢复级别(ERL)为2,这就是说,它可以在会话、校验或连接层进行错误恢复。而SCST 支持的 ERL 为 0,也就是说,它智能恢复会话级别的错误,所有连接层面的错误都会转到 SCSI 驱动层面来处理。

LIO 还支持“会话多连接”(MC/S)。MC/S 让 initiator 可以和 target 在一条或多条物理路径上建立多条连接。这样,在一条路径发生错误的时候,已经建立好的会话可以不中断会话,直接使用其他的路径。MC/S 还可以用来进行所有连接之间的负载均衡。这种情况下,会在所有通信路径上保持会话命令的顺序性。

LIO 还宣称,他们的代码被用于了很多设备之中,虽然他们的用户看起来和 SCST 的差不多。

没有性能对比的对比不是个完整的对比。SCST 的开发者经常会放出他们的性能数据。但是,所有数据都是和 STGT 进行的对比。SCST 的对比页面说,他们的性能好于 LIO,但是是根据代码研究而非真实世界测试的结果。SCST 指责 LIO 没有发布数据,(在我的印象里)确实没有性能数据来在两者之间进行直接对比。

不过最后,决定已经做出了,虽然有一点反对的声音。现在的任务就是把所有 LIO 没有但有用的特性从 SCST 移植到 LIO 来。尽管这个决定有些争议,但这俨然又是一次试图把不能和内核社区合作的代码并入内核的失败尝试。

 

不客观地对比一下移动Edge和联通WCDMA的业务

September 16th, 2011 by gnawux No comments »

嗯,首先声明,这是不客观评价,不同的人、不同的应用会有不同的结论,我的结论就是我的感觉与我的选择,读者可以参考也可以不同意,没必要来跟我争什么,当然,有什么我不知道的也请告知我。

公平与不公平

作为之前四年都在中国移动工作的同学,如果我心里没有偏向某一方的话,那简直是不可能的,这个我不仅承认,而且可以认为是我开始评价的一个前提。很多人都认为中国移动比中国联通靠谱,其实我也是这么认为的,而且对此更加深信,但是我也不得不承认,某些环节上,中国移动也很不靠谱。

对比 EDGE 和 WCDMA 本身可能就是不公平的,200K 和 5M之间似乎没什么可比性,但是,对于大量持有一款水货 WCDMA 手机的用户而言,移动或联通,也就是 EDGE 和 WCDMA 的一个对比,用行货 TD 智能手机的,如果不是换的手机,应该就是送的手机,花钱给买个 TD 智能手机,自己成天手机上网的用户,我是觉得比较另类啊。

嗯,顺便说,即使是 TD 和 WCDMA 的对比也是不公平的,单一的1.6MHz频段对一对5MHz频段,是6倍的关系啊。

结论放在前面

准备这样:

  1. 联通网络的地面覆盖还是不错的,地下就别提了,总体评价,大部分情况下是比移动的EDGE有优势的。
  2. 联通的电话套餐吸引力不足,过这个月后消掉联通的这张电话卡,维持原有的移动号码。
  3. 联通的上网卡套餐其实不错,准备后面买一张专门的上网的资费卡,配个mifi玩了

业务的对比和一些揣测

首先说说购买和入网,这方面联通做得很不错,网上商城可以直接选号、送到家,与移动相比的一个最大的优势是可以在开通当月就使用套餐。移动的 BOSS 系统提供这个很难么?必须逼着用户在月底才能入网么?简直不能接受啊。当然,网上的免费的联通的3G 号码没什么好号,估计没有不带4的。另外,不知道是联通的渠道策略问题还是经销商管理问题,很多淘宝商家都能买到不同价格的资费卡,对于用户的口袋可能有好处,但背后的混乱也有一点隐忧,而且担心可能会影响到出问题之后的处理。

卡到手之后说说覆盖,我有几天差不多是在外面跑的,感觉上联通在市区干道上的覆盖挺不错的,不仅一路上都有 3G/HSPA 覆盖,而且连接上 L2TP VPN 之后也基本不会断,这是相当不错的质量了。作为手机用户,我对速度没有明显的快的感觉,但应该不算慢,比较满意。不过在地铁里的覆盖就不敢恭维了,全程没看到过 H 和 3G 的字样,当然,也不能说一直都是 G,确实有的时候连 G 都没有。不过就冲地面的覆盖的质量,还是值得弄一张来上网的。

再来说说套餐和资费。联通的手机套餐分为A B C 计划,其中A计划是针对上网用户的,流量相对较高,但是流量实际也不算高,66块钱的套餐配有 300MB 流量,问题是之后价格的提升和流量的增长是不成比例的,将近两倍价格的 126 块钱的套餐也只有 400MB 流量,和常理中的“越高流量越便宜”明显相悖。并且,不像移动一样,提供附加的流量套餐。这里,我只能理解为联通对自己的网络容量没有信心,担心用户流量过高了。不过,上网卡支持到半年3G或1年6G的套餐还是不错的,而且可以买到便宜的,这方面不太容易理解啊。

最后说说渠道。首先说网上营业厅,移动联通真实不分伯仲的差啊,在网站的 UED 方面都非常渣,不说啥了。呼叫中心方面,我感到联通 10010 的 mm 说话比 10086 冷很多,虽然我还是给她打了“满意”,但说实话感觉她们不太专业,用户问到没有的东西的时候,完全不加解释,直接说“没有”,也不会为用户推荐任何可能的替代方案,她说了“没有”之后,我都不知道说啥好了⋯⋯

就对比这么多吧,嗯。

花絮

唯一的花絮是——我的手机拒绝显示“中国联通”字样,所有插入中国移动卡时显示“中国移动”字样的地方,换上联通的卡之后,都是空白,没有任何内容。我的手机是Moto Milestone (WCDMA),非定制机,CM7 的 ROM,Android 2.3.5 ,跟 OPhone 没有什么瓜葛。

有道理的有时是行不通的

September 15th, 2011 by gnawux No comments »

这两天和儿子玩以及和老婆吵架想到的,不是想说谁对谁错啊,就是说点感受。

昨天和3岁半的儿子玩球,发现捡球这事情是这样的:

  • 对于没接到的球,说服儿子是他没做好,让他捡球是困难的;
  • 但是,接受儿子的结论,然后问他能不能帮忙捡一下,是可以被欣然接受的,即使球比较远也可以,只要再说声谢谢
  • 而且,如果跟儿子商量石头剪刀布,赢了的捡球,那么他会抢着赢,甚至有些在我脚边的球,他都要求石头剪刀布

这就是说:

  1. 如果让人有被请求的感觉,对方是可以接受一些本不乐意的事情的
  2. 如果让人有胜利的骄傲,对方甚至会很愉快地做这样的事情

捡球这事骗骗孩子还行,大人就没戏了,但大人的世界有时也很类似,简单的一句话说,就是——

争辩赢得了道理,但不一定能赢得到最后的结果。

这事情在家庭这种感情因素比重很大的地方尤其适用,对付 bug 啥的我还有点招数,对付老婆方面,我实在是束手无策。最常发生争吵的事情就是:

  • 自认为有理的时候,老婆坚决拒绝低头,针锋相对,然后⋯⋯
  • 自认为委屈的时候,老婆坚决不予同情,赶尽杀绝,然后⋯⋯

嗯,最后结果当然都是我惨败啊。不知道两种情况是不是互逆的啊,呵呵,完美的换位思考这事,真的不是人类能做到的啊。

武夷山游记

August 22nd, 2011 by gnawux 5 comments »

抓紧时间记一下,迟了就忘了⋯⋯

这里分成山水篇、住行篇和往返篇,分别介绍这次玩的主要景区、武夷山的衣食住行、以及往返的路程,每部分最后都总结了一下一点心得,供参考。

山水篇

这次在武夷山玩了四天,这里按顺序分别记述每天的行程。

保护区:青龙瀑布和龙川大峡谷

8月14日当天早上不到7点,到达了武夷山,到住处吃早饭时,刚好遇到一对上海来的夫妇,他们租了车要去生态保护区玩,于是我们就和他们拼车前往了。保护区无法乘坐公交车或旅游车去,租车是唯一的手段,租车的事后面单聊,这里讲讲保护区。

我们选择了比较轻松的玩法,只去了青龙大瀑布和龙川大峡谷,每个景点每人60块钱。后面回忆,这是最好玩的一天。青龙大瀑布略远,山更陡峭一些,坐车上山,自己爬下来,龙川大峡谷则相反,自己向上爬,累了坐车下来。这两个景点都是顺着水走,所到之处有山有水,绿树成荫,非常舒服。

青龙瀑布与龙川峡谷

后来斯屹累了,坐在我肩膀上走了很长一段路,登山杖有效降低了对膝关节的冲击,只是第二天有些腿疼而已,关节没有问题。

天游峰和九曲溪竹筏漂流

天游峰和九曲溪都是武夷山的必去科目,我们也不能免俗。第二天,我们上午去爬天游峰,下午九曲溪漂流,这两个都可以坐星村专线到达。我们比较休闲,没有一大早出来,据说早上可以看到云海,不过我们上山的时候都日上三竿了,就不要想这个了。

天游峰的景致主要在于俯瞰周围的山水,某同学评价是和百花山差不多,只是多了水⋯⋯对此我不发表任何看法了。斯屹在上山时的陡峭部分主要都是自己上去的,或者是妈妈拉着,下山就有一半是在爸爸肩膀上了,等到出了天游峰景区,已经累的睡着了。

九曲溪则比较轻松,只是开头一段很晒。在九曲溪上,可以路过周围一系列山头,比较著名的可能就是玉女峰了。竹筏需要给10块钱的小费,据说是香港人培养出来的,呵呵。事后我倒更想不给小费,好不要讲解,毕竟也没说出啥来。下面还是照片:

天游峰与九曲溪

整个武夷山的导游讲解都有些偏色情,什么“一楼泡茶、二楼泡妞”之类的言语总能重复听到,不知是在迎合谁的需要,反正我不喜欢这样的讲解。

虎啸岩和一线天

连续第三天的爬山,我们的目的地是虎啸岩和一线天,同样乘坐星村专线前往。我们乘车到达虎啸岩,爬山后,从后山徒步走到一线天,然后出一线天,乘车回到住处。

虎啸岩是一块大石头,据说是因为风吹过会发出虎啸一样的声音而得名,石头山有两条路,好汉坡陡峭,另一条路平坦,但无法到达峰顶。我们成功挑战了好汉坡,斯屹表现很好,其中最陡峭的部分都是自己走上去的,一直到半入云。下面中间那张照片就是在半入云的石门拍的,酷吧。

从虎啸岩下山一直到一线天,斯屹已经非常累了,我全程一直驮着他,大概数了2500步,才到一线天,还好路不算难走,只是当时水都喝完了,还是很辛苦的,仍然要感谢登山杖,才能平安到达。

一线天非常坑爹,狭窄是意料中的,意料之外的是里面非常臭,斯屹一直喊“我不想闻这个味”,直到出来,才算是长出一口气,如果再给我一次机会的话,我一定不去一线天。

虎啸岩和一线天

《印象大红袍》

第三天晚上我们去看了《印象大红袍》表演,话说张艺谋很会圈钱啊,里面差不多还是大型运动会团体操的那个路子,360度转动的观众席用来切换不同的幕算是个新意,作为背景的大王峰是亮点。强烈的光影色彩冲击感觉用力过猛,老婆当时说喜欢,回来回味的时候也觉得不如让人自己感受,而我一直就不喜欢这种风格。

武夷宫

前三天累坏了,最后一天上午我们去了武夷宫,这里可以去爬大王峰,不过我们没去爬,只在武夷古代名人馆转了一圈,又在宋街看了看有没有什么可买的。宋街实际就在第二天九曲溪漂流下船的码头那里,只是当天出门没来转一圈而已。这里实际没用多长时间,就留这么一张照片吧

武夷宫、大王峰

Tips:

  • 如果能不带上孩子就别带了,挺累的;
  • 如果一定要带上孩子就带着登山杖吧,挺管用的;
  • 天游峰比较累,九曲溪竹筏漂流平日的票比较好买,虎啸岩一般累,一线天很坑爹,保护区比较好玩。

住行篇

这次的住行都是老婆安排的,我坐享其成,简要介绍下。

候鸟家驴友驿站

我们住的候鸟家驴友驿站离景区入口很近,大约不到一公里,早上出屋门就可以看到烟雾缭绕的大王峰。这里的吃住都还不错,老板阿明还可以帮忙买票、联系租车什么的,而且出门走一点点就可以在兰汤站坐星村专线。

不过我们没用上之前说过的洗衣机,幸好衣服带的多,要么每天一件还真有点困难。

星村专线、旅游车、租车,以及黄包车

武夷山旅游最经济的手段就是星村专线了,可以到景区大红袍、水帘洞以外差不多所有的景区,包括天游峰、大王峰、九曲溪竹筏码头、虎啸岩、一线天等,根据距离,1-3块钱不等。如果坐旅游车的话,三天票是95块每位,差距太大了。

如果去保护区玩,必须要自己租车,旅游车也不到。

我们去看印象大红袍的时候,还坐了一次三轮车,因为太近,没租到车。去的时候,师傅要价6块钱,我们看着辛苦——我承认,是我太重,给了10块,师傅很高兴地10块钱又拉我们回来,一直到住处路口。

感觉当地人,各种司机乃至蹬黄包车的大叔,都很支持旅游事业,发自内心地向我们推介武夷山的各种好处,呵呵,没有什么抱怨。

Tips:

  • 大部分情况下,出门坐星村专线就行了,旅游车完全就是坑爹的;
  • 候鸟家还不错,可以考虑。

往返篇

老婆被之前单程 30多个小时的巴西之行飞怕了,这次一定要坐火车。Z59/60的买票有一点波折,不过总的讲一切顺利。

Z59/60、京九线

Z 字头的车全是 25T 的车底,也算是比较好的车了,软卧还算舒服,只是两个人带着孩子还是有点挤。来回在餐车上吃了几顿,感觉也还算不错。回来的路上,同一隔间是另外一家三口,父母带着一个小萝莉,从武夷山来北京出差+旅游的,还挺热闹的。

关于回来买票,我们观察了好几天,发现只有发车当天下午会有票,据店家讲,这里的票会被旅行社先全拿走,当天如果有剩下,再退回来,于是就只有当天有机会了。软卧的有票的时间窗口其实还蛮长的,每天都回超过 2个小时,而且经常到发车还有剩下,不过买票当天还是感觉挺紧张的,买到票感觉挺兴奋的。

Tips:

  • Z60回京的车票不好买,跟踪几天看规律吧,我们这几天的规律是下午三点半左右开始放出当天晚上的票,软卧还是比较有保障的;
  • Z59的票,在北京买,售票点和电话订票95105105都还算靠谱,不用太发愁;
  • 飞机的话,如果有合适的特价票也不错。

后记

其实没什么可记的,就这么几句吧:作为联合国评出来的遗产,武夷山保护的还挺不错的;每年政府都会给老百姓一点小钱,虽然老百姓知道这点只是毛毛雨,但看起来还挺知足,而且自觉维护的,连小贩都会多给我们一个垃圾袋;山顶上的价格也不是非常离谱,整体的物价水平都还比较容易接受。

总的讲,这次旅游还算挺满意的,就是有点累,后记完成。

暂时放弃译书工作了

August 1st, 2011 by gnawux 6 comments »

其实近期也没打算开始译书,这是时间和精力的原因。但这两天看到china-pub 的一些书评,心里不怎么舒服,在自己的汉语水平得到有效提高之前,我还是暂时不要接这类工作了。

我可以自我安慰地说某些网友可能就是来踢场子的,毕竟调戏译者也是件挺好玩的事;同时也见到有人在夸我或者安慰我。但译书这件工作本身,是有责任的。我眼里这个责任,不是说我尽力了就可以了,而是确实做好了才行,这是能力问题,而非纯粹的态度问题。就我的个人能力而言,只要认真看,技术文章还是能看懂的,但中文作文的能力自己也没什么信心,我自己能保证所有内容我自己看得懂,却无法让它达到读者所期望的流利水平。

再者,计算机领域,尤其是快速发展的互联网相关的技术领域,知识的新陈代谢速度非常之快,本书的翻译时间是三个月,前面是原书的出版周期和版权谈判等时间,后面是出版社的整理出版周期。这样,原书是针对0.6 正式版和0.7 Beta 版的,等到中文版上架的时候,0.8 都已经发布了,所幸,主要是增加了几个新特性,而非去掉本书介绍的东西。

那么我这三个月是怎么干的呢?我是业余翻译,支撑我的是兴趣和责任,在翻译期间,用掉了几乎所有的业余时间,甚至在医院一边排队等号,一边用iPad 翻译,为此还特意买了个蓝牙键盘。所有内容都是过了两遍的:第一遍初译,纯直译方式;第二遍整理,按照我的语言习惯来理顺语言,统一表达等。时间紧迫的情况下,有可能影响整理的精细程度,所以,如果有人说部分内容译得像机器的话,我想应该不是来无理取闹的。

或许我可以说,快餐的质量无需和大餐去比较,不过我也看过李松峰等优秀译者翻译的文章和一些不错的译著,我必须承认,我在翻译方面的水平仅限于自我娱乐,一两天或三五天翻译一篇自己喜欢的文章还不错,但长篇翻译一本书还是欠火候,我还没有能力在短时间内遣词造句,兼顾表达愿意和语句流畅两个方面。出版业是一个严肃的行业,没能力的同学应该自觉靠边或是回家学习去。

嗯,当然,在不污染视听的角落里,我还是会悄悄地在我的blog 里,在不违反原作者意愿的情况下,翻译一些我喜欢的文章的,对于读者,可以任其选择读与不读。

 

ZooKeeper Watches

June 6th, 2011 by gnawux No comments »

按:王旭(http://wangxu.me/blog, @gnawux)于2011年6月6日译自 ZooKeeper程序员指南 (http://zookeeper.apache.org/doc/r3.3.3/zookeeperProgrammers.html)的同名章节。似乎很少有文档提这个啊,我其实在看这个之前一直不明白这东东是怎么用的。

所有的Zookeeper读操作,包括getData()、getChildren()和exists(),都有一个开关,可以在操作的同时再设置一个watch。在ZooKeeper中,Watch是一个一次性触发器,会在被设置watch的数据发生变化的时候,发送给设置watch的客户端。watch的定义中有三个关键点: 

  • 一次性触发器

    一个watch事件将会在数据发生变更时发送给客户端。例如,如果客户端执行操作getData(“/znode1″, true),而后 /znode1 发生变更或是删除了,客户端都会得到一个  /znode1 的watch事件。如果  /znode1 再次发生变更,则在客户端没有设置新的watch的情况下,是不会再给这个客户端发送watch事件的。

  • 发送给客户端

    这就是说,一个事件会发送向客户端,但可能在在操作成功的返回值到达发起变动的客户端之前,这个事件还没有送达watch的客户端。Watch是异步发送的。但ZooKeeper保证了一个顺序:一个客户端在收到watch事件之前,一定不会看到它设置过watch的值的变动。网络时延和其他因素可能会导致不同的客户端看到watch和更新返回值的时间不同。但关键点是,每个客户端所看到的每件事都是有顺序的。

  • 被设置了watch的数据

    这是指节点发生变动的不同方式。你可以认为ZooKeeper维护了两个watch列表:data watch和child watch。getData()和exists()设置data watch,而getChildren()设置child watch。或者,可以认为watch是根据返回值设置的。getData()和exists()返回节点本身的信息,而getChildren()返回子节点的列表。因此,setData()会触发znode上设置的data watch(如果set成功的话)。一个成功的 create() 操作会触发被创建的znode上的数据watch,以及其父节点上的child watch。而一个成功的 delete()操作将会同时触发一个znode的data watch和child watch(因为这样就没有子节点了),同时也会触发其父节点的child watch。

Watch由client连接上的ZooKeeper服务器在本地维护。这样可以减小设置、维护和分发watch的开销。当一个客户端连接到一个新的服务器上时,watch将会被以任意会话事件触发。当与一个服务器失去连接的时候,是无法接收到watch的。而当client重新连接时,如果需要的话,所有先前注册过的watch,都会被重新注册。通常这是完全透明的。只有在一个特殊情况下,watch可能会丢失:对于一个未创建的znode的exist watch,如果在客户端断开连接期间被创建了,并且随后在客户端连接上之前又删除了,这种情况下,这个watch事件可能会被丢失。 


ZooKeeper对Watch提供了什么保障

对于watch,ZooKeeper提供了这些保障:

  • Watch与其他事件、其他watch以及异步回复都是有序的。 ZooKeeper客户端库保证所有事件都会按顺序分发。

  • 客户端会保障它在看到相应的znode的新数据之前接收到watch事件。

  • 从ZooKeeper接收到的watch事件顺序一定和ZooKeeper服务所看到的事件顺序是一致的。


关于Watch的一些值得注意的事情

  • Watch是一次性触发器,如果你得到了一个watch事件,而你希望在以后发生变更时继续得到通知,你应该再设置一个watch。

  • 因为watch是一次性触发器,而获得事件再发送一个新的设置watch的请求这一过程会有延时,所以你无法确保你看到了所有发生在ZooKeeper上的一个节点上的事件。所以请处理好在这个时间窗口中可能会发生多次znode变更的这种情况。(你可以不处理,但至少请认识到这一点)。

  • 一个watch对象或一个函数/上下文对,为一个事件只会被通知一次。比如,如果同一个watch对象在同一个文件上分别通过exists和getData注册了两次,而这个文件之后被删除了,这时这个watch对象将只会收到一次该文件的deletion通知。

  • 当你从一个服务器上断开时(比如服务器出故障了),在再次连接上之前,你将无法获得任何watch。请使用这些会话事件来进入安全模式:在disconnected状态下你将不会收到事件,所以你的程序在此期间应该谨慎行事。

 

 

Switch to our mobile site