Dan Lucraft谈NoSQL DB在Rails中的使用与基于JRuby的编辑器RedCar的设计思路

个人简介 Dan Lucraft是Songkick的高级开发人员,在工作中他使用Ruby。他还创造了基于JRuby的可扩展编辑器RedCar http://redcareditor.com/。Dan的博客是http://danlucraft.com/blog/。

之前大获成功的Scotland on Rails Conference更名为Scottish Ruby Conference,继续由举办过2008、2009年活动的原班人马负责,只是有了个更精确的名字和一个令人激动的新会址:位于爱丁堡市中心的皇家医学院。

   

1. Dan,你是谁?

我是一个开发者;任职于伦敦的Songkick.com。我们是一家专注于近期演出列表的公司。我也是一个Ruby的狂热份子,这是为什么我会出席这个大会的原因——这就是我。

   

2. Songkick是做什么的?

正如我前面说的,我们专注于近期的演出列表,在我们的数据库中有超过11万近期的演出信息,我们从多个票务机构获取信息,所以如果我们的数据库里没有你想要去的演出,那是一个Bug。我们有超过140万个活动,可以追溯到60年代,如果你有一个装满演出票的鞋盒,想要和全世界分享的话,可以上 Songkick。这就是Songkick。

   

3. 你们是如何获取数据的?如何获得票务信息?

我们和很多票务机构都有合作关系。他们提供数据,我们将这些数据转换成你在Songkick.com上看到的漂亮的列表。如果你正在找一场演出,我们通常会提供多个选择,你能从多个不同票务机构买到票,价格都附在旁边。你能在页面上通过点击选择要从哪家买票。

   

4. Songkick使用的是什么技术?Ruby?

在Songkick我们只用Ruby。我觉得这是句实话。我们的网站使用多个不同版本的Rails,当然我们也用了大量的Gem。因为我们广泛地使用 Ruby,所以Songkick的每个人都是Ruby开发者,我们的网站使用Ruby、我们的API使用Ruby,后端的守护进程用Ruby来处理多种不同任务,我们还有用Ruby写的库来从所有站点获取数据。所有的系统管理工作都是用Ruby来完成的。这里简直就是Ruby的天下,我们也觉得它很管用。

   

5. 你们使用哪个库来从其他提供方获取数据?

我们专门写了个东西来做这件事。我们有一个抓取器的库来管理针对不同票务机构的抓取器集合,通过这个库可以监控抓取器,检查它们是否正常。

   

6. 你们目前使用哪个Ruby?1.8还是1.9?

我们现在用的是MRI 1.8.7。事实上我们正在使用Ruby Enterprise Edition,我们发现切换到这个版本还是很值得的。目前还没有升级到1.9的计划,但可以想象在不久的将来我们会做的。

   

7. 在Scottish Ruby Conference上,你做了一个关于你是如何使用Rails和数据库的演讲。那个演讲的内容是什么?

我和我的同事Matt Wynne在大会上做了一个演讲。演讲内容是在Rails中使用NoSQL,还有SQL数据库。我们讲的内容是关于如何从SQL迁移到NoSQL,因为如果有机会,这里的很多人会希望使用NoSQL数据库,但我们之中的大多数人可能是靠维护运行于MySQL之上的大型应用程序来赚钱的。对我们而言,要从头开始一个新的项目来使用NoSQL并不简单。如何才能在现有关系型解决方案中引入一个文档数据呢?既要有原则,又要注重实效。这就是这个演讲的主题。

我觉得使用NoSQL带来了很多好处。我想要解释一下不用从头开始也有可能使用NoSQL。在Songkick,我们在探索的过程中开发了一些库,我们的演讲就是在展示这些库,它们结合在一起就能实现这一目标。其中一个库是用来代替Rails内置的观察者的,它能让你实现异步观察者,运行于进程之外,但与此同时他又维持了Rails现有的工作方式。这对于一个习惯了Rails的人来说是种很能理解的使用异步观察者的解决方案。我们还没发布这个库,但在合适的时间,我们会将它开源。我们还实现了一个用来在MongoDB中保存数据的库。MongoDB是一个新的面向文档的数据库,和那些库一样,我们也在使用它。

