BT

你的观点很重要! 快来参与InfoQ调研吧!

FlightCaster秘笈——Clojure和Rails

| 作者 Werner Schuster 关注 4 他的粉丝 ,译者 宋玮 关注 0 他的粉丝 发布于 2009年11月17日. 估计阅读时间: 12 分钟 | ArchSummit社交架构图谱:Facebook、Snapchat、Tumblr等背后的核心技术

亲爱的读者:我们最近添加了一些个人消息定制功能,您只需选择感兴趣的技术主题,即可获取重要资讯的邮件和网页通知

Clojure是JVM上的LISP,由Rich Hickey创建。过去一年中,它之所以受到广泛关注,最主要的原因是其并发特性,如支持软件事务存储(Software Transactional Memory——STM)及其他强大的数据结构。所以最近函数式语言颇吸引眼球,这也是很正常的。在Clojure 1.0 发布几个月之后,用Clojure实现的现实项目也终于出现了。

FlightCaster是一个新站点,用来提供航班延误预告。它的Web前台是用 Rails开发的,部署在Heroku上。后台处理数据的程序则是用Clojure开发的,用到了HadoopCascadingCloudera以及其他工具。

我们就该项目采访了Bradford Cross,了解用于开发FlightCaster的架构,如何用Clojure实现它,以及OOP程序员采用Clojure和Lisp时应该掌握的使用技巧。

InfoQ:你能解释一下FlightCaster,也就是其分析部件,都做些什么吗?

Flightcaster实时预测航班延误时间。其分析工作涉及到统计推断及机器学习技术的应用。关于航班延误预测的精确技术并不存在,即使其存在,我也没什么可说的。 :-)

InfoQ:你们的架构是什么?你们在Clojure群中发表的文章中,提到了Hadoop之上的一层Cloudera?它们是怎么组织在一起的?

Cloudera非常强大,为需要使用Hadoop开发大规模分布式处理的人们提供服务、Hadoop分发、部署脚本及AMI(Amazon Machine Instances)。我们使用Cloudera将Hadoop集群部署在EC2上,用于进行数据处理和分析工作,结点数介于10到100之间。我们发现 使用Cloudera分发可以减少把Hadoop部署在EC2上的复杂性。我们只有两个人从事研究方面的工作,因此采用Cloudera对我们帮助很大。

InfoQ:FlightCaster的哪一部分是用Clojure写的?

基础设施的另一个关键部件是Cascading;在Hadoop上非常棒的一层,其增加了附加抽象概念和功能。我们向那些正在用Hadoop进行大量数据处理和挖掘的人强烈推荐Casading。

我们所有的Clojure都是运行在Cascading上的。
该系统里有两个主要部分是用Clojure编写的。

一是把数据预处理并转换成适当视图用以分析的所有操作。包括过滤、多阶段分布式连接(destributed join)等等。把来自异质数据源的适当视图转变为非结构数据是非常复杂的。例如,我们不得不把时间序列视图构建到数据中,因为我们大量的分析需要考虑时 间因素。任何构建过这类系统的人都知道数据处理的工作量到底有多大,而Clojure + Cascading帮了大忙。

二是所有的统计推断和机器学习代码。如果该系统存在这一部分,我们将更深入介绍系统的这一部分。假定该系统存在这一部分,它应该能从Clojure优秀的 功能抽象、宏系统、丰富的不可变数据结构和序列处理类库、解构(destructuring)、组成复杂多阶段计算(中间可能出错)的单体抽象 (monadic abstractions)等诸多特性中获益良多。

InfoQ:你们用到了Clojure的并发和STM特性吗?

尽管这些特性很酷,但我们没有用Clojures构建并发特性。相反,我们利用了Clojures的另一个特性,务实的选择将其构建在JVM上。我们只是 把并行和分布式计算委托给Cascading + Hadoop,我们在这两者之上又加了一层,使用起来很友好,如果有时间,我们会将其开源。

InfoQ:你能简要介绍一下你们的Clojure代码是如何组织的吗?比如,如何使用命名空间、muti-methods(多重分派)、macros(宏)等等。

过往函数式编程的经验使我们能够将代码组织成非常“函数”的形式。我们使用命名空间的方式与在其它语言中使用命名空间的方式相同。我们尽量少用 macros和muti-methods,就算用也只是在适合的地方使用。人们对Lisp的所有印象就是其有大量的macros和meta-sauce。 尽管从某些方面来说这是对的,但是用FP基础构建块,你能走得更远;如lambdas、HOFs、currying、partial application等等。

我不能算是精通monad,但是我觉得mondads和multi-methods及macros都差不多。这些抽象概念不但功能强大,而且也很酷,吸引 了不少眼球。当这些抽象概念有助于简化开发时,我就会设法使用这些工具。但是这要求思维缜密,使用原始的函数编程方式及数据结构你也能做得很好。

最后谈一下Clojure中的monads,有些人认为monads是用于状态的,可是Clojure已经有了许多有效方法来处理状态,为什么还要用 monads。我们没有使用过state monad,但是用过许多其他很有用的monads。我很欣赏Brian Beckman对monads的描述:他们只是伪装的函数合成物而已。使用这一概念的最大好处是,能够安全构造出中间可能失败或碰到空值的多阶段计算。

虽然Destructuring bind看起来并不像macros和monads那样引人注目,但在实践中它实际上是一个非常强大的抽象概念。Rich选择从模式匹配中解耦 destructuring bind的方法非常聪明。我相信很快在Clojure里就会有ML风格的模式匹配,这一切正在实现中。

