0
0

Quora使用到的技术

陈皓 发表于 2011年07月04日 08:35 | Hits: 3929
Tag: 技术新闻 | 杂项资源 | Facebook | MySQL | Nginx | Python | Quora | StackExchange

以前向大家介绍过Stack Exchange的系统架构Facebook的系统架构,今天和大家说说Quora的。本文主要参考了Phil Whelan的这篇文章《Quora’s Technology Examined》。关于Quora是个什么网站我就不多说了,国内对他的C2C网站叫“知乎”。呵呵。我们还是来看看Quora的技术吧。

Search-Box

Quora只能搜索问题,主题标签,用户名,和主题标题。没有全文搜索,所以,你无法搜索问题和答案的内容。而搜索中使用前缀搜索方式,比如你输入mi,则Microsoft会马上出来。其搜索还会有一些非常简单的模糊匹配的算法。另外,如果有重复的问题,其中一个问题会自动跳转到另一个问题,但是在搜索中还是会出现。搜索中没有拼写检查。

一开始,他们使用的是一个开源的搜索服务器,叫Sphinx。其支持上述的那些功能。现在他们不用这个技术了,因为受到了一些限制。他们做了一个比较新的解决方案,这个算法由Python实现。

参看What libraries does Quora use for search?

实时查询

Quora的查询是非常高速的,其查询请求是通过AJAX的GET请求发送的,结果返回用的是JSON数据格式,但他们解析JSON是在服务器端,而不是通过浏览器的javascript。这么做的原因可能是他们想高亮搜索关键词,似乎使用Client端的Javascript非常不好做。

Quora的即时搜索好像比较暴力,如果你输入Microsoft(一共9个字符),你会看到其会像后端发送9次查询——每按一个键一次,无论你敲这个单词的速底有多快,每输入一个字符都会发一个请求给后台。对于这样的看上去没有效率的对后台的请求,后台的服务器端会来控制相关的前台请求,所以,就算是前台这样做,也不会增加服务器端的负载,因为后台会做相关的处理。

Quora的搜索使用HTTP长连接,当你开始敲查询的时候,连接就建立了,这个连接会持续在那里,你下次搜索的时候会继续使用这个连接,除非你60秒没有动作了。

参看Is Quora going to implement full-text search?

Webnode2 和 LiveNode

Webnode2 和 LiveNode 是 Quora 内部的系统,其用来管理内容。Webnode2  生成 HTML, CSS 和 JavaScript 并且和 LiveNode 紧紧地耦合在一起,Webnode2主要是用来管理内容在网页上显示的,LiveNode主要是用来做动态网页内容更新的。Charlie Cheever 说,如果他可以从新开始,他 第一件事要做的就是重写整个LiveNode.

Quora的工程师看上去对他们搞的这些东西非常的满意,并且 他们也在努力地找到这些东西的弱点。有一个有意思的关于LiveNode的问题是,如果A和B同时正在看相当的一个问题,那么用户A的一些交互动作会影响B的页面。例如,如果A顶了一下某个答案,那么这个答案可能会往上移动。这样的一个显示变化会通过AJAX更新B的浏览器。如果B此时展开了评论,可能会受到影响。

LiveNode 由这些东西写成:Python, C++, and JavaScript. jQueryCython也用到了。

因为Quora 想要对他们的LiveNode开源并准备把他们的代码分开,做这个事可能需要太多的工作和时间。

Charlie Cheever 指出 WebNode2 和 有一个叫做 “free and easy website builder” 的 Webnode 的 webnode.com没有任何的关系。

参考Tech Talk – Webnode2 and LiveNode

Amazon Web Service

Quora全部host在AWS的EC2和S3上,这对于这些刚刚起步的快速发展的公司非常关键,因为你可以省去了很多硬件和维护的成本。(建一个数据中心并不是所有公司都能干的事)。Quora的操作系统使用Ubuntu Linux,这是非常容易部署和管理。

其静态页使用了Amazon的CDN的 Cloudfront服务分发,CloudFront用于所有的静态图片, CSS 和JavaScript。图片先传到 EC2 服务器,使用Pyhon S3 API处理后后传到 S3。

HAProxy Load-Balancing

HAProxy作为前端负载均衡服务器,反向代理服务器是 Nginx,Nginx 后面则是 Pylons (Pylons + Paste) , 承担动态 Web 请求。

Pylons,是一个轻量级的Web框架,通常都是在Nginx后面使用。选用Pylons就像你在春节先饺子当主食一样。他们把Pylons中的template和ORM取走而使用自己的技术(由Python写成),这个地方就是 LiveNode 和 WebNode2的地方

Python

从facebook出来的Charlie 和 Adam选用了Python而不是PHP。正如Adam指出的——“Facebook is stuck on that for legacy reasons, not because it is the best choice right now”(Facebook使用PHP并不是因为其好,而是因为历史原因的问题),当然他们也不会使用C#,因为那样一来就会引入一堆微软的东西。当然,也不会是Java,因为Python要比Java更容易写出代码,Scala太年轻了,还需要考验。Ruby看上来很像Python,但是他们对Ruby没有过多的经验。最终还是Python胜出。当然,他们知道Python的弱点是性能和速度,所以,他们在需要速度和性能的地方使用了C/C++。 他们使用Python的版本是2.6。

