qyb的博客

Forking the ARM kernel?

June 2, 2011
This article was contributed by Thomas Gleixner
http://lwn.net/Articles/445417/

翻译:李潇/林业

在过去的几个月里,许多人都提出了建议将ARM与内核分离出来,将之作为一个独立的项目来维护。或许分离ARM的理由对一些人来说看起来是很有吸引力的,在这些人看来无论对于ARM社区还是内核,作为一个整体没有太大的意义。

下边来一一批驳这个提议的几个普遍的理由:
  1. 更容易把握市场时机

  2. 它符合消费性电子产品一次性的性质

  3. 它更符合SoC世界的多样性

  4. 它避免了维护者的瓶颈和代码审查之类的一些无用的额外工作

市场时机

持这种观点的人认为,hack出一个新的驱动程序所需要的时间要小于让 Linus 等接受它。我知道我学识很老,不再懂这个快速变化着的世界和半导体工业的新挑战,但是,我仍然有许多的工程学的知识和常识以至于我知道在这个工业里根本没有什么真正的、和过去完全断开的新东西。大多数 SoC 的IP模块并不是新的。所以当IP模块第二次被应用的时候市场时机又有何变化?如果一个驱动程序是 upstream 的,它可以很容易的被复用,但是常常的情况是,一个新的驱动程序从头开始编写,完成的时候仍然有一堆漏洞需要修正。当重写那些他们所出售的SoC IP模块新驱动程序的时候,供应商们真的得到了更好的时机么?

此外,真正一个完整的新一代的芯片市场化的时机不是几周就能衡量出来的。通常情况下,对于一个新的芯片从市场发布到稳定应用到设备上需要大约一年时间。这是对于得到一个新的驱动程序有了足够的时间。而且,市场发布的时间显然不应该是在工程部喝点啤酒,几个天才工程师在酒吧的草纸上勾勒出个设计的第二天,所以大多数的项目应该有更多的时间去推向 upstream。

嵌入式商品是一次性的

对于嵌入式的项目,特别是在消费品市场,硬件是一次性的是毫无争议的,但是另外一个事实是,SoC family 在很多方面是普遍的,只在一些小细节方面有所不同。此外,特定硬件的不同变种(比如智能手机)共用了绝大多数的基础架构而只在一些特定功能上存在差异。新一代 SoC 往往会有很多的上一代的模块被嵌入其中,因为没有令人信服的理由去取代那些已经被证明构建好且可以实现充足功能的模块。复用那些已知的的可以工作的部分不是一个新的概念,而且毋庸置疑的是实现市场化目标的一个基本的部分。

最近我们身上发生了这么一件事:一个几乎所有的外部组件都已经在内核主线中得到完美支持的 SoC 进行了升级。CPU 内核被替换,但外围组件保持一致——除了为符合新 CPU 核心所作的一些 VHDL 的细微改动。现在我的工程师性格也许应该期待Linux对于B代片上系统的支持只存在调整现有的驱动程序这样的小问题而已。现实是供应商们组建了一个小组去开展对“新”的片上系统和所有从头重写的驱动程序的支持。与此同时我们抓到一些驱动程序去审阅,而另一些进入了主线,所以我们为同一片半导体硅得到了两个完全不相同的驱动程序。

有一段时间,我非常难以接受这样一种观点:宁可从头开始重写成打的驱动程序也不愿坐下来鉴定那些已经存在的、被证明可以工作的驱动程序,根据新的 SoC 的设计去修改它们。嵌入式工业经常复用硬件,为什么就不能同样复用软件呢?

SoC 的多样性

无疑,每一个 SoC 供应商都会叫喊他的芯片在所有方面都是独一无二与众不同的,共享很多的代码基本是不可能的。从市场方面很容易理解这些,但是如果你深入查看 SoC 的数据表,独特的外围模块数量并没有多令人兴奋的增加,鉴于该系统芯片供应商相同的市场目标和相同的客户群,或多或少的预期。一份调查揭示了不同的供应商经常使用相同的或十分相似的IP模块去实现一个给定的功能。只有很少数量的功能性方法去实现一个给定的硬件需求,而且只有很少的相关IP模块供应商把自己“独一无二”的构建模块提供给其他的 SoC 供应商。差异性常常只是局限于供应商们在登记注册的安排上以及不同的供应商选择不同的功能子集这件事实上。

我们最近看到了一些被证明是正确的内核合并工作,当清理中断子系统时我注意到只有两种广泛运用的中断控制器。不用投入太多努力就可能将30个声称有“与众不同”的芯片实现代码全部替换掉。一个相似的成就是,在替换掉许多重复的通用输入输出(GPIO)芯片的支持代码过程中,这些都是很容易得到的成果并且有更潜在的合并方法。

避免无用工作

与那经常只有很少的时间去复审的维护人员们打交道似乎是一个瓶颈。那些导致了提出复审评论的额外的工作也看起来像是浪费时间。维护人员的数量和复审可用的时间固然是一个需要注意的限制性因素。复审的能力对于那些维护着一个特定内核的子系统的人不是限制,并且我们希望看到更多的人参与到复审的进程中来。花一点时间去复审别人的代码是一个收益巨大的工作,它就像对所有接近者打开了一个人的思想以使他们更好的理解全面的状况。

从另一方面来讲,让别人复审自己的代码也是很有益处的,一般来说可以让你的代码更好和更具可维护性。并且为我们避免在下一个项目中犯错提供了帮助。在最近的一次已经进行过很多轮的复审中,一个1200行的驱动程序被缩小到了250行,并且少量的漏洞和主线错误得到了修正。

我曾经有机会在一个冗长的复审进程之后和开发者们谈话,他们中的大多数人承认学习和理解更多的Linux开发方式的机会的痛苦要大于复审进程和一些必要的回顾工作。当检查最近的补丁时我经常注意到,这些开发者已经提高并且避免了一些在第一次尝试时所犯的错误。所以复审对于开发者和他们的公司来说都是有益的,复审帮助他们用更高效的方法写出更好的代码。我称呼那些仍然叫嚣着复审和其所带来的工作是主要障碍的人为表里不一的,他们在努力把他们所在公司的责任转嫁归咎到的内核社群。

一个问题是不培训他们如何同Linux社区一起工作就指定专有的实时系统(RTOS)开发者们去写Linux内核代码。不懂如何同Linux社区一起工作不是什么羞耻,毕竟,包括我自己在内每一个内核开发者都是从一个不知道的点开始着手的。但是它花费了我一段时间去学会如何同社区一起工作,而且它也将花费那些专有 RTOS 的开发者们一些时间去学会和社区一起工作,这些所付出的时间和努力都是值得的。

Fork ARM内核后,需要解决哪些问题?

假如有一个专门的ARM GIT仓库,扮演一个所有Vendor trees的堆积站。它将不时地把主线内核的增强功能吸收进来,这样的话,嵌入开发人员就能获得新的文件系统特性和网络特性等。推断出近期流向Linux的SoC支持补丁,移除掉这上面的所有正确性检查将导致那个ARM树的增长率立即超过所有主流内核的增长率。并且,如果主线内核的增强功能像需要我最近的一些工作有所改动一样,也需要ARM树的所有驱动都改动的话,那该怎么办啊?谁来完成这些改动?如果驱动都在主线内核里面,驱动是作为这些增强功能的一部分发生改动。如果有一个单独的ARM fork,一些ARM-fork的维护者将不得不完成这些改动。

而且,谁来维护这样一个树?我严重怀疑是否会突然出现足够的有经验并有资格去处理这样一大堆改动的维护人员。维护人员在与主线内核打交道时,他们有所抱怨,为了避免这些,他们也许只会扮演集成者的角色,仅仅是在中央区域对各个Vendor trees进行合并。

我们会从这样一个动作中收获什么?据我看来,我们将一无所获,它仅仅是让所有人都声称他们所有的代码是一个神秘的ARM Git tree的一部分。当然短期内,这样会完成最终的产品上市要求。

ARM-fork能支撑多久呢?

我严重怀疑ARM复制树能活得过若干个内核周期,原因很简单,核心代码的改动将导致不兼容SoC API产生完全不具有维护性的#ifdef混乱,这会让任何不得不维护这样一个“野兽”的人立刻抓狂。我十分确定没有一个ARM-fork的支持者曾经试过将五个vendor trees拉取到一个单独的内核树上,并处理DMA APIs,驱动子系统,基础结构的冲突改动。我知道嵌入式内核的维护者的确因为这些原因立即变得绝望,我怀疑任何一个合理的内核开发人员会足够发疯到花掉不止几个月的时间去处理这样一件恐怖的事情。