我们的演讲中还涉及了在Rails应用程序中引入Presenter模式,这个模式在Rails社区中也倍受争议。我们也一直不太确定什么地方适合用 Presenter,但我们需要反规范化数据库,将网站和Rails项目所需的不同数据碎片集中到一起,Presenter的使用对我们来说真的非常有用,因为我们将其视为模型之上的第二层持久层,当网站有需要时,它能正确提供相应数据。

   

8. 你说异步观察者是在进程外运行的,是吗?

是的,这里有两种实现方式。 第一种,为每个想在系统中处理的任务实现一个特别的消息系统或消息格式,这种做法还不错。我们开始时使用这种方式,但后来我们发现用了异步观察者后,系统实际是把每个ActiveRecord事件(数据库记录的创建、更新或删除)都序列化成一个表示该操作的消息,并放进队列中。所有东西都是这么做的。我们把得到的东西称为大聚合(megafeed),它就像一个事件的消防水带,总有成千上万的事件进来。

我们可以监听这些事件,根据系统中的事件派发任务进行处理,不用担心在需要支持新消息类型或任务的时候要修改网站。我们经常发现自己需要写新的守护进程来处理一些事情,比如调整图像大小来为网站创建不同尺寸的缩略图。但实际上并不需要这么做,也无需对网站做任何修改,因为ActiveRecord事件的大聚合中包含了处理这些事情所需的所有信息。或者,在我们想要给新用户发送邮件时,只需监听大聚合里是否有新用户事件,有的话取得该事件,并从中获取信息,发送邮件。

这是个很好的抽象,因为它把所有我们想做的不同类型的事情都统一成了一类消息;而且它超出了我们的期望,因为我们想做的所有事都只是包含在一个ActiveRecord操作里的。

   

9. 那么这是一种事件总线?

是的,我们用的是RabbitMQ,所有消息都用它发送,这对我们而言是个很棒的解决方案。我们发现自己正越来越多地使用RabbitMQ。他们也在伦敦,我们有必要碰个头。

   

10. 你提到了MongoDB,它真有这么棒吗?

首先,它很快,当你把它作为缓存层的时候这一点尤为重要。其次,它还相当灵活,因为我们并不知道这个项目到底会往哪个方向发展,所以这一点真的很有用。你可以用Mongo来存储文档,把它当成Key/Value存储,可以对那些文档的内容进行索引,执行复杂查询,这意味着我们无需在一开始时就精确定义要做什么,这太有价值了。

我们目前把Mongo当作一个文档的Key/Value存储来用,但因为它还可以对文档进行查询,我们用它来保存HTML段和事物(例如列表形式的用户 ID)的索引,Mongo支持类似列表的原子操作的东西,这对我们也很有用。我认为Mongo真正的好处是它允许你在没有完全确定发展方向时保持灵活。在文档数据库领域中还有很多好的选择,如果有合适的,我们也会尝试另一种解决方案。

   

11. 你是如何选择MongoDB的,或者说在这么多选择中你为什么选了MongoDB?

正如我所说的,有很多好的候选对象。我对Redis更有兴趣一些,但此时此刻很难去说哪个就一定比其他的好很多。从某种意义上来说,我们在内部使用 Mongo已经有段时间了,因为我们都在尝试新数据库,它被用在一个管理应用程序上,我们已经在用了是选择它的一个重要原因。我们用它能保持灵活是另一个重要原因。从长远来看我们还未决定今后用哪个数据库,但Mongo正在为我们工作,而且做得很好,这对目前的我们而言已经足够了。

   

12. 让我们再来看看一些你的其他项目,你最近发布了一个剖析器——JRuby Prof,我想它是叫这个名字。

是的,那个东西我写地很开心。它还处在一个相当早期的阶段,还有需要改进和修正的地方。我认为在JRuby里,只要你想,还是有机会做出一些出色的剖析解决方案的,所以我期望更多地投入其中,尽早发布新版本。

   

13. 为什么说JRuby Prof比一般JVM剖析器好呢?

