Erlang程序设计03

译者序

  另辟蹊径——从容面对容错、分布、并发、多核的挑战。

  作为一名程序员。随着工作i经验的增长,如果足够幸运的话。终有一日,我们都会直面大型系统的挑战。最初的手忙脚乱是难免的,经历过最初的迷茫之后,你会惊讶地发现这是一个完全不同的“生态系统”。要在这样的环境中生存,我们的代码需要具备一些之前相当陌生的或者闻所未闻的“生存技能”。容错、分布、负载均衡,这些词会频繁地出现在搜索列表中。经历过几轮各种方案的轮番上阵之后,我们会开始反思这一系列问题的来龙去脉,重新审视整个系统构架,寻找瓶颈所在。你可能会和我一样,最终将目光停留在那些之前被认为是无懈可击的优美的代码上。开始琢磨:究竟是什么让他们在新的环境中“水土不服”,妨碍其更加有效地利用越来越膨胀的计算资源?

  其实,早在多年以前硬件领域上的革命就已经开始,现在这个浪潮终于从高端应用波及常规的计算领域——多核芯片已经量产,单核芯片正在下线——这场革命正在我们的桌面上演。时代已经改变,程序员再也不能坐在家中装作什么也没有发生。问题已经自己找上门来了。由单核CPU频率提升带来软件自动化加速的时代已经结束。性能的免费大餐已经结束。“生态环境的变化”迫使代码也必须“同步进化”。锁、同步、线程、信号量,这些之前只是在教科书中顺带提到的概念,越来越多地出现在我们日常的编程中,接踵而至的各类问题也开始折磨我们的神经。死锁、竞态、越来越多地锁带来了越来越复杂的问题。

  在多核CPU的系统上,程序的性能不增反降,或者暴露出隐藏的错误?

  在更强的硬件平台上,程序的并发处理能力却没有得到提升,瓶颈在哪里?

  在分布式计算网络上,不得不对程序结构进行重大的调整,才能适应新的运算环境?

  在系统的关键应用上,不得不为软件故障或者代码升级,进行代价高昂的停机维护?

  ......

  这一系列问题,归根结底,都是因为主流技术体系在基本模型上存在着与并发计算相冲突的设计。换句话说,问题广泛地存在我们所写的每一行代码中。在大厦初建的时候,却猛然发现每一块砖石都不牢固,这听来很有一点耸人听闻,但是这种事并不罕见。

  比如:x=x+n,即使是这个再常见不过的语句,也暗藏着烦恼的根源(你也可以把它称作内存共享陷阱)。从机器指令的角度来思考,可能做了这么几件事(仅仅是在概念上)。

  (1)mov ax,[bp+x];将寄存器ax赋值为变量x锁指示的内存中的数据。

  (2)mov bx,n;将寄存器bx赋值为n。

  (3)add ax,bx;将寄存器ax+n.

  (4)mov [bp+x],ax;将变量x所指示的内存赋值为寄存器ax中的数据。

  理论上,这是一个原子操作,在单核CPU下情况也确实是如此,但是在多核CPU下,就全然不同了。如果在每个核心上都有一个正在执行上述代码的进程(也就是试图对这个代码执行并行计算),问题就出来了。这里的x是在两个进程之间共享的内存。很明显,在第(1)步到第(4)步之间,需要某种机制来保证“某一时刻”只有一个进程正在执行,否着就会破坏数据的完整性。这也就意味着这样的代码无法充分地利用多核CPU的运算能力。也罢,咱们不加速就是了,但是更糟的是,为了保证不出错,还需要引入锁的机制来避免数据被破坏。现在的主流技术体系全都建立在内存共享的模型上,像x=x+n 这样的代码几乎无处不在,但是在多核环境下,每一处这样的代码(逻辑上的或者事实上的)都小心地处理锁。更糟糕的是大量的锁彼此之间又会相互影响又会导致更为复杂的问题。这迫使程序员在复杂度程序之外还要极度的耐心和娴熟的技术来处理好这些沉闷和易错的锁,且部说是否可能,但是这至少也是一个极为繁重的额外负担。

  Erlang为了并发而生。20多年前,他们的创建者就已经意识到了这一问题,转而选择了一条与主流软件完全不同的路(还有为数不多的另外几种语言也是如此)。他采用的是消息模型,进程之间并不共享任何数据,因此也就完全避免了引入锁的必要。对于多核系统而言,完全无锁,也就意味着相同的代码在更多核的CPU上会很容易地具有更高的性能,而对于分布式系统,则意味着尽可能地避免了顺序瓶颈,可以更多的机器无缝地加入到计算网络中来。用甩掉锁的桎梏,无疑是对程序员的解放。

  不仅如此,Erlang在编程模式上走的更远。他在语言级提供了一系列的并发语言,通过这些原语,我们可以用进程+消息的模型来建模现实世界中多人协作的场景。一个进程表示一个人,人与人之间并不存在共享的内存,彼此之间写作完成完全通过消息(说话、打手势、做表情、等等)交互来完成。这正是我们每个人生而知之的并发模式!软件模拟现实世界协作和交互场景——这也就是所谓的COP(面向并发编程)思想。

  在错误处理上,Erlang也有与众不同的设计决策,这使得实现“容错系统”不再遥不可及。COP假设进程难免出错——不像其他某些语言一样假设程序不会出错。他假设程序随时可能会出错,如果发生错误的情况则不要尝试自行处理,而是直接退出,交给更高级的进程来处理。通过引入“速错”和“进程监控”的概念,我们将错误分层,并由更高层的进程来妥善处理(比如,重启进程,或者重启一系列进程)。有了这样的概念作为支撑,构造“容错系统”就会变得易如反掌。在这样的系统之下,软件错误不会导致整个系统的瘫痪,发现错误也无需停机就可直接更新代码,在配置了备份硬件之后,硬件的错误也不会影响服务的正常运行。这么做的结果相当的惊人,使得Erlang的电信guanjiancp,达到了传说中的9个9的可用性(99.9999999%)

  Erlang采用虚拟机技术实现,用他编程的程序可以部经过修改直接运行在从手机到大型机几乎所有的计算平台之上。这是一项有着20多年历史的成熟技术,有着相当多的成熟哭、库(OTP)和开源软件,这些资产是的她有极高的实用价值。Erlang本身也是开源资源,这扫清了对于语言本身生命力的疑惑。Erlang还一个充满活力的语言,在他的社区,常常能够见到Joe Armstrong等语言的创建者在回答问题,这一点尤其宝贵。在熟悉了Erlang的思维方法和社区之后,很多人都发出了相见恨晚的感慨。

  虽说对于并发而言,Erlang的确是非常好的选择,但是这么多年以来,业界对于并发预料之中的增长却一直没有真正发生。此前,这类应用更多地局限于想一些相对高端的领域,而Erlang身上浓厚的电信背景,又使得第一眼看来他更像是适用于电信行业(实际情况远非如此)。长期以来Erlang的使用群体仅仅局限在一个狭小的技术圈子之内,他处于“非主流技术语言”的边缘位置。这种情况直到最近两年,Google的成功使得其引为核心的大规模分布式应用模式广为人知,而多核CPU进入桌面也迫使“工业主流”开始认真对待并发计算,直到此时,解决这类问题最为成熟的Eralng技术,才因其难以忽视的优势而引起人们的广泛关注。

  从历史的眼光来看,在计算机语言荣誉堂内,上演着一代又一代程序语言的繁荣和更替,潮来潮往让人难以琢磨。这与其说是技术不如说是潮流。对于Erlang这个有些怪异的小众语言来说,是否能够真正成为”下一个Java ”?还难以预测,而且也不重要。但是有一点已经毫无疑问,那就是“下一代语言”至少也要向Eralng一样,处理好与并发相关的一系列问题(或者做得更好)。也许将来的X++(或者X#)语言在吸收了他的精髓之后,又会成为新的工业主流语言。但是既便如此,先跟随本书的作者开辟的小径信不浏览这些饶有趣味的问题肯定也会大有帮助。

  对于想要学习Erlang的读者,虽然说语言本身相当简单,可是要想运用自如也是有很大的难度的。比如,在适应COP之后会觉得非常自然,但是对于有OOP背景的程序员涞水,从固有的思维习惯转到COP和FP(主要是和自己的思维习惯较劲)上需要一个过程。此外OTP和其他Eralng社区多年积累的财富(这些好比JDK,EJB之于Java)也需要一定的时间理解和吸收。但是这些有价值的资料大多零星地散落在邮件列表和独立的文档之中,给学习者带来一定的麻烦。现在好了,有了Erlang创建者Joe Armstrong为我们撰写的“官方教程”,这些问题都已经迎刃而解。

  一般而言,由语言的创建者亲自撰写的教程,常常都是杰作。在翻译的过程中,译者也常常会发住这样的感慨。在本书中,Joe Armstrong不仅全面地讲述了Erlang语言本身,还详细地交代了这些语言特性的来龙去脉。为社么要这么设计?除了掌握语言本身之外,有幸窥见大师精微思辨的轨迹,也是难得的机缘。书中的例子,还会将你为之惊异那些Erlang特性一一解密。通常是从一个不起眼的小问题开始。从宏观的分析到微观实现,层层深入细细道来。问题是什么?要如何建模?该怎么重构?各个版本之间的精微演化全然呈现,但是这些微小的改进,最终演化出了那些让人惊喜的特性整个过程可谓是相当精彩。

  本书有Eralng中文社区(erlang-china.org)组织翻译。其中,第一章到第十四章有金尹翻译,第十五章到附录F由赵东炜翻译,全书有赵东炜统稿润色和审校。

  由于时间仓促,加之译者水平有限,译文之处难免会有不足,欢迎读者批评指正。

(我感觉已经很好了 ——岑子哥)

赵东炜

2008年3月于北京

译者介绍

  赵东炜

  独立软件顾问,一直专注于Web应用开发,曾负责设计和维护某大型门户网站的多个核心应用,对高并发大容量的分布式应用领域有独到的见解。曾担任过软件开发工程师、系统架构师、技术经理、产品经理、创业者等多种不同的角色。闲暇时以思考技术问题为乐,从事软件行业10余年来,从最初的ASP/PHP到之后的Java/.NET以及现在的Ajax和Erlang,一直都活跃在技术的最前沿。2006年作为主要译者参与了Ajax in Action(中文译本《Ajax实践》,由人民邮电出版社出版)的翻译工作。之后为Erlang强大的并发能力所吸引,是国内学习和传播Eralng技术的第一批人。迄今已有两年多的实际开发经验。在2007年3也创建了Eralng中文社区(erlang-china.org),现在是国内Erlang爱好者聚集和分享资料的主要网站。

  金尹

  金尹,长期从事电信行业的大规模语言通信程序的研发,有丰富的并发/分布式网络系统的开发经验。业余从事于数学与编程语言理论,以及并行计算方面的研究。致力于在国内推广函数式语言的发展,分别在2001年和2006年在《程序员》杂志上介绍了Python、Eralng等前卫的编程理念。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值