除了它那令人怀疑的用处外,这样一个ARM fork将会从对Linux内核所有方向的影响中完全地切断ARM世界。对大部分有经验的主线维护者和开发者而言,ARM将变成一个毫无兴趣的领域。我怀疑尤其是当操作系统层面的软件的复杂性正在稳固增加的情况下,ARM行业能否禁得起以这种方式将自己断开联系。

有更好的方法吗?

从没有一个方法能从根本上解决所有的问题,但是有一些小的方法可以有效地解决主要问题点。

导致出现现在这种状况的根源之一是它的历史本质。二十多年来,ARM行业与那些不可能改变核心代码和不可能与之进行有竞争的合作的闭源操作系统打交道。如今,迁移到Linux以后,ARM的大部分都还在这个著名的模型下工作,并且让那些在转到Linux之前也在以其他操作系统上工作过的工程师继续按照过去的方式让他们的系统工作。这对管理层也是一个完美的解决方案,因为现有的自上而下进行软件开发和管理的结构和思想依然适用。

只要由此产生的代码不用集成到主线内核并且每个厂商维护它自己特有的复制品,这种解决方案貌似是有效的。有时会从客户那里传来主线内核集成的合理请求,然而,当这种方案让采用新特性变得更容易的时候,对冻结的厂商内核的依赖就会越少,并且,从最近可以看出,该方案允许对多平台的合并。后者能让合理的发行以上网本、平板电脑和相似设备作为目标工作,这是很重要的。它甚至对长期传言的在不久将来将成形的ARM服务器同样适用。这样的合并不仅需要ARM厂商的合作,还需要主线内核许多方面的合作,同时也需要那些不一定是ARM领域的维护人员和开发人员的合作。

因此,我们需要让管理层明白到坚持这个有名的模型并不是解决逐渐增加的SoC硬件复杂性以及开源世界中开发高效和可持久性操作系统带来的挑战的最有效方法。同时,我们需要解释一下在工程的层面上将Linux与其他OS平台以同样的方式对待的话,将会让前进更加艰难,至少当代码审查出现在邮件列表的时候,将是很让人痛苦的。

另外一个我们需要努力做的地方就是大量的协作性合并,这些合并需要先让芯片提供商至少在OS工程层面上接受他们的SoCs并不是销售部想让他们相信的那样独一无二。正如我以上提到的那样,尤其是对低复杂性的硬件,仅有有限的几种方式去实现硬件上指定的功能。因此,我们需要鼓励开发人员首先去看一看现有代码是否可以重构以适应新的设备,而不是轻率的拷贝最接近的驱动(或者在最差情况下随机拷贝一个驱动),并设法以hack的手段去适应新的设备。

另外,内核维护人员也需要对这种情况更加警觉,并且帮助开发人员避免重新造轮子。如果不能达到驱动再利用的目的,我们可以将通用功能取出来放到核心代码里面,避免那样的重复。有很多唾手可得的东西在那儿,Linux整个内核社区需要变得更好并且花更多的心思去避免代码重复。

最近Linaro发起的ARM SoC合并提前开始了这样的行动。但是仅当我们意识到与现有公司文化的冲突并在非技术层面上解决掉这些冲突的情况下,代码合并才会成功。

保密

除了上面的这些问题,秘密堡垒将成为下一个主要的挑战。当然,芯片提供商可以对它下一代SoC设计保密,但是它在营销公告透露的信息至少能让我们准确地预测出部分设计。

最明显一个例子是以2011剩余时间作为目标的各芯片供应商提供的下一代ARM SoCs。其中很多都会支持USB 3.0。从 IP block vendor 提供的信息知道,相比较计划支持 USB 3.0 的 SoC 数目来说,支持 USB 3.0 的 IP block 极少。那意味着在里面有重复的驱动,我很确信这一点,工程师都知道没有那个团队会被允许跟竞争者的团队交流。即使他们被允许这么做,也不可能猜测出谁会用哪一个特定的IP block。所以当秘密堡垒出现时,我们会看到几个工程团队在几个月内为了让自己的“正确”实现能被合并到主线驱动而争斗。

为了代码实现而竞争不是一件坏事,但是不能交流信息、讨论设计变化不会对任何一方在“上市时间”的竞赛中有所帮助。我严重怀疑任何一个即将发布的驱动会有相关的竞争性优势,即使它有这种优势,当代码公开后这个优势也不会持续太久。相互协作以及为所有参入进来的组织保留先前的工程资源的机会被牺牲掉,而却用来以竞争为导向的行为样式上,这让人很伤心。这些样式还没被改革掉,因为他们不过只有二十多年的时间,还从来没有遭到开源操作系统竞争环境的审查。

前进之路

逐渐增加的硬件复杂性,产生了更多的操作系统层面上的软件,导致知名度高的OS层面的软件开发人员长久以来短缺,而这不是能用金钱或者通过安排大量的脸颊开发人员能够抵消掉的。ARM领域是如此多样化以至于所有提供商都没有机会得到足够数量的杰出内核开发人员,对他们的竞争者产生严重的破坏。在这个事实下,这个观点相当正确—那就是那些杰出的开发人员普遍更愿意工作在开源环境下而不是半封闭环境下。

大概是时候让管理者们反思他们的竞争模式并开始理解和利用协作模式的大量优势。有能力的开发人员当然不会放弃这个机会让自己加薪,但是若能得到更让人享受的工作环境,虽然薪水稍微低一些,对很多人来说却是一个强大动力去拒绝加薪的诱惑。对我来说,没有“上市时间”竞赛,没有股东利益手册,没有人力资源管理课程的想法是很吸引人的。

我希望为嵌入式提供商工作的管理者能够开始去理解开源是怎么运转的以及为什么与这个社区合作会有巨大好处。毕竟,平庸的、老旧的服务器提供商都能想出如何与Linux社区合作,因此对快速移动的嵌入式提供商也不是那么难的事。然而,我是一个现实主义者——有时被称为脾气暴躁的老人——在嵌入式行业做了超过二十五年的时间,一点不相信真会这样。对如此多的SoC提供商而言,做出与社区合作的决定是出于外界的压力和炒作。

外界压力不是开源狂热者所希望的那样由开源社区本身的影响力造成的。不是的,他只不过是客户要求芯片至少基本上被主线内核支持所造成的压力。炒作是无处不在的,似乎总可以称为一个有效的理由去避免基于长期考虑所做的常识性决策。

我身上的永久乐观主义仍然希望嵌入式世界很快会成为Linux社区的一等公民。而我身上的现实主义却又怀疑在我这个脾气暴躁的老人退休之前它是否会发生。

Topic: sohulinux

Illumos:OpenSolaris社区的继承者

June 2, 2011
This article was contributed by Koen Vervloesem
http://lwn.net/Articles/445793/

翻译:曾怀东/朱翊然

在2010年8月,存储供应商 Nexenta Systems宣布了一项免费的OpenSolaris发行项目:illumos。Illmuos的最终目标包括两个方面:一是使用开源代码取代所有仍在OpenSolaris使用的专有代码,二是围绕之前的OpenSolaris代码库建立一个独立的社区。现在已经过去了将近10个月,Nexenta Systems于5月20日在Amsterdam召开了Nexenta European User Conference并展示了Illumos的计划和Nexenta的产品。现在正是关注Illumos进展情况的好时机。

源代码

Illumos的代码库正在形成或将要形成一组发行项目,包括来自Nexenta的存储应用,来自Joyent的云计算平台以及通用的OpenIndiana(这是OpenSolaris发行精神的继承者)。他最初的目标之一是用开源的组件取代OpenSolaris代码库中仅存的部分二进制代码组件。现在,Illumos仍然保留着部分二进制代码的组件,例如NFS lock manager,IKE deamon(Internet Key Exchange, IPsec的一部分),一些支持的库,以及一些驱动,但是据Garrett D’Amors(Nexenta系统的开发主管)所说,Illumos的开发者正在致力于解决这些问题。而且,去年编译Illumos仍依赖于Sun Sutdio编译器,Illumos现在使用GCC构建(build),尽管这还需要更多的测试。