使用Python的另一个原因是Python的数据结构和JSON可以很好的映射起来。代码易读性很高。而且有很多的库,调试器和重载器。Quora的B/S结构几乎完全通过JSON进行数据交互。

他们没有使用IDE,他们使用得最多的是Emacs,一看就知道这是一个个人的选择,随着他们开发团队的扩大,这个事会得到改变的。

另外,他们提到了PyPy,一个让 Python更快更灵活的项目。

Thrift

Thrift用于后端服务器间的通讯。Thrift  服务由 C++开发。Facebook同样使用了这个技术

参考Why would you write a Thrift service in C++?

Tornado

Tornadoweb 框架用于实时更新,其运行在Comet 服务器上,其用来处理大量的需要长时间poll和push更新的网络连接。

Long Polling (Comet)

Quora的网页并不是简单的显示,每一个页面都需要更新,或是创建问题,答案和评论。所以,他们使用了Long Polling而不是传统的Polling,传统的Polling需要浏览器一端不停地重复地向服务器询问——“有更新吗?”,服务器说没有,于是过一会浏览大再问,现在呢?服务器说,还是没有,浏览器过一会又问,现在呢?服务器说,还没好。这样一来,就好像让我们的客户端放到了驾驶室里,这显然是有问题的,因为只有服务器知道什么时候会有更新。而且浏览器这么干,很快会让服务器的负载加上去。

Long polling 也就是我们熟知的 Comet,其让服务器来控制这些事,让客服端等在那里听服务器的响应。在client和 server的会话对于两者是是相同的,而不是client需要等着然后向服务器查询。服务器端可以把一个连接打开很长时间(比如:60秒),在这段时间里,服务器会查看是否有相应的东西需要更新,如果有的话,就发给浏览器。如果没有的话,就等下一次的client询问。可见,这种服务器等一会再响应的方法可以让浏览器少发几次查询。

对于long-polling 的最好的地方是,可以降低浏览器和客户端间来来回回的次数。让服务器端来控制时间,所以,内容更新可能会只是几个毫秒,或是几十秒。 服务器端也可以积攒一堆更新后,一次发给浏览器。这样做会更有效率。

但是,这个方法的黑暗面是——这会让服务器端出现大量的TCP链接,想一想,Quora也是百万级用户的应用了,只需要10%的在线用户,你就需要一个可以处理10万并发量的架构。注意,如果一个用户在其浏览器里打开了多个Quora网页的话,那么,这个链接器会是非常致命的。

当然,好的消息是已经有一些技术专门为Long Polling设计,这些技术可以让你在那些等待的连接中只会消耗非常非常少的内存(因为那些等待连接并不需要所有的资源)。例如:Nginx 是一个单线程的事件驱动的小型服务器,每一个链接只花非常小的内存。每一个Nginx的进程只会在一个时候处理一个连接。这意味着其很容易扩展成一个可以处理成千上的并发量的服务架构。

参考How do you push messages back to a web-browser client through AJAX? Is there any way to do this without having the client constantly polling the server for updates?

MySQL

就像Adam D’Angelo 的老东家facebook一样,,Quora重度使用MySQL。对于,把数据库里的数据分区是最需要做的事。他们的行事原则是,尽可能的把数据放在一台机器上,使用hash主键把大规模的数据存放到多个数据库中。坚决不用表连接。Adam参考了FriendFeed的一篇文章How FriendFeed uses MySQL to store schema-less data并说你不应该在你的社区还没有100万用户的时候使用NoSQL 数据库。

并不只是Quora和FriendFeed使用MySQL,Google,Twitter,Facebook都在使用MySQL.

参考:How does one evaluate if a database is efficient enough to not crash as it’s put under increasing load?

Memcached

Memcached用于 MySQL的前端缓存。

Git

Git是他们的源码版本控制工具.

JavaScript Placement

如果你看一下Quora的网页源码,你会看到其JavaScript总是在页面的最后。 Charlie Cheever建议这会让你的页面显得载入得很快,因为其先显示内容,然后在载入Javascript。

Charlie Cheever 遵从 “14 Rules for Faster-Loading Web Sites”

Steve Souders,  High Performance Web Sites 和 Even Faster Web Sites的作者,其列了一些 rules让你网页更快的原则。 Charlie Cheever 的 Quora 创始人提到这些过,这应该也是Quora的速度的原因。

“One resource we used as a guide is Steve Souders’ list of rules for high performance websites:http://stevesouders.com/hpws/rules.php
– Charlie Cheever, Quora

Steve Souders的14条规则是——
 
  • Make Fewer HTTP Requests
  • Use a Content Delivery Network
  • Add an Expires Header
  • Gzip Components
  • Put Stylesheets at the Top
  • Put Scripts at the Bottom
  • Avoid CSS Expressions
  • Make JavaScript and CSS External
  • Reduce DNS Lookups
  • Minify JavaScript
  • Avoid Redirects
  • Remove Duplicate Scripts
  • Configure ETags
  • Make AJAX Cacheable

(全文完)

相关文章

原文链接: http://coolshell.cn/articles/4939.html

0     0

我要给这篇文章打分:

可以不填写评论, 而只是打分. 如果发表评论, 你可以给的分值是-5到+5, 否则, 你只能评-1, +1两种分数. 你的评论可能需要审核.

评价列表(0)