在写JRuby Prof前,我的一个项目需要剖析器,于是我试用了一些现有的产品。Ruby自带了一个纯Ruby的剖析器,它可以用,但要用于生产环境它还不够好。然后我又看了下Java世界的剖析器,我对Java了解的不多,所以对我而言这些都是全新的。Sun的Visual VM很不错,但在我要真正开始做剖析时却偶尔会让我的JVM发生段错误,因此我很快就放弃它了。Charles Nutter向我推荐了YourKit,比前者好一些,我也更喜欢它一些,那是个商业产品。

目前有很多商业产品,例如JXInsight,我都很想用,但对我而言它们都太贵了,特别是对一个纯粹是个人兴趣爱好的项目。介于纯Ruby的和完全基于 Java的两个剖析器之间,我想要找的是和我们在Ruby社区中使用的工具类似的东西,当时JRuby中还没有这样一个剖析器。把一个东西弄出来然后就甩手不管是很简单的,这就是为什么我说这是个新的项目,它还需要下很多功夫,但它能满足你的需要。它的成本很低,剖析你的方法树,构建一个调用图,这样就能清楚地知道代码中哪个部分耗时比较多,这就是我所要的,也希望它能对你有帮助。

   

14. 你使用什么技术来实现JRuby Prof?又是如何将它挂入运行时的呢?

JRuby支持Ruby事件,这和MRI的很相似,很可能在项目开始时它就支持了。写一个能挂入事件并进行监听的Java库非常容易。事件中涉及了方法调用、方法返回、异常,代码调用过程中发生的事情。它给了你足够的信息去构建包含方法和耗时的调用树。

   

15. 你的另一个JRuby项目叫RedCar。那是什么?

RedCar是个文本编辑器,我写了一段时间了。目前是用JRuby来实现的,从年初起它就跑在JRuby上了。自顶向下,它的大部分内容是用Ruby实现的,唯一由Java实现的是语法高亮,它要很快才行。实际上它是用Ruby写的,我想为Rubyist做一个很棒的编辑器,因为你能随时按下Tab键键入Ruby代码,RedCar能在内部执行这段代码。你能为RedCar实现新的Ruby命令,假设你想用你的文本在缓冲或别的东西中做点什么,你可以直接在里面实现命令,它立刻就能弹出在菜单里。

你甚至都无需重启编辑器。使用Ruby的动态特性来支持在内部修改编辑器真的很有趣。总的来说,我试着为Rubyist提供一个好的解决方案,因为我们都希望能从头到底修改所有东西。RedCar中的所有东西都以插件的方式实现,所有插件都用了相同的 API,和其他东西一样。编辑器里没有你不能修改的隐藏核心。如果打开代码,如果在RedCar中打开一个REPL,你能修改它的任意部分。

这也造成了一些问题,因为在Ruby里你无法阻止任何人做任何事。我们要非常小心,保证我们的API足以支持人们想做的各种事,但这些项目真的让我很兴奋,我希望本次大会能带来更多用户。

   

16. 你使用什么GUI库来构建RedCar?

我们用了SWT,这是开发Eclipse项目用的GUI库,它很棒,在所有的三个平台上都使用了本地组件。实际上我相信它在Motif上也能跑得很好,如果你喜欢的话。它真的很棒,工作的很好,使用过程中我们没有碰到一点问题。

   

17. 你用的是基本SWT,还是OSGI库,或是别的什么?

我们在主程序中使用基本SWT,但在此之上还用了一些JFace类,它们提供了一些方便的东西,这很有用,因为我们目前还没有诸如Eclipse中的撤销管理器之类的东西,我们主要用的就是它。我希望很快能用纯Ruby的版本替换它。我们的剪贴板就是这么做的,起初用JFace的剪贴板,当发现纯Ruby 的版本时就切换过去了。

   

18. 在RedCar里有一些TextMate集成,那是真的吗?

是的。TextMate是一个非常棒的编辑器,实际上我开始做RedCar的最大原因是我想在Linux上有一个类似TextMate的东西。我不清楚你对TextMate有多熟悉,但其中大多数的主题和语法定义都包含在一个开源包集合里。这对TextMate很有好处,因为这意味着谁都能编辑那些东西,以此种方式改进编辑器,这一点非常好。