Illumos已经从一些硬件厂商(Areca4Front)那里获得了贡献的代码。根据D'Amore所说,还有来自于主机总线适配器和网卡供应商贡献的一些代码正在等待合并。而且,Intel和LSI成为了Nexenta的技术合作伙伴以及主要的赞助商,这意味着Nexenta获得了这些公司的规范和工程方面的支持。D'Amore还说到,很快会得到这两家厂商的代码贡献。值得注意的是与Illumos/Nexenta关系并不很好的AMD和Nvidia的缺席。但是,在D'Amore自己博客的评论中,他解释到:这些合作关系或是非合作关系不会一成不变:“我很高兴和其他厂商维持良好的关系,无论是NVDIA或是AMD。只是在此刻,这三家公司中只有Intel向illumos或Nexenta伸出了橄榄枝。”

成长的烦恼

目前,有一些针对Illumos运作方式的批评。因为对“思维狭隘,ZFS中心独裁以及大教堂式的开发模式”不满,Stamos Tolias已经开始呼吁创建分支。显然他开始筹措资金并准备在11月份将自己的分支项目公开。项目的领导来自于Athens大学,经费支持来自于某欧洲研究基金,并拥有EADS作为合作伙伴。Totlias并没有回应本小编的问题进行澄清。

Tolias批评Illumos的部分矛头直接指向D'Amore,后者在自己的博客上进行了申辩


首先,声称我对illumos具有绝对的控制权这种说法是荒谬的。我创立这个项目,并作为一个技术领导为该项目服务,当开发人员理事会和管理理事会希望我下台时我就会离开。值得注意的是,我的雇主(Nexenta)在两个理事会中都拥有表决权,我尽可能的让组织保持中立。我说过当我创立illumos项目,我依旧会让这个项目保持为一个社区项目,而不是一个Nexenta的项目。

D'Amore进一步解释到,Illumos没有处于Nexenta的绝对控制之下:


我已经向开发者理事会上报了Advocate List(拥有批准和整合提交权限的人的名单)的决定。到目前为止,Nexenta占据了名单的75%,但是这些会根据开发者理事会的要求进行改变。由于illumos代码的75%的贡献都是来自于Nexenta的团队,Nexenta的成员在名单中占据75%的比例并不稀奇。事实上,尽管有一些贡献很大的候选人,但是我已经开始拒绝更多的Nexenta advocates的加入。这一情况会持续到当我们具有更广泛的代表性为止。

D'Amore正在与Software Freedom Law Center合作,准备为Illumos创立一个法律实体,让这个法律实体成为一个独立的组织完全独立于Nexenta。所以,目前在某种程度上,Illumos的发展确实不够开放和独立,但是Nexenta一直在努力为一个真正的属于社区的Illumos进行着铺垫。

Nexenta

Nexenta建立在Illumos的基础之上,造成了两面性的影响:一方面是一个开源的GNU/Solaris操作系统(2009年是版本2),Nexenta Core Platform (NCP),另一方面是一个商业存储解决方案,NexentaStor。后者是基于ZFS的存储解决方案,通常是由系统集成商和增值经销商(VARs)购买作为带有认证的硬件的整体解决方案的一部分,认证的硬件大多数来自于LSI,Quanta,Dell,Supermicro, 和 Intel这些厂商。

Nexenta的关键卖点是他自己声称的“"Open Storage”:因为NexentaStor使用者能够简单迁移到其他操作系统支持(同一版本或是新版本)的ZFS上,例如Solaris, FreeBSD 等等,他们可以不用担心厂商对他们数据的 Lock-in。相比之下,大存储厂商使用专有的磁盘格式,它们的解决方案紧密结合自己的硬件。使用Nexenta,用户甚至可以自己选择需要购买的硬件。

之前Nexenta的用户空间部分(除了kernel外)是基于Ubuntu的,但Nexenta 4(计划在2011年底发行)将基于Debian 6("Squeeze")。Nexenta工程师们做这个决定的原因是:Debian更容易移植,而Ubuntu有太多使用特定Linux特性的补丁这造成将用户空间部分移植到Illumos核心更困难。Nexenta 3仍会基于OpenSolaris内核,Nexenta 4将成为第一个基于Illumos的Nexenta产品。因此,既有OpenSolaris内核到Illumos内核的切换,也有从Ubuntu用户空间到Debian用户空间的变化,Nexenta 4 的确是一个很大的变化。

但是,现在仍然有很多的“FUD”在ZFS和合作者之间蔓延。去年,存储厂商NetApp向他的竞争者Coraid发送了一封威胁的信件,结果Coraid决定停止代售其ZFS存储设备(基于NexentaStor的)。在甲骨文和NetApp之间也有诉讼,该诉讼不得不处理NetApp对ZFS违反专利权以及NetApp使用来自于Sun公司的具体技术的权利的申诉。甲骨文和NetApp解决了他们的纠纷,但是他们和解协议的细节并没有公开。

Nexenta 以及其他在自己操作系统中使用ZFS的公司肯定不用担心和甲骨文公司的官司:ZFS代码的CDDL授权允许其使用任何甲骨文可能拥有专利的代码。但是NetAPP或者其他组织仍然能够因为ZFS代码对他们专利权的侵犯控告Nexenta,尽管从今年开始Nextenta成为了Open Invention Network (OIN)的一部分。在Nexenta的欧洲用户大会主题演讲上,首席执行官Evan Powell明确表示他认为这个成员身份是为了应对潜在的NetApp专利侵权诉讼:“如果NetApp要起诉我们,我们可以通过由OIN共享的Novell的UNIX专利起诉他们。”

StormOS

2011年1月,Nexenta还聘请了Andrew Stormont,他是StormOS——一个基于Xfce桌面系统的Nexenta核心平台衍生品——的开发者。这个桌面操作系统面向那些喜欢类似于Nexenta提供的ZFS/apt combo服务,但是不想安装桌面包的人群(因为Nexenta并非针对于桌面型用户)。目前,Stormont作为一个软件工程师,主要在为即将上线的Nexenta 4打包软件,但他最近也提交了Illumos补丁。

作为他在Nexenta Systems工作的一部分,Stormont一周中有一天是在做StormOS的工作,而且他在Nexenta大部分的工作,StormOS最终也能从中受益。但是从StormOS项目启动开始,它始终更像一部独角戏。StormOS的下一个版本——StormOS Flash——将基于NCP4以及一些来源于Debian 7的一些组件(比如X.Org和Xfce的更新包)。其中一项新的特性将是一个在文件管理器中整合ZFS快照的Xfce图形界面,类似于OpenSolaris中GNOME的时间滑块功能。

Stormont正在考虑的一个更具实验意义的特征是FatELF:在单独的二进制文件上支持32位和64位架构。Illumos内核已经具备在32或者64位的硬件模式下自动启动的能力,所以内核中的二进制文件就能够自动的运行于正确的模式。

在一次接受电子邮件采访中,Stormont解释了FatELF可以给StormOS带来哪些好处:


FatELF将会取消对单独的/bin and /bin/amd64, /lib/ 和 /lib/amd64 等目录的需要。它也会取消对臭烘烘的isaexec命令的需要——这似乎是普遍痛恨的。它也使32/64位库更容易打包——不需要把64位的规则hack到Makefiles中。最后它将使可携带StormOS变为可能,能够自动的运行于32/64位的模式下。大多数人一想到FatELF就畏缩了,主要因为字节数膨胀的原因。但我认为那不再是一个问题,因为现在大多数人都有又大又便宜的带宽和硬盘。我不确定FatELF是否将其改造成一个官方StormOS的发布,但我一定会实验的。

其他公司

Nexenta不是唯一支持Illumos的公司。Joyent是另外一个大的贡献者,它聘请了像Bryan Cantrill 和 Brendan Gregg那样的Solaris核心人员。Joyent已经发布一个存有他们的一些补丁的git仓库到Illumos树上。John Sonnenschein在他的的树公告中写道:


illumos-joyent树是Joyent快速发布illumos补丁的载体,在有点类似 linux 的 -mm tree。也就是说,它不是fork或者alternative development hub。Joyent员工和社区成员都被鼓励去bundle来自illumos-jouent的补丁,并且把它们归并到Illumos树的主线上。