InfoQ:你提到过用于将数据格式输入到Clojure数据结构的Clojure reader:你在使用Reader macros吗?

Clojure没有reader macros,我们也压根不需要。要读写Clojure数据结构,我们只需使用print-dup语句即可,它可以让我们定义multimethods来 分派printers。只有在你需要读写没有内建的类型时,才真正需要实现Printer。例如,我们有一个针对joda-time日期的特殊 printer,那么我们也将以一种特殊的方式将他们读回。

InfoQ:你提到过编写Clojure数据结构——你是用其来序列化传输、存储或其它用途的数据吗?

我们将Clojure数据结构用作通信和存储的中间表示。例如,我们所有数据转换工作的输出都是Clojure数据结构形式,这种中间表示遍布于我们所有 的Hadoop工作中。这是我们置于Cascading和Haooop之上的那一层东西的关键,可以让我们免于处理Hadoop输入格式。

InfoQ:你们有什么想加到Clojure或Clojure生态系统中的东西么(类库、工具……)?

有人提议加个高质量的destructuring模式匹配工具,这个东西挺有用。但我对局部改进更感兴趣。我们没有用模式匹配,而且Clojure有许多很好的抽象概念,因而并不会缺失太多模式匹配,但是我认为它还是让很多地方的代码更加整洁了。

如果Rich开放该reader,我想一定很酷,或许这将帮助为模式匹配和monad实现创建良好的语法。其次,Clojure是我第一次使用Lisp,因此我并没有使用reader macros的经验,因此,在这方面我并不在行。

如果Rich不保留竖线也挺好,这样我们可以将它作为我们核心DSL的一部分,用来作为条件概率记号。 :-)

InfoQ:对于你所使用的Clojure类库,你有什么建议?

使用Clojure的第一个建议是:Clojure-core 和 Clojure-contrib都很小,因此最好通读全部代码。从中你将发现非常好的东西。留意所有神奇的数据结构及数据结构处理函数。例 如,Clojure有一个友好的Set及Set操作实现,以及一些准关系代数实现。

我把Clojure看作是一种面向函数编程的数据结构。

Clojure拥有一套神奇的数据结构。此外,所有这些数据结构都有书面陈述,因此reader和destructuring都很自然。所有这些结合在一起让人非常愉快。

传承自ML的函数语言中,函数是类型签名。而在Clojure中,函数是数据结构拓扑签名。

InfoQ:FlightCaster的Web前台是用Rails编写的,部署在Heroku上。为什么选择Rails和Heroku?

当我开始介入FlightCaster开发时,已经定下来用Heroku和Rails了。这一决定是有道理的:Ruby和Rails生态环境生产效率比较 高,并且为构建WebApp铺平了道路。Heroku和Rails对团队来说是很自然的选择,因为创始人中有两个具有Rails开发经验,Herkou的 创始人之一还是我们CEO的密友。:-) Flightcaster和Heroku共处一室,这太棒了!拥有这种内部联系有益无害。

InfoQ:你们是如何将Web UI与Clojure后台进行集成的?

Rails不只是Web前台,而且还是WebServer。我们使用Clojure来进行数据处理和机器学习研究。我们使用一种非常简单的策略来实现集成:我们让Clojure代码产生预告模型的json中间表示,然后把它推向Ruby端,以json格式来读取这些数据。


Clojure第一本书的作者——Stuart Halloway,最近发表了一篇文章介绍了使用Clojure的不同技巧。该文章提供了Clojure中的封装、多态等一些例子——那些拥有OOP背景的开发者会对此产生兴趣(这是类和继承之外的生活)。

要了解更多Clojure方面的信息,请参见InfoQ的interview with Rich Hickey,其中谈及了STM、并发性及multimethod。Rich关于Clojure的视频讲解提供了有关Clojure特性及其设计原则的更多详细内容。

查看英文原文:Clojure and Rails - the Secret Sauce Behind FlightCaster


感谢刘申对本文的审校。

给InfoQ中文站投稿或者参与内容翻译工作,请邮件至editors@cn.infoq.com。也欢迎大家加入到InfoQ中文站用户讨论组中与我们的编辑和其他读者朋友交流。

评价本文

专业度
风格

您好,朋友!

您需要 注册一个InfoQ账号 或者 才能进行评论。在您完成注册后还需要进行一些设置。

获得来自InfoQ的更多体验。

告诉我们您的想法

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

rails不是本文的介绍重点啊. by xiao deshi

就最后一句说了rails,看了应该就是使用ajax显示,并且对于如何显示,没有说到,遗憾.

这句话有道理 by 张 逸

这些抽象概念不但功能强大,而且也很酷,吸引 了不少眼球。当这些抽象概念有助于简化开发时,我就会设法使用这些工具。但是这要求思维缜密,使用原始的函数编程方式及数据结构你也能做得很好。

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

允许的HTML标签: a,b,br,blockquote,i,li,pre,u,ul,p

当有人回复此评论时请E-mail通知我

2 讨论

登陆InfoQ,与你最关心的话题互动。


找回密码....

Follow

关注你最喜爱的话题和作者

快速浏览网站内你所感兴趣话题的精选内容。

Like

内容自由定制

选择想要阅读的主题和喜爱的作者定制自己的新闻源。

Notifications

获取更新

设置通知机制以获取内容更新对您而言是否重要

BT