TextMate的作者Allan Odgaard足以支持使用了那些包的项目,没有它们,RedCar可能就不存在了。所以我要对Allan大声说句“谢谢”,谢谢你开源了那些东西,这对我们来说真是太好了。RedCar支持和TextMate一样的主题、代码片段和语法定义。

   

19. RedCar是单一Ruby文件的编辑器,还是里面有项目的概念?

我们有项目的概念,它并不完整。RedCar还很新,还有很多东西需要实现,正如我所说的,希望本次大会能带来一些贡献者。本项目目前还相当简单,但足以让我在工作和家中全部使用它了,这对我来说是最重要的。我们已经开始有更多项目支持了,有人提供了GitHub项目浏览器,我们很喜欢它;有人提供了 RedCar的ctag集成,我等不及要用它了。我们在RedCar里也能有ctag支持。

   

20. 基本上,这是用于代码浏览的。

我想Emacs用户应该更熟悉ctag,它是从方法和类的使用处跳转至其定义处的一种途径。到处都在使用它,而且它的跨平台性也很好。

   

21. 可以用JRuby代码来写RedCar扩展,也可以用HTML和JavaScript来写扩展。这是怎么做到的?

我不喜欢编辑器或IDE里有又大又复杂的对话框。在RedCar中用来代替它们的是HTML视图,HTML标签页。RedCar吸引人的地方中很大一部分是你能用自己已经会的语言来写扩展。要学一门GUI API,哪怕是和SWT一样优秀的,对大多数人来说都没什么吸引力。我想要这样一种能力,用我已经掌握的技术,例如HTML、CSS和 JavaScript,来编写RedCar的插件;这正是我们在这些Web标签页里所尝试的。它们允许你使用JavaScript,随后RedCar运行时会回调Ruby,这都是透明的。

你写了一个控制器,其中有些Ruby方法,RedCar会把它们变成JavaScript,让你从JavaScript中调用那些方法。这让我们有希望用 HTML表单、JavaScript替换大多数复杂的对话框。这有点像Ajax,你无需重新加载页面或做类似的事,它能立刻生效。我希望人们可以用他们现有的技术来编写RedCar插件,就像这样。

   

22. 你正在使用SWT HTML组件,并将Ruby API和Java API发布出来,是吗?

是的。缺少了SWT的支持,我们做不到这些,SWT太棒了。SWT允许你将JavaScript方法绑定到Java方法上,而JRuby和Java集成得如此紧密,很容易就能把JavaScript绑定到Java上,而这个Java方法又绑定了JRuby。把这些全串联起来,所有这些库结合在一起让一切成为可能,这给我留下了深刻的印象,虽然我有些吃惊,但这很不错。

   

23. 在HTML视图中,只能写一般的JavaScript代码,还是你自带了什么JavaScript框架?

插件的作者可以使用他们喜欢的任何东西。我还没决定辅助工具中是否要自带默认框架,目前你可以使用你想用的各种东西。

   

24. 为什么你建议使用这些HTML视图而不是构建自己的小SWT窗口或组件?

基本是因为我个人认为它们会更好用一些。人们已经拥有HTML、JavaScript和CSS的技能了,能立刻用它们来改善自己的编辑器,写一些新命令和新插件。学习一个GUI系统并不是个大的障碍,对于更复杂的事情或更紧密的集成,仍然需要使用它;但你在标准IDE中做的很多事,例如某些实例的搜索结果,可以用HTML来展现。

也许是首选项面板、插件管理器或调试器——有很多事可以用这种方法来做。这是为了让RedCar的用户能方便地扩展它,这才是最主要的原因。

   

25. 听众们可以从哪里找到RedCar和JRuby Prof?

可以在GemCutter找到JRuby Prof的Gem。“sudo gem install jrubyprof”,这就可以了。需要把它安装成一个JRuby的Gem。RedCar也能通过Gem的方式来获得,尽管它运行在JRuby上,但你只需要安装任意的Ruby或RubyGems,它会自己下载所有启动所需的JRuby jar文件。你只需执行“sudo gem install redcar”。

   

26. 我们稍后会去看的,Dan Lucraft谢谢你。

谢谢。

你可能感兴趣的:(Dan Lucraft谈NoSQL DB在Rails中的使用与基于JRuby的编辑器RedCar的设计思路)