一些补丁是Joyent特有的,但另外一些的用途更普遍些。大部分的补丁为区域功能的增强(操作系统级别的虚拟化),以及DTrace(Solaris动态追踪框架)的改进位在云中提供更好的分析。许多这样的改变可能会在不久的将来找到它们的用武之地,虽然现在有实际的问题:Illumos 使用Mercurial 而Joyent使用Git。

另外一个代码贡献者是数据库公司 Delphix,该公司雇用Adam Leventhal,他曾经从事于RAID-Z工作(一种冗余模式,类似于RAID 5,使用ZFS),也是DTrace的共同发明人。Delphix似乎更愿意保持其参与的安静性,因为它们还没有公布任何关于他们的贡献,但是粗略的看他们在Illumos仓库中的提交,表明他们肯定参与其中了。因此,虽然Nexenta Systems仍旧是主要的贡献者,但也有一些其他的公司已经参与其中。

Google Summer of Code

尽管发布还不到一年,Illumos 已经在Google Summer of Code (GSoC) 2011上作为指导组织者的身份出现。他们已经接受了两个 Illumos GSoC项目:Harshit Jain将更新Illumos,为了能引导GRUB 2,并支持用GUID分区表(GPT)从硬盘启动,该项目由D'Amore指导;而Shashank Karkare在Joyent's John Sonnenschein的管理下,将用C重写一些Perl系统组件(如intrd和kstat)。后者的目标是为Illumos消除Perl运行时的依赖。

此外,Nexenta还资助三名未进入GSoC的学生。例如,Andrey Sokolov将在没有区域(zone)的情况下做支持Illumos 上的linux二进制文件的工作(商标(branded)区域是在虚拟环境中在Solaris上运行linux二进制文件的一种方法),Bayard Bell将从事IKEv2守护进程的工作去代替IKE,Viktor Ikonnikov会位服务配置工具svccfg写一个GUI的前端。对于GSoC以及Illumos学生的未来版本,Illumos已经有了大量的项目设想的清单

ZFS工作组

另一个在Illumos 保护伞下的令人关注的发展是ZFS工作组,虽然它有点低调。这个小组由Delphix 和 Garrett D'Amore的Adam Leventhal and Matthew Ahrens (他曾工作于Sun/Oracle 的ZFS)在几个月前成立的,Ahrens是该组的组长。小组的目标是通过协调工作和交换思想促进ZFS社区的合作。特别是,创办人担忧ZFS会分裂成各种不同的支持文件系统的操作系统的子社区。

ZFS工作小组包括来自Illumos/OpenIndiana, Mac OS X(最有可能Don Brady开发ZFS支持他的公司Ten's Complement),FreeBSD(或许是移植ZFS的Pawel Dawidek),Linux, 和Solaris的开发人员. 按照D'Amore的说法, Oracle也在小组中占有一席之地。该工作组的活动不是公开的,部分成员不希望自己的成员身份公开,但是会定期的发表讨论的结果。

ZFS工作组的第一个结果是feature flags proposal。在公告中,Matthew Ahrens写道:

该工作组的第一个产品是ZFS 磁盘版本化方法的设计,在没有进一步明确的协同信息的情况下,此设计将允许分布式的开发ZFS磁盘格式变化。这种方法消除了两个开发人员都分配版本号31去表示他们自己功能的问题。这种“特征标签”版本化允许未知版本被识别,而且在许多情况下,即使在未知的磁盘特征的情况下,ZFS池或者文件系统可以是只读的。我的建议涵盖了SPA/zpool, ZPL/zfs, 发送流,以及分配压缩和校验标识符(枚举值)的版本化。

正如Ahrens所说,这个特征标签功能是必要的,因为与只有Oracle/Sun开发ZFS的时候相比,当前ZFS的开发正处于一种更分布式的方法。在ZFS v28之后,Oracle已经停止发布它的源代码,而Illumos,FreeBSD以及其他支持ZFS的操作系统不希望等到Oracle发布Solaris 11后的再一次代码公开,所以开发继续进行。因为特征标签,Oracle外的开发人员可以在不破坏互操作性的情况下添加新的压缩算法或者新的RAID变体:大多数情况下系统应该仍然能够在只读模式下访问ZFS池或者文件系统,如果它拥有未知特征。特征标签将在今年夏天应用,并且并入Illumos中。

结论

Illumos显然在向前发展,虽然这样做会让一部分人沮丧。Illumos的开发商大多数使用大教堂式的开发模式,而一些Illumos社区的vocal成员更喜欢完全开放的开发——就像linux正在使用的开发模型一样。对于fork和关于ZFS工作组封闭性质的批评是这些情绪的产生的后果。

然而,这些批评忘记了OpenSolaris的发展模式更加的封闭。虽然Sun发布了Solaris系统的大多数的代码,而且称OpenSolaris“开放源码”,实际并没有一个真正的OpenSolaris社区:它总是过于依赖Sun和后来的Oracle,这两家公司并没有努力去围绕他们“开放源码”的项目创建一个独立的社区。目前Oracle对于Solaris 11的开发模式是完全封闭的。

因此,虽然Illumos尚未完全开放Solaris代码库,并且还没有许多OpenSolaris的人梦寐以求的充满活力的社区,事情正在朝着正确的方向。它再也不是一个Nexenta独享的项目,它会有一个独立的Illumos基金会,而且这个项目已经吸引了一些大硬件厂商的支持。现在只是等待基于Illumos的Nexenta的发布和第一个稳定的基于Illumos的OpenIndiana的发布,让这个项目蓬勃发展起来,并重新获得那些在Oracle封闭的时候离开OpenSolaris社区的人的兴趣。

Topic: sohulinux

Eclipse Orion——基于 web 开发的 IDE

June 2, 2011
This article was contributed by Joe 'Zonker' Brockmeier
Web-based development with Eclipse Orion
翻译:李凯

Web 开发者应该使用以 Web 为核心的工具进行工作。这看起来是一个非常合理的事情,但是在实际的应用中,Web 开发人员被禁锢到设计用于桌面开发的工具上。Eclipse Project 正在寻求用 Orion 来改变这种现象,它是一款基于web的开发工具,用来进行web应用的开发。Orion仍然处于起步阶段,但它确展示出了很多的希望。

Eclipse project 在一月初宣布了Orion,并在三月份推出了一个主机服务版本。最初的贡献是来自IBM的原来的 Eclipse 团队做出的,并作为促进了这件事的发展。最新版本Orion 0.2 M7已在五月初发布了。

Orion跟许多开发者熟悉的Eclipse IDE是完全独立的。Orion是用一套松散的、成对的(前端是js,后端是Jetty + Equinox)组件集合成的工具。根据Orion 的整体架构,我们可以看出Orion的目标是使基于浏览器的工具成为其特色,这些工具与本地存储的数据进行交互,或者是通过REST APIs获取存储在“云”里的数据。前端代码是EPLEDL双许可的。服务器端只有EPL许可。

适用于 Orion 的场合很多,可以是任意类型的web开发。从单个开发者用PHP、JavaScript、HTML和CSS开发简单的网站,到开发像Orion一样的架构,包括服务器端的Java组件、客户端的JavaScript、CSS和HTML。

这不是Eclipse Foundation第一次以 Web 为中心所做出努力。2008年,在EclipseCon上展示了一个基于web的Eclipse 4.0 原型。但是这个方案后来被摒弃了,Orion是一个新的代码库,它几乎不包含现有的Eclipse代码库的任何东西。

世界上已经有很多IDEs(像Eclipse)和其它开发工具,你也许会对为什么还很有必要再开发一款在浏览器上运行的工具而感到奇怪。Eclipse开发者Boris Bokowski对此有一个简单的回答——Orion并不等同于IDE。根据Bokowski的说法,开发者已经用了很多基于web的软件作为他们开发的一部分:Bugzilla,代码审查工具Gerrit,在线阅读文档,基于web工具的代码库,比如GitHub。但是他们使用桌面工具(诸如文档编辑器或者完整的IDE)来进行实际的编码和调试—------这并不是最理想的。Bokowski总结:

  1. 我们建议是把余下的软件开发也活动转移到浏览器上来。。。
  2.  
  3. 这让其作为一种开发软件的方式变得有意义,你会想让所有这些基于浏览器的工具一起工作。更理想的情况是,你会想要得到一集成的东西,这通常都是要从典型的IDE得到类似的,但是不用建立另一个IDE。我们想建立一个与现有的网络上已经存在的工具合作很好的东西,不应该让程序员去更换其已经使用很熟练的开发模式。因此,我们的方法必须基于发展成熟的网络架构——用超级链接在不同的工具和资源间浏览,使数据能在RESTful方式下访问,并使用诸如HTTP、JSON、OAuth、OpenID等一些网络技术。

这个的优势在哪里呢?一般来说,从大多数基于web应用中派生出来的一个共同的优势是:开发者不用安装IDE,也不用一直保留一个(假设他们用了一个由其他人提供的主机服务实例)。它非常适合于 Web 开发,因为开发者已经用浏览器来进行测试和调试。Orion 是用 JavaScript 开发的,这意味着它的目标受众——Web开发者——应该也有能力扩展和帮助项目的发展。

Orion具有非常好的可扩展性,现在已经有一个插件架构在其上运行。然而,Orion处理插件的方式可能与你之前使用的方式有些差异。不同于在Orion托管的服务器端安装一个插件,Orion的插件 link 到那些 host 插件 JavaScript 源代码的外部网站上。这消除了开发者通过接入服务器来安装他们所需要的插件的做法。相反,他们可以链接到(或创建)插件,然后指向它们。

这些插件一旦被安装了就会一直存在着—也就是说,开发者在第一次用Orion指向它们之后就不用再重新安装了。目前,Orion并没有一个计划来保证插件不是恶意的或者提供一个kown-good插件库。如果Orion能发展起来的话,人们希望这个功能能增加进来。

Orion的开发原则是建议在任何时候都要重复使用已经存在的工具,而不是创造一些新的工具。有这么一个例子是,Orion正致为于Firebug的整合,并让Firebug 调用 Orion 当编辑器使

获取和使用Orion

开发者使用Orion有两个办法。其中一个就是注册Orion的托管版本,叫做OrionHub。但是你也许想抓紧时间注册---根据测试公告,这个服务仅对最先注册的5000个开发者开放。当Orion社区发展以后,也许会增加新的账号注册——但在公告中并没有做出任何承诺。

或者你可以在你自己的机器上下载安装Orion。这个项目提供了用于Windows、Mac OS X、Linux的版本。相对于简单地注册OrionHub来说,安装稍微有点复杂,但是对程序员来说可以更多的控制,甚至修改 Orion 的功能。要特别提醒那些正在运行他们自己Orion实例的人们,需要注意----现在的Orion没有内置升级功能。这也就意味着,作为一个快速发展的项目,你也许不得不经常手工升级,所以必须记得自己备份用户帐号和数据。在wiki上有一些关于demo上如何清除服务器端数据的指导,你可以用这些指导来找出备份帐号和数据的方法。

在花费了一些时间来看Orion能提供什么之后,我得出的结论是它还需一些工作要做才能适合普通用户使用。事实上,Orion 的 FAQ也这么说. 尽管Orion团队正在自己使用它们,但是对于进行“实际的工作”Orion尚未做好准备。Orion最近仅仅获得了一些类似于HTML的语法高亮功能,仍然缺少 JavaScript 语言的代码完成(但是已经可以部分的支持 css 开发了)功能。现在是用 Textmate 的 grammars 做的语法高亮。想 hack 出自己所使用的语言的功能可以参考 wiki

Orion 已经可以跟Git库协同工作,包括从 OrionHub 向 Github 去 push。但目前最好还是用另外的Git客户端来完成 。Orion同时也缺少对其他版本控制系统的支持,Subversion、Mercurial或者其他VCS的用户暂时比较背。

Orion的下一个里程碑定于6月3日。这个版本会简化服务器配置,移动到 Dojo 1.6上,为内容辅助、按键设置提供扩展点,以及和不同的 Web 编辑器集成。Orion 已经获得了 Mozilla 的一些关注,打算将 Orion 编辑器放到 Mozilla 代码库里。从Orion的开发列表来看,这个项目已经相当活跃。

从目前来看,Orion并不是一个严肃的开发工具。尽管现在它已经具有了一个好的开发环境的开端,但是目前还无法在生产环境中使用;或许一年后它能做到这一点。如果你希望用它来开发你的下一个网站,你最好不要抱太大期望。然而,如果以浏览器为基础的网络开发环境的概念激起了你的幻想,那么Orion项目就是为了做这种贡献而开放的。关注这个项目是如何发展以及基于浏览器的模型超越桌面工具都将会是一件很有意思的事情。

Topic: sohulinux

支持内存能耗管理的 VM Infrastructure

From: Ankita Garg
Date: Fri, 27 May 2011 18:01:28 +0530
http://lwn.net/Articles/445045/
翻译:王鑫

现代的系统为了满足应用程序的需要,在每一代都会提供更高性能的CPU以及更多的内存。内存子系统已经开始提供更为广泛的能力——电源能耗的管理,这就促使我们需要重新审视操作系统管理内存的方式。Linux VM 子系统如今使用复杂的算法来优化管理资源以求获得最好的整体系统性能:除了内存区域的容量和地址外, VM 子系统若有必要也会跟踪内存区段特定的受限的寻址,以及和CPU的相对距离而定义的不同NUMA节点。考虑到各类不同主存比如PCM、或者non-volatile RAM中的内存子系统的能耗管理能力,可以开发出 Linux VM 子系统新的边界能力和属性,从而进一步被内核和应用程序所利用。

本补丁集提供了一个可以被用来标记那些属于特定内存能耗管理领域的内存块的边界的通用memory regions架构,并且从长远来看,还能够在内存能耗管理功能平台上做进一步探索。

Linux VM如何帮助节省内存功耗的?

  • 合并内存分配的并且(或者)引用那些没有在整个内存空间被分散的。基本上,没有被引用的内存区域,可以处在低功耗状态。
  • 支持目标内存回收,对于那些特定部分的内存能够被轻易地释放,允许那些被置为低功耗态。

什么是Memory Region?

Memory regions是一个开启了虚拟内存管理的通用内存管理框架,它充分考虑了内存分配和回收时的内存特性。它是位于真正的NUMA节点之下的抽象出来的一层,并将下层的内存硬件信息封装于其中。这一层是在启动时就被创建的,并且含有相关平台可管理内存功耗粒度的固件中的信息。比如,在支持“部分数组自刷新”(PASR:Partial Array Self-Refresh)[1]的平台上,regions可以按内存单元对齐,而这可以使其独立地自刷新或者关闭(内容破坏关闭)。另一方面,支持多内存控制器的平台则是这样控制内存的功耗状态的——为单个内存控制器下的所有内存只创建一个memory region。

对齐的目的是为了确保内存的分配、重分配以及回收是在一个确定的硬件边界上执行的。通过在memory region中创建区段,伙伴分配器将会在区域级别上操作。提出的数据结构按下图所示:

Memory regions有以下功能:

  • 按照内存区域的顺序进行连续内存分配,因此保证了大号的内存区域总是比开头的那些内存区域缺少可分配的地址。
  • 然而随着时间的推移,分配的内存将会分散到不同的区域。但是区域边界的概念和区域级内存统计将会保证通过目标内存分配和回收来使得特定regions被释放。

Mel Gorman提出的块式回收以及其它内存压缩策略,将会更进一步合并内存[4]。

Memory regions只是一个最基础的架构,它将使Linux VM知道物理内存硬件的特性,同时它也是实现其它复杂算法和技术来真正节省功耗的根本。

进阶

Memory regions框架是同现有的内存管理数据结构一起工作的,并且只是添加了一个被要求捕获特定边界和属性信息的抽象层而已。大多数VM代码路径同当前的实现相似,只是额外多了以预定义顺序对区段数据结构的遍历而已。

其它方法:

当然也存在着一些把同属于同一功耗范围的内存分组的其他方法。在真实的NUMA节点下伪造NUMA节点可以把内存硬件单元的信息封装起来以进行独立的能耗管理。通过最少的代码改动却可以完成像memory regions一样的功能。然而,伪造NUMA节点并不是一个很直观的解决方法,它破坏了NUMA的语义并且事实上并不通用。通过展示比真实情况的更多的NUMA节点,它呈现给管理员的并非是系统的真实情况。

挑战

内存的交叉存取被广泛地用在所有平台上来增加内存的带宽,提升内存的性能。然而,交叉存取会降低硬件中闲置内存的数量,从而影响了节省能耗。对于一个给定的平台,选择一个即有好的性能又有最优的能耗节省的策略是十分重要的。

本邮件的附件是一个 Request For Comments 补丁集,用最少的功能代码演示了可以实现的选项。它已经在1Gb的RAM的TI OMAP4 Panda板子和Samsung Exynos 4210板子上测试过了。这个补丁在这两个平台下以默认的配置文件编译的,可以被应用在内核版本为2.6.39-rc5上。我关闭了cgroup,内存热插拔,和kexec。对于这些框架的支持可以很容易地被扩展。u-boot的引导程序还没有导出关于物理内存条的边界信息,因此regions并没有按照硬件正确对齐,当然只能以硬编码的方式来做测试和演示。而且,代码假定节点中至少有一个区域。memory regions的编译时间排除将是下一步要做的事情。

运行结果

在Samsung Exynos 4210板子上,2GB RAM,以4个memory regions启动,每个region 512 MB大小的环境下,运行pagetest——一个简单的分配和访问指定页面号的页面的简单的C程序。分配的大小是512MB。下面是运行这个基准程序时的空闲页的统计:

(区域3的总页面数是57332,由于它包含了剩下的所有页面,因此区域大小并不是512MB)。

第一列代表了每一个region在基准的起始处的空闲页的数目,第二列在480MB的地方分配的空闲页数目,第三列则是512MB。region 1、2和3的内存是空闲的,只region 0被使用了。因此如果region按照硬件内存单元对齐的话,空闲region则可以被潜在地置为低功耗状态或者关闭。当然也可以不用这种方式从低址分配,但是一旦页面回收开始运行,页面的分配将会分散开来。

参考文献:

[1] Partial Array Self Refresh
http://focus.ti.com/general/docs/wtbu/wtbudocumentcenter.tsp?templateId=...
[2] TI OMAP$ Panda board
http://pandaboard.org/node/224/#manual
[3] Memory Regions discussion at Ubuntu Development Summit, May 2011
https://wiki.linaro.org/Specs/KernelGeneralPerformanceO?action=AttachFil...
[4] Memory compaction
http://lwn.net/Articles/368869/

Topic: sohulinux

Android 权限

By Jake Edge
June 2, 2011
Phones and permissions

翻译:刘晓佳

对应用而言,Android 权限系统采用的是一种非此即彼的机制;要么授予应用所有要求的权限,要么就无法安装。现在我们已经可以在安装的时候了解到应用都需要哪些权限,但对于非常在意隐私和安全的用户来说,能够选择否决某些权限——那些没有和该 app 正常应用有明显关联的权限,是一个更有用的功能。五月中旬以来,基于Android的CyanogenMod固件在其git tree中已经有了这项功能,然而令人惊讶的是,基于这项功能的一个新补丁遇到了一些阻力。

加入权限撤销特性的原始补丁是由Plamen K. Kosseff提供的,但该补丁解决了某些应用程序没有获得期望权限而崩溃的问题。另外,是否启用权限撤销功能可以在 CM 的“Performance Settings”菜单中选择,即使这个功能有 bug 用户也可以简单的 disable 之。现在 Kosseff 基于这个早期工作又提交了一个补丁,它允许用户“欺骗性”地授予 apps 某些权限。一个例子是,应用要求获取 IMEI 的时候提供一个假串号——这让包括CM创建者Steve Kondik在内的某些开发者很难接受。

如果没有伪造 IMEI 串号这个功能的话,也许该补丁早就被接受。Kosseff 的补丁里还有不少在隐私方面争议更小的特性。在补丁的注释中他描述了其它的方法,包括限制联系人列表中哪些信息可以传递给应用程序,或者仅仅显示SD卡的一部分内容给应用程序。不管哪种方法,都明显提高了隐私性,而且应该不会给应用开发者带来任何问题。

返回一个假IMEI值(或者返回一个假SIM ID和手机号码)主要令人争议的是,通常应用开发者都需要该信息来进行数据收集。尽管数据收集可能会被用在恶意企图,但从社区中大伙这个补丁的评论中很明显感觉到,大部分应用开发者是善意的使用该信息统计使用状况。Kondik和其他人都认为,把 CM 弄成一个对应用开发者“有敌意的环境”是会导致整个生态圈的排斥,包括应用开发者、Google、手机制造商、移动服务运营商。

但是,正如Kosseff所问到的,难道最终用户不应该为让应用程序访问哪些信息而做出决定吗?对于IMEI和相关信息,现在看来从CM开发者那里得到的答案是“不”。对于一个以解锁所有硬件潜力为目标的固件版本而言,这样做有点违背它的理念。其它项目,比如 Guardian,对这种补丁很可能就接受了。

争议的一部分在于作为使用它们代码的代价,程序开发者有权"拥有"什么并不清晰。对付费的应用来说,再清楚不过了,因为比起付费来没有更好的方式让应用开发者得到更多了。对免费应用来说,情况变得有些模糊。如果某休闲游戏获得了通讯录访问的授权,那么收回该权限或者提供一个空通讯录,这是否合理呢?此外,许多免费应用使用网络权限来抓取广告并显示在它们的应用中,这也是一种开发者使用来为开发程序提供经费的一种收费方式。此时收回权限对开发者来说是否公平呢?另一方面,如果应用发现(无法访问网络所以)无法播放广告,是否就该拒绝运行呢?

对于这些问题,并没有些简单的答案。对该问题的一种解决方案就是避免应用程序请求比它们需要的更多的权限,但是这些权限实际上并没有划分的足够细来阻止滥用。如果某人授予电子书阅读器使用SD卡的权限(假定SD存储了所需要阅读的电子书),这是否意味着可以延伸到获得其它电子书应用存储的资源的权限呢?这也假定需要网络权限来从不同地方抓取内容,那么也能使用该权限从手机中复制一份用户的阅读习惯吗?

对大多数消费者来说,这些保护措施大都没有意义。在我们看到的消费者的PC世界里,如果用户在获得最新款游戏,鼠标,或视频内容时需要安装某些东西的话,用户将会安装几乎任何东西,甚至会忽略来自系统的安全警告。但是对于我们来说,可能仅仅关心我们存在手机上的数据是否安全,而对授权给应用程序的权限进行更多的控制来解决这方面的问题却还需要走很长的路。一个免费应用程序的健康生态系统需要走的更远才行。

Topic: sohulinux

Scale Fail (part 2)

May 20, 2011
This article was contributed by Josh Berkus
Scale Fail (part 2)
翻译:刘晓佳

上一部分中,讨论了若干影响网站扩展性能的问题,而大部分其实是管理的问题。上一篇文章主要涉及到了公司所做出的一些欠缺长期考虑的决策-或者叫它“反模式”,比如compulsive trendiness, lack of metrics, "barn door troubleshooting", and single-process programming。这一期,我们将探索导致停工的一些更一般的技术管理失败。

No Caching

“报告显示每秒完成了7000次读查询。你确定它们都能被缓存吗?”
“我们已经安装了memcached”
“memcached是如何配置的?缓存了哪些数据?如何使缓存更新?”
“我…不太确定。我们都留给Django解决吧。”

我有时对web公司愿意在更快的硬件上花多少钱,和愿意在一些能够使得他们的应用在平稳的方式下运行的更快的简单事上所花的努力感到非常吃惊。比如,如果你打算扩展一个网站,首先应该问问自己:“我该在哪加一个更有用的缓存呢?”

上面提到的memcached,并不仅仅指简单的数据cache。对任何一个真正可扩展的网站,你可以加入多级缓存,每一级都大有用处:

  • database connection, parse and plan caching
  • complex data caching and materialized views
  • simple data caching
  • object caching
  • server web page caching

详细分析不同类型的缓存和如何使用这些缓存需要一系列的文章来阐述。然而,每种形式的缓存都共享了将数据发给用户而不管用户在哪和减少响应次数的能力。更为重要的是,通过降低重复应用请求所需要的资源,能够提高你的平台的效率,从而使得它更具扩展性。

看起来很明显,不是吗?但我一只手就能数出在雇佣我们之前就已经具备有效缓存策略的公司。

客户在数据缓冲方面常犯的一个错误是让ORM来完全决定缓冲。问题主要在于作为一个即开即用的方案, ORM无法有效的使用cache,对于完全一致的用户请求才请求缓存,导致命中率几乎为0

我所见过的一种最坏的情况是一个在线拍卖的应用程序。用户做的每件事,如每次点击,每次翻页,每次鼠标移动,都会导致对后台PostgreSQL数据库的查询。加上拍卖的桌面精灵轮询查询拍卖数据库,每用户每秒更新30次。这意味着每个程序的用户每秒将会完成查询内核事务处理数据库100次。

缺乏缓存是个非常常见的错误,下面是另一个我喜欢称之为反模式的一种症状:
伸缩不可能的事情

“在发展的第三阶段,我们会将数据表根据统计出的用户分组分割成12个shard。
没有被分割的数据需要在每个shard上复制,并且我也发明了一种复制机制来
完成这个任务。”
“看起来很复杂。你考虑过仅仅缓冲最常用的搜索吗?”
“那不行。我们的数据太动态了。”
“确定吗?我做了一些分析,当前数据库的90%的访问属于四种模式之一。”
“我告诉过你,它将不工作。我才是这里的CTO!”

你的应用程序所需要的某些东西很难扩展,但消耗了大量的系统资源,管理时间和员工的创造性来做这种无意义的事情。这包括事务性数据库,队列,共享文件系统,复杂的web框架(如Django或Rails),和ORMs。

你的基础架构的其他部分很容易扩展许多用户的请求,如web服务器,static content delivery,缓存,本地存储,客户端软件(如javascript)。

基本上,当一个架构越状态化,复杂化,特色化,每个应用的用户使用的资源就会越多,越容易出问题-因此也就越难扩展。通过这个,你也许会认为与快速解决扩展化问题斗争的公司会首先集中扩展容易扩展的,并尽可能推迟那些难以扩展的。

这你就错了。

相反,开发部门的领导貌似热衷于先解决架构中最难扩展的问题。数据库Sharding,负载均衡主从服务器复制,转发事务性队列,200个节点的集群文件系统-这些都会令IT民工们兴奋,而且得到大量的资金上的支持。而有时只需要通过增加一个低成本/简单的Varnish(Varnish是一款高性能的开源HTTP加速器)节点就能解决问题,或修补程序中资源消耗的大户。

比如,我们有个客户的Django服务器过载后down掉了。他们的服务器数量从四台增加到八台,仍旧需要定期重启,需要将应用服务器的数量再加一倍,而这需要扩展数据库服务器。相反,我们做了一些流量分析,发现大部分Django服务器的资源利用在服务静态图像上。我们就把所有的静态图像移到了CDN上,然后就能够减少服务器的数量了。

故障的单点/SPoF

“我们如何负载平衡中间件服务器和数据库服务器之间的连接?”
“通过Zeus负载均衡群。“
“从web服务器到中间件服务器呢?“
“同样是Zeus群。“
“Web服务器到网络文件存储呢?数据中心之间的VPN呢?SSH访问?“
“Zeus。“
“该网络上的一切都通过Zeus吗?“
“是的,相当的多“
“好吧,什么可能导致错误呢?“

SPoF,当然,代表着Single Point of Failure。特别的是,它指的是这样一个部件,如果它失效,将会导致整个系统不能工作,而不管其它地方有多么冗余。令人失望的是多少公司花费了大量的硬件和工程时间来使得它们的很多部件高可靠性,却没能移除SPoFs。最终你的系统的可靠性是由最不可靠的部件决定的。

上面对话中的公司在那次会话后的几周的某天就垮掉了。一个系统管理员下载了一个buggy配置到Zeus上,立马整个网络就瘫痪了。数据库服务器,web服务器,和其它服务器都正常运行着,但是甚至就是管理员都无法访问它们。

有时,你的SPoF是一个人。比如,你有一台服务器或甚至一个数据中心,它们只有通过手动操作才能失效,仅有一个员工了解相关知识或者能够登录进去操作。更险恶地是,这些SPoF经常潜伏在你的开发或恢复过程中。我曾目睹过一个公司为了防御DDOS攻击而部署了一套热代码,仅仅让热代码仓库down掉,系统就无法修复了。

"Cascading SPoF"是指那些看起来有冗余措施的SPoF。这里有个简单的数学练习:你有三台应用程序服务器。每台都工作在它们最大能力的80%上。当其中一台失效后,且它的流量均衡到另外两台上面会发生什么情况呢?

并不是说某个组件是唯一的才成为单点;它仅仅需要成为导致失效的一种情况而已。如果所有的组件都工作在接近最大能力的情况下,那么你就有麻烦了,因为少数的服务器故障或者中等的流量增加就可以导致一系列级联的服务器失效。

云成瘾

“……所以如果你一直待在AWS平台上,你将不得不主要进行
横行的扩展,这将需要40K美金的咨询费的工程。如果你转
到传统的托管上,你大约需要10K美金的咨询费用完成迁移,
同时得到更好的应用性能。云服务的价格大约是自己租用机
架服务器的三倍。“
“不到明年我绝对不考虑迁移“
“所以你想花40K美金的合同吗?“

今年年初我曾参与一个火热的讨论,我逐渐发现了一种新的反模式,我们叫它“云成瘾“。我们的几个客户拒绝移走他们的云托管,甚至当它们几乎要毁掉它们的业务时。最糟糕的是AWS,因为亚马逊不支持仅迁移云的一部分(要么就全迁移走),其它的公有云也有类似问题。

云托管的优势在于它不需要预先的基础设施的投资就能启动新的应用和服务用户。作为一种降低创新门槛的方式,云托管拥有巨大的优势。

当应用扩展达到云服务器的资源限制时问题就出现了,不得不转换到新的平台。通常公司会通过超时,运行中断,逐渐增加服务器数量却不能改善性能等方式发现这些限制。提到限制,我指的是这种大规模的公有云自身的内存,处理能力,存储吞吐量和网络配置方面的限制,而且购买繁忙云实例的费用高昂。云服务支撑一个项目起飞是足够的,但是当你需要每个节点上严格的性能需求时就会启动失败。

那就是关于云的伸缩性问题。之所以会这样,是公司没有经验来管理基础设施,没有系统方面的人员,没有迁移的预算。更危险的是,管理人员没有做任何关于基础设施的决策。Advice that a change of hosting is required are met with blank stares or even panic.下一财政年度在启动,实际上是委婉的说永远不会启动。

结论
当然,这些并不全是扩展反模式。个人管理不善,没有预期到需要峰值,缺乏部署工程,依赖不可靠的第三方社团,以及其它一些问题,和我之前所概括的那八个问题一样都可能造成严重的损害。也可能有许多不扩展的方式。我无法一一列出。

只是希望这篇文章能有助于你认识到发生在你自己公司或客户中的这些“scale fail“的模式。我所概括的这些问题主要归结于失误的决策-而不是任何技术方面的限制。就我所经历的,技术方面的问题很少抑制web生意的增长,往往都是来自管理方面的问题造成的。如果你能识别出反模式,你就能够犯更少的错误。

Topic: sohulinux

prefetch的问题

By Jonathan Corbet
May 24, 2011
The problem with prefetch

翻译:曾怀东

随着经验的增长,软件开发者会发现微优化的努力并不值得,尤其是在缺少针对具体问题的硬数据(hard data)的时候。性能问题通常不是出在我们认为的位置,所以没有头绪地进行调整试图获得更好的效果可能是徒劳的,甚至可能使事情变得更糟糕。这是内核开发人员得到的教训。

在内核层面,性能通常受缓存行为的影响。真正高性能要求只有命中cpu缓存才能够满足,内存访问相比较显得过于缓慢了。内核尽量地使用cache-hot memory;以及其它一些其它重要的工作,例如调整数据结构使得经常被访问的数据位于同一条cache line中。作为通用的准则,这些优化方法对性能的提升很明显。

百分百命中缓存是难以达到的,但是也可以想办法尽量提高命中率。如果内核知道最近将要访问的数据所处的位置,它可以使用CPU提供的 prefetch 指令将数据放入缓存。这种指令是通过内核prefetch()函数实现的;开发者已经在广泛使用这个函数。例如通常使用的
宏:

#define list_for_each(pos, head) \
for (pos = (head)->next; prefetch(pos->next), pos != (head); \
pos = pos->next)

这个宏是用于遍历一个链表。Prefetch()的思想是在处理当前实体的同时开始获取链表中下一个实体。希望在下一次循环开始前能够获取到数据,或者至少使这个数据已经开始传输。众所周知,链表是对缓存不友好的数据类型,所以这种类型的优化能够有效提升速度。

但实际上这样做并不能提升速度,至少在x86处理器上不能。

Andi Kleen可能是第一个对这一优化方法提出疑问的,去年九月他尝试移除list操作中的prefetch。他的patch引发了小规模的讨论,但是显然误入了歧途。最近,Linus在自己最喜欢的workloads(内核builds)之一上做了一些分析然后发现prefetch 指令集占据了极大比例。执行Prefetching所消耗的时间超出了缓存带来的好处;将prefetch()移除能够让made和build更快。

Ingo Molnar,牛人 Ingo,也关注了这件事情,他进行了很有意义的研究。通过使用perf和一些细微的kernel调试,他证明了使用prefetch()结构造成了0.5%的性能下降。这不是一个简单的性能退化,它本来被指望带来更快的速度,一定有什么地方没有按照人们想象的方式运行。

Linus指出其中最明显的一个问题:他的测试引入了大量对单链哈希表(singly-linked hlist hash table lists)的遍历。这些列表比较短,所有没有足够的范围实现prefetching;事实上,大部分时间中,唯一的prefetch操作仅是在尝试使用指向列表末端的空指针。Prefetching 一个空指针看起来没啥消耗,但实际上是有代价的: 在 x86 上(ARM 也是如此)的每一条这样的指令都会导致 a translation lookaside buffer miss and a pipeline stall. Ingo 测算得出空指针的 prefetch 大约消耗 20 个 CPU 周期.

很明显,空指针 prefetch 不是个好主意。如果CPU可以简单的忽略对使用空指针的prefetch尝试那么会好一些。但是,从软件层面解决并不是最好的办法。Ingo对只prefetch非空指针版本的prefetch()函数进行了测试。这个版本确实性能更好。但是仍不如不使用prefetch的方案。

CPU设计者很清楚内存等待的代价;他们花费了大量的努力将任何可能的代价都降到最小。CPU有自己的内存prefetch单元,这些单元尝试预测下一次需要的内存并提前对内存进行遍历。Ingo在他的测试中提到,即使没有任何软件层面的prefetch操作,cpu进行的prefetch操作数量几乎是相同的。所以硬件prefetcher一直处于繁忙状态-并且在决定fetch哪些内容方面上它比软件层面表现得更优秀。将显式的prefetch操作混入其中只会影响硬件的prefetch操作。

Ingo总结如下:所以即便将NULL的部分刨除,prefetches也明显是有害的。

他工作的成果之一:2.6.40(现在被起名叫3.0了),将prefetch()操作从链表,哈希表以及sk_buff表的遍历操作中移除,正如Andi Kleen在九月份尝试做的那样。或者其他的prefetch操作也被移除的话性能也有提升的几率。内核中仍然存在prefetch()操作,不过只存在于特定的能明确提升性能的场景。如同我们尝试的其他底层优化(立刻能想到的就是likely()),我们自以为prefetch能带来帮助,但并不是我们真正需要做的工作。

这个事情的另一个经验是numbers matter。Andi在移除这些操作的时候是正确的,但是他不能说服社区接受自己的补丁。这一次,除了Linus注意到它并进行了研究外,更重要的原因是基于性能的补丁确实需要用数据来证明自己能够达到设定的目标。如果Andi花些时间量化他的做法带来的影响,上一次可能就已经被大家接受了。

Topic: sohulinux

WebGL 的安全问题

By Jake Edge
May 25, 2011
WebGL vulnerabilities
翻译:李凯

最近的报道强调指出,在WebGL中某些现存以及潜在的安全漏洞正在被广泛传播。显然,这种允许网页内容与复杂的3D图像硬件之间互操作的新特征很会导致一系列的问题。该特性肯定会在浏览器上全面支持,事实上已经有几个浏览器已经具备了这个功能。

WebGL是一种底层的3D图像API,该API基于目前多数3D图像卡库采用的OpenGL ES 2.0标准。支持WebGL的浏览器,JavaScript 控制的 canvas元素将可以被硬件加速显示。对网页浏览器而言,无论是玩游戏还是探索三维景观,当然也包括大量其他的用途,WebGL都将会是一种非常受欢迎的扩展。但是,允许互联网中的内容与复杂的硬件进行交互很可能会导致一些安全问题。

典型的图形硬件是由通过驱动连接的一个或多个图形处理器组成的。驱动提供了与高层库之间的某些标准化接口,这些高层库采用了诸如OpenGL之类的图像标准。为了给图像程序员提供更多的灵活性,把特定处理模型以库方式提供的称为shaders。shaders是用来对复杂的图形处理进行渲染,图形库和驱动把那些程序转换为硬件中的GPU运算。

本质上,那意味着恶意网站可以编写出运行在用户硬件上的semi-arbitrary程序。仅仅这一点就应该足够让我们停下来好好考虑考虑安全的问题了。例如一个恶意的shaders可能完全控制了图形硬件,从而破坏任何试图写入到显示器的东西(如其它窗口)。在最糟糕的情况下,这可能会导致用户不得不重新启动图像硬件。

上述拒绝服务可能是极其恼人的,但并不会直接影响桌面的安全问题。它不会泄露用户数据到恶意网站,尽管它可能会由于用户的某些行为而导致数据丢失。这有点像某些恶意的JavaScript,比如无限循环程序,可锁住一个浏览器(但一般不是整个桌面)。现代浏览器把每个标签作为一个独立的进程运行,(例如Chromium就是这么干的,Firefox正在朝这个方向努力)这在很大程度上限制了类似JavaScript问题。

但是这并不是Context(一个英国安全咨询公司)报道概述的唯一的问题。潜在的问题是跨域的图片偷窃。当canvas元素包含跨域的内容,且声明一幅图像来源于其他网站时,有一个“origin-clean“标志将会在浏览器中被清除掉,这样做是用来避免通过JavaScript函数从外域提取图像数据。然而,恶意的canvas元素可以创造shaders从而很容易泄漏影像内容。

这种袭击依赖于一种通过时序分析提取加密密钥的技术。通过计算shaders描绘一个像素的“亮度”要花多长时间,JavaScript可根据该值再生图像。这是一个复杂的攻击,并且要找到真正使用它的exploit有些复杂,但这正好是跨域的一个缺陷。

Mozilla 的黑客 JP Rosevear 认为跨域的图片信息盗窃是一个真实的威胁,即使实践中很难找到漏洞。"While it is not immediately obvious that it can be exploited in a practical attack right now, experience in security shows that this is a matter of when, not if." 他对此的建议是 CORS 草案(cross-origin resource sharing),即让站点明确哪些外域可以包括它们的内容。

防止拒绝服务问题更加的麻烦。唯一真正防御恶意shaders的方法是用审查shaders代码。所以Rosevear建议在需要展示WebGL内容前进行用户确认。

也有一些在硬件层面上努力着试图处理拒绝服务的问题。GL_ARB_robustness(和GL_ARB_robustness_2),是硬件制造商用来检测这些问题和当出现问题时重启硬件的一种机制。但就像Context的FAQ里所说,这可能并不是真正解决问题的办法:

  1. 重置图形卡和驱动应该被看作是当发生异常情形时,维持OS稳定性的辅助手段,并不是一种用来保障用户免受恶意代码的机制。重置图形卡并不能保证整个操作的顺利进行,图形子系统的用户需要正确地处理这一事件。图形攻击需要确保在防范另一个应用程序滥用硬件资源前,任何的硬件资源都可以被重建。这一行为不能直接引起拒绝服务,却仍然可以间接影响整个系统和运行在上面的应用程序。

从安全角度来说,在系统硬件上允许运行从任意网站上发送来的代码,永远是有问题的。Rosevear 指出 WebGL 组件应该分成若干部分以提供必要的隔离: "Nevertheless, claims of kernel level hardware access via WebGL are speculative at best since WebGL shaders run on the GPU and shader compilers run in user mode." That assumes that the libraries and drivers don't have exploitable bugs of their own, of course. 正如Rosevear指出,“对[WebGL的]重大攻击是可能的”。这显然是值得关注的一个领域。

Topic: sohulinux
订阅 RSS - qyb的博客