主题:QCon北京2012大会

4月20日

主持人:大家早上好。今天是QCon的第三天了。接下来介绍今天上午的几个主题演讲。由于一些原因,今天上午第一位演讲人Khawaja Shams不能来到我们的现场,他录了一小段视频给大家。在很多软件开发人员心目中,昨天Bryan Cantrill算一个神奇的人物,今天的产品工程师是Mike lee,他是世界上让人最头疼的程序员,这两天跟他交流下来,他还是一个很随和的人,他演讲完之后,大家有什么问题可以跟他交流。他今天上午第一个演讲题目是如何开发靠谱的应用。Mike lee本身有8年的移动开发应用经验,他还做的08年奥巴马的竞选应用,还做的苹果应用商店。这种应用既能够做到本地化,又能够及时响应,同时在影响范围上又是整个国家范围的。应用能够做到这种层面,Mike lee一定有很多经验可以分享给大家。
    第二个演讲是Robert Johnson带来的扩展社交计算,他曾经在Facebook担任一个工程总监的职务,在他的带领下,整个Facebook的网站规模扩展了100倍,而且用户超过8亿。Facebook存储了超过2600亿张图片,数据量大小超过20P,用户每周上传超过10亿张。Facebook每秒钟提供的图片响应超过100万张,这是2010年的数据。
    第三个演讲是Mike lee带来的从创意到盈利产品成功背后的奥秘。你在商业方面有哪些考虑,还有考虑如何研究客户,研究市场,研究平台。这些都会在Mike lee的演讲里面有一个相关的分享,毕竟这个演讲是他这么多成功产品实践经验的一个结晶。听了这个演讲之后,很多人会觉得移动互联网成功创业没有那么容易。接下来有请几个环节的主持人,首先有请大众点评网的资深架构王宏,一个鸡蛋的爆走,王宏也是几支队伍的后勤大队长。
    王宏:大家好。今天下午有四个演讲,第一个是由我主讲的,为什么要迁移?怎么迁移以及迁移中遇到的问题,我们怎么解决的。之后是由Facebook工程总监Robert Johnson讲扩展中的数据库,讲Facebook框架中的一些数据库。之后是由国内一个知名网站豆瓣网的洪强宁讲合久必分、分久必合,一个很有意思的演变过程。最后是人人网带来的人人网缓存系统架构的发展和演进,演讲人是人人网的张铁安,从以前的系统碰到的问题,到现在缓存系统整个的演变过程,是一个子系统的演变过程。
    主持人:接下来有请新浪云计算首席架构师丛磊。
    丛磊:大家好。下午会有一个关于云计算主题的介绍,现在说云计算,大家以为它在忽悠,其实并不然。将来越来越多的小企业一直发展到中型企业、大型企业,他们将来都会构建在云计算的平台上。我想说在座的大多数人都属于IT部门,要么就是运维部门,所以云计算跟所有的部门相关,这是未来软件发展的一个趋势。第一个是由我自己分享关于新浪App Engine的安全实践,这些系统为什么相信SAE上?这是一个具有挑战的话题。下午我会给大家讲解SAE的挑战策略。接下来由盛大云技术委员会主席杜海介绍基于云的架构—云计算时代的ABC。这些具体产品在架构当中的一个应用。第三位是eBay的沈晋,做Teradata云计算在ebay的实现。最后一个是淘宝的技术专家彭渊,向大家介绍淘宝分布式并行计算四合一五框架Fourinone,大家如果对这四个话题有兴趣的话,可以关注今天下午的演讲。
    主持人:下面有请海豚浏览器创始人刘铁锋。
    刘铁锋:为什么今天下午探讨企业移动开发?如果2009年是衍生的做互联网,我们2009年是刚刚开始,对于2009年、2010年,对于2011年来说,我认为是做互联网公司开始进入移动互联网,比如说QQ、百度或者是大型的互联网公司开始做。2012年,我们来看做企业应用的会不会开始进入移动开发应用市场。今天下午会探讨这个方面的议题。今天下午第一个议题是由我主讲的,我会详细对比一下由我知道和见过开发案例以及主要的解决方案。第二场是来自上海电信研究院的赵勇介绍移动开放平台分析。如果大家听完这个演讲可能会知道在移动互联网时代,开放平台不仅仅是互联网公司的架构工作,作为运营商也开始思索怎么把他们的计算能力给移动平台做开放,大家会听到电信这边的分享,不仅仅是开放他们的计算能力,甚至还会开放短信通道和相应的计费通道,这对于做移动开发的人来说是一个好消息,你借助运营商的渠道来分享你的程序。第三个演讲会比较偏,来自于东软的孙广宇,他分享的是基于HTML5技术构架企业级跨平台智能设备解决方案,他会讲到我们多个屏幕整合的时候,在跨屏幕的时候如何做同步,如何做相应的交互,在这个演讲里面还是比较有前瞻性的,并且非常具有互动性的一个演讲。最后一个演讲讲的是在电子商务企业如何往移动化的迁移。演讲者是白天,他是一个创业者,之前在微软工作,工作几年之后进入移动互联网创业领域。我相信大家额会听到很多一线的数据,为什么电子商务这个领域开始很火?然后有多大的空间可以做?实际上它属于一个非常大的垂直领域。在这里面大家不仅仅学到了技术解决方案,可能还进入到一个新的垂直领域。
    主持人:第四位主持人是百度的高级架构师路宁。
    路宁:今天下午有一个体关于看板和经济开发的,它不像前面的主题广为人知,但是在很多公司有了非常成功的经用案例,看板本身是一个持续改进的方法,它有自己的工具、原则和实践。看板本身也属于经济开发当中的一个重要方法。精益开发和敏捷是一个路子,其中有很多比较极端的技术想法和实践,包括一些管理,还有需求上的一些做法,所以今天下午这个主题就是把这个方面的内容带给大家。王晓明老师是独立咨询师,他在敏捷和经济这个圈子里面非常有影响力。他也是腾讯首位的外部咨询师,他今天下午会跟我们分享从1万到150万,这是他们一个游戏的产品,从开始到有了非常好的这种成绩的这样一个过程。这个项目也是跌宕起伏,他会详细介绍在这个项目中如何运用精益的原则做一些改进,提高产品在市场上的影响。第二位是陈斌老师,他在汤森路透管理一个团队,这个团队在做工程师的过程改进、研发效率提升这方面的工作。看板在汤森路透已经有很长时间的应用了,他们是一套非常系统的做法,其中的一些总结也值得很多公司借鉴。第三位是ThoughtWorks首席咨询师熊子川,从Lean Startup看持续交付。我每次跟他接触,或者是听他的演讲,都感觉特别清新,小清新。不光是因为他的形象,主要是因为他关注的领域比较靠前。我们平时会关注一些技术、管理需求方面,他关注更多的是业务,更多的是用户体验。所以我每次跟他交流都会有这种茅塞顿开的感觉,他本人在手绘能力方面非常强,每次看他的PPT都是一种享受,非常值得大家去欣赏。这种创业的模式,可能跟很多传统的创业模式不一样,之前也有很多这方面的公司做一些分享,可以在没有实际应用的情况下把想法放出去,看市场的反应。在传统的公司,熊子川给大家介绍的这个项目是一个非常传统的项目,大家会感觉这么极端的做法怎么在传统的项目中应用,他会讲。最后我给大家带来精益开发的最佳实践,包括技术方面的,包括管理方面的,包括做法和工具,这些工具带有精益的特色,在很多敏捷团队也会有这种引入。谢谢大家。
    主持人:今天本来预计第一个主题演讲是Khawaja Shams,他由于工作原因来不了,他录制了一段视频,可以给大家放一下,大家可以听一下。
    Khawaja Shams:我非常高兴到北京来参加今天的QCon大会。我是来美国宇航局推进技术实验室,行动规划软件实验室的成员。但是我不能来这里,所以不好意思。可以看到我们现在正在做这个项目,我们会把这个小车放到火星上,这个小东西的登录是8月6号,是星期天的时间,我们会把这样一个小车放到火星的表面上。这个小车也是跋涉千山万水,最终到了这个上面,它只是需要太阳能电池,同时它利用了非常好的技术,它也是充分利用亚马逊云服务的机构,同时加上我们自己的架构,5分钟时间内可以处理5G的图象数据。同时把亚马逊的云服务器进行了更好的放大。我们希望这个小车在火星登录的时候能够尽快把这些数据实时与我们全球的科学家进行共享,希望大家能够喜欢今天的大会。希望大家能够学到更多的东西。再次感谢QCon北京。
    主持人:下面用热烈掌声欢迎Mike lee给我们带来今天上午第一个主题演讲。
    Mike lee:今天上午跟大家探讨的话题是做靠谱的应用软件。有一次我在喝咖啡,旁边坐着一个男士,他从兜里面掏出了两个这样的唱盘,还有一对音箱,还有一些唱片,他开始在我跟前做起了DJ,大家觉得这是不可能的事,但是我们今天生活的世界就是这样的,就是由应用软件形成的世界。
    这些应用软件来自何处?这种奇迹出自谁之手?应用软件来自工匠,他们不仅仅是技术的工匠,他们这些工匠愿意来把自己的工艺跟其他的工匠进行分享、交流。在几年前,我在一个加利福尼亚的一个小公司服务,我离开了我的职位,为的是去世界上做更多的探险,我想环球全世界。我想不光去大家都去的地方,我也想去一些地方是谁也不去的地方。我不仅想去大都市,也想去小城镇。像这个地方叫USHUAIA,它是世界上最南部的一个城市,在南美的顶端,他们自称为是世界之端。
    我想了解伟大的事物是如何产生的,不光是西方的创举,还有东方的创举,也不光是第一世界的,我想获得一个新的视野,我想了解同样的问题大家用什么不同的方式去解决的。不光是第一世界的解决方案,也要看一看第三世界的解决方案。
    在我探险的过程当中,我做很多旅游,我也做了很多演讲,我的这个演讲其实应该换一个题目,叫如何创造伟大的东西。因为如何制造不靠谱的软件,听上去有点负面消极,甚至翻起来有点费劲。其实我谈的内容是如何做好的软件,因此我换一个标题,叫如何制造伟大的东西。但是问题是所有的人都以为自己制作的东西了不起,但是关键是如果你做很差的东西的时候,做很不靠谱的东西,一开始你以为你会做一个伟大的东西,你假设你能够做出伟大的东西来,这个时候你会纳闷,为什么你不富有?为什么你没有在挣钱?但是这种思维是不灵的。我有一种不同的行事方式,我相信做伟大的东西,你应该先假设你做的东西不怎么样,你要先假设你的东西是不靠谱的,然后你会考虑如何让这个不靠谱的东西更好一些,这样的话你做出来的东西就会更好一些。
    要做事先做人,我想中国也有一个类似的说法。要想做伟大的东西,你先要做一个伟大的人才可以。大家知道,作为工程师,我经历过很多的问题、难题,也经历过很多的解决方案,我可以告诉你们,我发现的每一个解决方案,我要是讲给你们听的话,也不见得能够帮助你们,因为你们的问题跟我不一样,如果你们发现自己的解决方案,你们需要工程学,不光是规则,工程是一种看待世界的一种世界观,你必须要从整个世界里面获得灵感,如果你想学习,做一点不那么离谱的东西的话,不想做一些很可怕的东西出来的话,你一开始作为起步,你要把软件看成是一种经历体验,那么这是客户的体验,软件能够给客户带来体验,要理解生活就是这样的,生活是整个一系列的体验。你需要做的是从体验当中学习。
    当你经历任何事物的时候,有时候是坏的事物,你感到很不愉快,你不高兴,你有点不安,你要注意,你要注意当不好的事情停止的时候,你要想一想为什么发生这么糟糕的事情,为什么我不高兴?如何能够让它做的好一点?如何使得这个体验能够变得一种好的体验?反过来说也一样,如果你有一些好的体验,你要考虑为什么这是好的体验?为什么我那么高兴?出什么错会让它变成一个糟糕的体验呢?
    有时候你需要去提取一些潜在的真理,然后把这种真理应用在其他的体验当中,给大家举一个例子。有一个案例,我把它称为赶紧还是等待。在美国我住的地方,我们有这种键盘器,你去买东西的时候,你可以用键盘器来刷卡付费,当收银员在计算的时候,你就可以付钱了,但是有时候需要等待,因为它们的体系系统不一样,我不希望他们算清帐才能刷卡。我不喜欢我在工作的时候,他在等,他在工作的时候,我在等待,我不喜欢等待,你们喜欢排队等待吗?你们不喜欢排队等待。但是有时候我们老让我们的用户等待,经常看到软件会发跳出这样一个窗口,意思就是你等待吧,正在发送,这是很讨厌的,我不喜欢,你的用户也不喜欢等待。那么这就是离谱的东西,这个就是不好的东西。
    我在旅行的时候,我到了阿根廷,我住的酒店里面,我想洗澡,结果热水器不灵了,这个热水器的按键是这样的,看着很简单,看上去很合逻辑,你把电源打开,你按一下这个按键,然后你把火条到正确的位置就好了,如果真是这样的话就好了,但是实际上并不是这样的。实际上按键是这样操作的。首先把按纽转到这个位置,然后把它往里推,然后按这个红的按键,然后这个按纽要按一段时间,等待一段时间,然后再转到5的位置,然后再把它拉出来。这个按键一点作用也不起,完全是没有用的,只是一个装饰。非常让人糊涂。我那天只好洗了冷水澡。我从中学到了什么东西呢?一个好的用户界面和一个好的用户体验之间是有不同的。界面是一种承诺,可能能够给你带来好的体验,好的体验是结果。
    大家知道,取决于成败的是细节。这是一个车牌,他把它颠倒了,S应该是朝向另外一个方向,有时候我买书,比如说电子书是这样的,不管它内容怎么样,实际上你看看表面,大家就不想读了,这是一个不可读的一个读物,经常这种小的错误,也是非常愚蠢的,让你觉得你是个业余人士,但是这个并不是世界末日,小的错误会带来很大的恶果。刚才我们看到机器人叫火星登录人,我有一个朋友也是做类似工作的,他是一个软件的工程师,这是一个报纸上的文章他剪下来了,由于软件错误,使得火箭发射延迟了,那么延迟了一天,一天好象不长,但是因为是火箭发射,所以一天付出的成本很大,如果小错误使你的公司上了报纸,这就是一个很大的错误了。
    当然大家都不记得是他犯的错误了,因为还有他的一个同事犯的错误使得火箭爆炸了,而且还有一个火箭是根本没有到达火星,花了几亿美元全付之东流了。为什么?这种小的错误,人们还在嘲笑,小的错误可能会多来极大的后果。这是一个医疗设备,这是一个放射疗法的机器,如果你有肿瘤的话,他们就会用射线来杀死你的肿瘤,但是必须要控制的很好,这样才能挽救你的生命。由于一个软件的错误,有时候放疗机会用巨大的射线把一个病人整死,就是由于软件小小的错误人就会死掉。小小的错误会带来极大的恶果。
    但是知道人类心智是这样的,以扑克牌在为例,你看到不这张牌是什么。我以为这是大王,但是上面只是一个小丑,大家知道对自己的错误是看不到,你周围的人能够看得很清楚,他们看不到他们自己的错误,但是你能够看到他们的错误,你的错误对他们来说很显然,就像他们的错误对你来说很显然一样。
    如果你想避免犯荒谬错误,你要依赖其他的人给你反馈,你要依赖其他的人看到你在犯的错误。反过来,你要指出别人错误的时候,你要友好一点,你不要说你犯了这么恶心的错误,因为你的错误比他的错误还要两倍的恶心,可是你不知道。有时候我们会让用途糊涂,这是伦敦塔,我知道我需要买一张票,我说OK,非常简单,这是箭头,箭头是指向右边,我也看到这边有个小亭子,我也许应该到这边来买票。不,结果发现我把这个标识看错了,实际上箭头是指在左边。
    大家不需要读这个东西,这个语言很糟糕的,多少次读到这种混乱的东西,很多文本就是这样的一大堆乱乱的文字塞一起,我来读一下,这是很好玩的文字。落地的飞行员是非操作的飞行员,直到决定高度的呼叫,当处处理非下降的飞行员开始处理,由于最近造成了对规则的误读,所以我们要重新把这个规则改写。这种事为什么会发生?由于我们对自己的领域不熟悉,你们开发软件的话,你们是自己软件产品的最好的专家,你要记住,你的用户不可能像你一样了解你自己开发的软件,你拥有所有关于软件的知识,这不光是编码,这不光是我们所从事的工作我们还有另外一半,另外一半叫设计。
    设计有时候能够化腐朽为神奇,化平庸为非凡。我见过一本书,这本书封面不怎么样,好象这个作者不愿意花钱让别人设计封面,也许他只是请了他的侄子来帮他做。我们说不要靠封面来判断一本书的内容,但是每个人都喜欢这么做,每个人都喜欢通过封面来判断一本书的好坏。我一开始打交道的软件,我们聘请了一个设计师,把它变成这个样子,它实际上是软件当中最成功的一款软件,他赚了数百万美金的利润。为什么会这样呢?他们之间有什么不同?关键在于设计。设计是最便宜的一种能赚钱的方式。
    大家不要以为走了一半就以为自己做完了全部的征途,这是一个干燥机。大家知道原来的厕所里面有纸巾,也有烘手机,纸巾虽然好,但是对环境会造成破坏,所以烘手机越来越流行。但是目前烘手机不怎么样。这一款烘手机,看上去是外空间来的东西,但是有问题,当你烘了一半的时候,烘手机停了,手还没有干就停了。我研究了一下,我发现有两个小小的激光感应器,把手放进去的时候,感应器就会从你的手指之间通过,然后它会关闭机器,由于这样小小的错误,就使得这个机器没有用了。如果把手烘干不了,它看上去漂亮有什么用?
    有时候当你解决第一个问题的时候,你会发现第二个问题的存在。其实最显然的解决方案往往是错误的,或者是不够的解决方案。乔布斯说过,当你要解决问题的话,你会先找到一个很漂亮的解决方案,但是不是最有效的,你发现这个方案有效,但是却不漂亮。你必须回来寻找另外一个解决方案,既漂亮又有效。我们有一个说法,今天把货发出去,明天就得去修。好比我上这个舞台穿着裤衩,如果大家有抱怨的话,我明天换一条长裤。不能这么做,要发送3.0,不要一做完就发送,而是做完以后重新做测试,做一点修改,再次修改,只有在这个时候,你才能发送,彻底准备好了再发送。
    我给大家举一个小小的例子,这个例子也是在伦敦塔的。大家知道现在Iphone软件很流行。我是一个游客,是参观伦敦塔的,我的手机上并没有数据,也没有数据线,我怎么可能下载这个软件呢?你做这个广告有什么用?他们考虑到了,他们有一个wifi,他们预测到了我的问题,在我想到这个问题之前,他们先我一步。如果在服务客户方面能够先他们一步的话,要超越他们的期待的话,他们总会很高兴的,如果他们超你一步的话,他们就会对你失望。
    要给你的客户带来惊喜,当他们发现了问题,如果你事先已经预见到了,你就能够给他们带来惊喜,就是惊加上喜。我们非常讲技术,我们的倾向是要把我们的技术知识跟我们的用户进行分享,但是我们的用户并不想了解我们的专业知识。比如说我以前做过柠檬汁,看上去不错。但是另外有一个照片,这个也是柠檬汁,我只放了一个柠檬,因此里面加了一些人造的柠檬粉沫,看上去不错,但是实际上没有那么好。我们有时候也做这样的事,为什么我们要把这种东西让我们的用户看?我在飞机上看一部电影,结果我看到蹦出来这样一个东西,我会说真棒吗?不会的。用户对这种文本并不感兴趣。软件应该像魔术,不要让他们看到你制作魔术的过程,不要把这种幻觉移除。你在乎,我在乎,但是他们不在乎。他们不在乎你的业务。到了这个部门,他说你要换另外一个部门,你要找另外的同事,他们度假了。但是作为用户来说,不管属于哪个部门的责任,我只要解决我的问题。用户也一样,用户并不在乎你的公司,他们只在乎自己的问题,他们只在乎自己。
    我们要依赖我们用户的反馈,我们要依赖我们的用户、客户,我们要今天能坐在一起,是因为我们的客户。但是经常我们是神经过敏的人,我们对我们的客户并不友好。我有另外一个体验,有一次坐飞机,这是一家航空公司,我的行李超重了3公斤,他们说你必须交一些费用。我说好吧,他说交100欧元,差不多等于800人民币,仅仅是3公斤。我就Twitter抱怨说,我超重了3公斤,居然收了我100欧元,他们居然给了我回应。航空公司的人说对不起,很遗憾你不知道我们行李携带的政策。大家知道他应该怎么说吗?什么也不要说,他们什么也不要说就可以了,因为我已经够烦了。但是我看到这个回应的话,我简直是愤怒极了。
    我们有一个黄金规则,叫己所不欲,勿施于人。我想在商业世界里面,这条非常非常重要,可以变成己所不卖,勿卖于人。你不要对你们的用户这样做,如果你不喜欢,他们为什么要喜欢?我们来谈一谈全世界。我见过这样一个标识,这是在加利福尼亚。它主要的意思是说如果你需要帮忙,如果你帮忙一个残疾人,你可以过去帮忙,不管这个残疾人是男人还是女人,就是说异性人士也可以陪同一个残疾人士,他对性别有假设,我们现实世界本身就是这样的,我们通过教育,我们发现生物学比这种分类更加复杂。这点不是很重要。但是你能不能变一下,你可以变成任何性别的人,而不要说相对应的,这样就把世界变成了黑白的世界。
    惠普推出了一款笔记本电脑,这不是我编的故事,他们为女士推出了一款笔记本电脑。大家看上面有蝴蝶,看上去像女性的手提包。还说这个屏幕非常亮,以至于可以当成镜子来化装。他们是这么说的,这是2010年的事情。这是为女性推出的一款笔记本电脑,你可以用亮的屏幕来补装。什么意思?这是给女性用的ipad,这是给男性用的ipad,这是给黑人用的,这是给黑人男人用的,这是给黑人女人用的,这是给自闭症儿童用的ipad,他们都是一样的。没有一个专门给妇女的,专门给儿童的。市场细分不会使我们团结起来,如果你要制作一个给妇女用的东西,这聪明的一个点子,你干吗不设计一个给人人都能用的东西。
    我认识制作这个游戏的人,任何人可以玩这个游戏,这些人现在富到比上帝都富,因为他们发明的游戏是给人人玩的,是给每一个人玩的,要为人人设计,不是因为这样做好,而是只有这样做才是正确的。当你为人人做设计的话,你的客户就变成了人人。
    我们讲先人一步的故事,我参加过一个漫画大会,包括科幻的作家、漫画的画家,是一个非常大的聚会,但是参加这个大会,大家都要做一些化妆,做成超人之类的。我觉得我有好主意,我不化妆,我干脆把我以前的胡须刮掉,让他们觉得我是来自漫画里面的人物。所以我就参加了这个漫画大会,刮掉胡子参加的,但是没有人注意我。我看到其他的一些人,他们穿了戏装,很可怕的戏装,结果有很多人蜂拥过去跟他们拍照片,非常兴奋。你完全可以说这些牌照的人真傻,给这些穿廉价戏装的人拍照,他们难道没有发现我不穿戏装更好吗?很多人会采取这张态度,这是手推依,我看到一个人坐轮椅上,他嘴上咬了一个铅笔,他是做程序设计的。
    我是否要就这点来抱怨呢?我不会的,因为我看到他了。他们是怎么做的呢?我回家之后哭吗?不。我做了另外一套制服,我站起来,我穿成这样又回到舞台上,然后我就成了头版头条,我成了墨西哥的头版头条。我碰见有人说我在报纸上看见你了,我在新闻上看见你了,简直是太棒了。也就是说我们只有自己才能自己,我们不可能改变所有人,我们不能改变别的想法,我们只能改变自己。如果说你做的事情没有影响别人的话,可能就是你的错误,也许他们错了,你对了,但是不要去管它,我们能做的可能就是改变自己,我们没有办法改变别人。有的时候,关键是我们要改变自己。
    我们再看一下这个,这个是最好的一个服装,我们都知道它的服装是特别酷的,如果有100个人都穿这个衣服的话,那就更加酷了。就像士兵的制服一样,如果100个士兵穿这样的衣服,那就更加壮观了。这是另外一个版本的,如果我们有100个人穿着刚才的制服,其中有一个人穿着夏威夷草裙的模式的话,那就更加凸显了,一下会记住这个人。就是说我们要保证我们能够被别人记住。比如说在这样一个会上,有很多的信息,有很多人,我们很难把所有的东西记下来,开完这几天会议以后,你的脑子里面装满各种各样的信息,你可能记不住我的名字,但是你会记住戴帽子的那个人。
    同时我们还有这样的一个,大家看这种服装,我们知道刚才的夏威夷的例子比较拷贝,如果说有人穿夏威夷草群的话,可能明年会有五六个人拷贝,但是这个人的这种做法很难拷贝,很难复制。也就是说当这个东西做起来更难的话,那么拷贝的难度会更加大。我们明年如果参加舞会,我们可能会做一套非常非常难的制服,这样别人复制起来也更难了。当我做演讲的时候,我在中国会讲一些中国的情况,我跟别人也会讲,我们到底该怎么样来应对中国?因为中国生产的东西很便宜,我们怎么样与中国进行竞争?我们看到在过去的几十年中,可以看到有一些物质的快乐的东西,我们的东西越来越便宜,越来越便宜,就是说它可不是那么贵,但是在不贵的同时,可能质量也下降了,由便宜所产生的快乐它并不会持续太久,如果你买一个东西让你快乐,我觉得它不会持续太久,可能刚买的时候很高兴,过一段时间可能就不高兴了。
    比如是我们会产生很多垃圾,我们会为孩子买很多玩具,然后很快就扔掉了。我们必须要做一些质量高的东西,我们不要再做一些垃圾,我们的世界已经充满了各种各样的垃圾,各种各样的廉价品,我们不要再去做廉价品了。如果想赚钱的话,做一些质量不好的东西很难赚钱,很多人在做质量不好的东西,如果你做的东西特别好,你面临的竞争很少,因为很多人无法把东西做到很好。但是如果你要做到好东西的话,做伟大的东西的话,首先你应该拒绝做那些廉价品,拒绝做那些不好的东西,但是实际上也很难,因为我们在不断地推你,快做,快做,赶紧出新品,所以我们需要在质量和速度方面寻找一种平衡。我们很难做出一些特别伟大的东西,不仅仅是从技术角度来讲,从社会角度来讲也很难。
    如果我们要去做这种伟大的特别好的东西,我们必须保持头脑清醒。所以希望大家不要从价格上来进行竞争,因为我们都知道我们不可能通过成本上来进行竞争,因为我们知道中国不可能一直都有这么便宜的成本,我们知道现在中国变得越来越好。如果中国的价格优势没有了,那个时候可能大家会觉得在中国生产的东西太贵了,他们都去柬埔寨。到那个时候,我们就不可能通过价格取胜,我们必须通过质量来取胜。
    刚才讲到中国产品,我们觉得中国的产品就意味着不是好质量。因此我们必须改变这样的一种模式,我们必须让我们的质量更好,必须生产出更好质量的产品。我们做的产品不应该是复制品,而应该是一些新奇的创新的产品,让大家一看到就问这个东西从哪儿生产的?北京生产的,不可能吧,北京一直都是生产廉价品的。
    我们知道在这个世界上,有人扔下石头会看到在的地方有一些复制,我们看到世界上,比如说像哈利.波特,或者是奥巴马的这样的一些东西,印着这些标记的东西,我们看到这些东西都是一些复制品,都是没有价值的。实际上不管复制成什么样,都没有人去关注,我们不要关注这些东西。如果我们花的时间都在看我们的竞争对手做什么的话,你一直在跟着竞争对手的屁股后面走。如果你要在竞争当中脱颖而出,你不要去看在前面的这些人是什么,不要看别人的屁股,我们要自己实现创新。我们做事情的时候,仅仅因为钱的原因吗?当然钱很重要,但是如果仅仅因为钱的原因做事情,这就大错特错了。比如说我雇一个人,这个人需要钱,那么就很容易激励这个人,但是你可能会发现,我们赚钱的方法有很多其他特别容易的方,为什么要做工程师呢?我们可以去赌博,赌博也赚钱很容易。有一些人想富有,主要因为他们当时的目标想改变世界,所以他们富有了。
    同时也不能想当然,我们不要仅仅个去复制,仅仅出于钱的原因去复制,我们应该把一个新的东西推出来,保证这个新的东西有非常持久的时间。昨天我碰见了一个人,大概和父亲的年龄差不多,我问他,你是否想过中国的未来?你对你儿子的希望是什么?他告诉我,他根本没有考虑未来的事情。他对未来没有任何的期待,因为在他小的时候,他当时捱饿了,但是现在他有东西吃,过的很富足,因此他很高兴。但是对于下一代,他们会生活更加容易,他们会做的更好。我们现在所拥有的这些东西,主要是因为我们的先驱,我们的先驱他们曾经做出了很多的事情,所以才使得我们现在有这样的生活。因此,我们现在的这种好生活是因为我们的祖先,因为我们的祖先为扫清了道路,对于我们来说,我们应该为下一代扫清道路,这样他们将来就不会受苦受难了。
    但是生命是有限的,它是短暂的,它是非常珍贵的资源,任何时候这个资源都有可能消失,但是我们没有注意到。因此我们必须要利用这些时间来做一些值得记忆的事情,我们在这里牺牲所有的时间,所有的东西,都应该是值得的,我们所做的这些牺牲应该是能够为世界带来一些不同的。当然赚钱很好,但是我觉得我们一方面也可以赚钱,另外一方面也可以让世界变得更好。虽然做这个事情并不容易,但是它是可能的,我们可以把世界建的更好。
    我当时买了这个东西,它实际上也是一个广告,我们会看到买东西的时候它有很多的包装袋,这个包装袋最后都变成了垃圾袋,但是我们可以把这些包装袋变成一种非常珍贵的资源。通过这种方法,我们可以节约更多的资源,让我们的世界变得更好。我们再看一下苹果所做的一些事情,我们并不是说这点来解释苹果的做法。我们以前有纸质的书,还有塑料的音乐或者是媒体。当时我们所有的音乐的设备都是实体做成的,我们必须在家里面留出空间来装这些音响设备或者是音乐设备,但是现在都不需要了。现在都变成了数字的产品,我要告诉你的是,我所有的媒体,它都可以随时带在身上,不需要在家里面占一个地方,我不需要害怕别人会把我的媒体带走,为什么?因为我根本不担心,我的媒体即使丢了,我也可以马上下载过来找到。因此它是非常强大的。通过这种做法,苹果赚了很多钱,变得非常富有。通过这种方法可以看到,我们一方面可以赚钱,另外一方面也可以让世界变得更好,这是可以做到的。
    有可能你会觉得质量好的东西非常贵,但是实际上质量好的东西并不意味着是奢侈品,并不意味着价格很高。苹果最开始的时候,经营状况并不是特别好。我们希望有一样东西可以一年一年的使用,我们甚至希望这个东西可以传给我们的孩子,或者是传给朋友,能够反复使用。比如说iphone,如果你不愿意用的话,你想升级的话,你可能会把这个iphone传你的朋友,有人愿意买帐,因为它质量非常好。这里并不是关于成本,而是因为价值,如果质量是零的话,那么它的价值就是零。对于我们和我们的客户来说,现实就是非常短,我们没有时间做特别糟糕的东西。谢谢。
    主持人:再次用热烈掌声感谢Mike lee带来的精彩演讲。
    
    主持人:今天上午第二个主题演讲是Robert Johnson带来的扩展社交计算。掌声有请Robert Johnson。
    Robert Johnson:非常感谢,我非常高兴到这里来。我今天想讲一下社会应用的升级。我在Facebook已经工作六年的时间了,我主要负责升级。当时我只是负责几百万个用户,现在有上亿的用户了。很多时候我发现我面临的挑战一样,总是重复出现。几乎在所有的行业,可以看到应用也变得越来越社交化。因此,必须使得我们的应用非常地强大才可以。但是我们也需要应对新的挑战。因为我们都知道人们在进行升级的时候,可能会采用不同的方法。
    今天我会讲一下社交应用以及社交数据,它的数据是什么样子的以及它产生的问题是什么。同时也会讲一下架构的模式,我们应该使用什么样的架构模式来解决这些问题,来解决这种大型扩展的问题。同时在今天下午会更加具体讲讲社交数据库,但是在这一部分,我主要讲的是故障,在处理错误的时候我们到底应该怎么做。我们知道在扩展社交数据的时候,我们会碰到很多很多的问题。它对于不同的应用,对于不同的数据库来说意味着什么。
    他们是彼此互动的,如果跟你有连接的用户,你可以跟他实现互动,是你的朋友,或者有共同的兴趣,因此可以实现互动。但是我们并不能保证很多人都共享这个东西。我们需要有一个连接,把这些人联系在一起,才能够实现互动。我描述一下我自己,我六英尺高,金黄色头发。好象这个描述没有什么意义。但是如果说呢?我有一个六岁的双胞胎,这个可能比较好了。因为它体现的并不是我的一些属性,而是我与世界相联系的一些东西,这样就比较容易记住,而不是我自己本身的一些属性。
    我们通过什么和世界联系在一起?你可以看到和世界联系在一起的这些东西,可能要比我们自己本身的属性更加有意义一些,更加容易被人们所认可。因此,我们必须保证其中的联系是没有问题的。我们再看一下Facebook图片的链接。不知道有多少人应用。这个应用并不是特别好,可能你会觉得它和其他的一些图片的应用相比,并没有那么好。比如说我们无法修改我们的图片,或者说图片看起来并不是特别好,但是它是世界上最强大的一个关于图片的应用。我们知道Facebook的图片,谁在看这个图片?而且它能够传递出一种非常准确的意义。
    图片能够达到这样一个目的,那么它会变得非常重要,因为通过这个图片就知道这个图片里的人谁,他通过什么方式与世界的人联系在一起的。我们都知道即使是那些特别有名的人,他们可能也是通过这种方式与世界联系在一起的。因此,这就使得我们图片的一个应用变得非常非常大。很多用户也非常喜欢,但是升级起来比较难。经常有人跟我说,你为什么不把这个数据放到离我比较近的服务器,这样的话,可能速度更快一些,我的答案是什么?因为我们去都知道,当我们去一个网站的时候,我们看的不是自己的图片,我们看的是别人的图片,别人的数据,我们可能会把别人的一些数据和别人的图片放到一个数据库当中去。但是不会关心他的朋友是谁,这个不是我们关心的。我们整体的一个数据集,它一直在使用,即使有时候网站上只有2%到3%的用户,但是使用的是整体的用户空间,现在只有1%的人在线,你不可能说我不给他所有的资源。你这样来做是不可以的,为什么?因为即使人少的话,它也要使用所有的这些资源。
    因此,在这种情况下,即使人很少的情况,我们也很难进行分区。这是很难做的。你不能说上线的人很少,然后我给出的资源很少,我进行分区,这是很难的。另外有很多比较小的一些对象,比如说一些电子邮件等等,这都是比较小的对象。很多人说这个简直太糟糕了。觉得我发的信息很少,但是我并不同意他们的观点。最为重要的就是你可以实现互动,我跟某个人交谈,并不是说跟他交谈五六分钟,我一直在做演讲,并不是这样的。对于社交站点,它并不是一个正常的沟通方式,比如说只发一个图片,实际上也是一个对话,它是非常强大的。
    通过这种方式,我们可以进行以前从来没有尝试过的这样一个对话方式。你可以看到,网站上发一个图片,我们需要保证这个图片在即时之内所有的人都能够看到,这样才能与其他人进行对话。因此变更这个频率非常重要。另外就是一致性,你应该保证用户彼此之间在进行对话的时候,他使用的这种模式都是一致的。实际上和我们建机场或者是开银行,这是不一样的。也许这个结果很糟,如果我们的产品传递的是错误的信息的话,那么人们会非常沮丧,在用户之间就传开了,这个产品不好,它并不能够保存数据。这个时候你马上会失去你的用户。有的时候,人们在看一些产品的时候,他也会觉得非常地互动,并不是说一个产品很有意思就意味着这个产品不重要了,并不是这样的。
    我觉得这一点也是非常重要的。很多人会经常喜欢使用我们的社交网站来与其他人进行互动,进行交流。在有意思的同时,他们也传递了非常重要的一些东西,你并不能说一个网站它只是有趣就不重要了,我并不同意这个观点。我们在传递有一些意思的东西的同时,也会传递一些非常重要的东西。
    我们知道有一些数据可能是非常热的,有一些数据非常冷,可能对于量比较少的热数据,到底应该怎么做?如何保证人们经常访问这些数据?我们知道,把这个东西给我们朋友的时候,一个用户可能有几百个朋友,当他贴了一个照片之后,他的一两百个朋友都会看到这个图片。但是我们还必须保证整体的一个数据集它不能够速度特别慢。虽然我们从总体上来看,你贴了一个图片,然后你有两百三个朋友,这样的话整体数据集处理量特别大。对于单个用户来说,他觉得这个速度并不是特别快,他可能会有一些抱怨。有一些人可能会贴一些新的图片,新的图片可能会比老的图片有更高的一些点击率,有更多的浏览率,你也会看到,通过这样的一些新的图片,也会有很多的几年没有联系的一些老朋友也会过来看你的图片,这样的话也会加大我们的数据处理量。
    因此,在很多时候我们需要实时的来处理很多特别小的对象。很多时候它也是这种随意独具,随意的度曲可能会导致非常高的延迟。当我们做随机读取的时候,我们会把非常有用的东西传递给用户。我们看这个页面,我们要成就这样一个页面,我们会需要很多数据。在这里面可以看到,我朋友最近所做的这些事情是什么,以及对于我们来说非常感兴趣的一些东西在这里也能够找到。同时在这里也会看到其他朋友对这个图片的一些评价。
    但是在这里,我们显示的每一个信息的时候,我们必须检查一下它的一个权限才可以。因此,我们需要保证一个实时,保证它实时的出现。可以想象,我们每天处理这样一些信息会达到上百万个,即使这样一个简单的一个页面,大概在几秒钟的时间内,我们要处理的数据就达到几千、几万个,量是非常大的。
    再看一下水平的扩展,什么是水平的扩展?如果看一下机器上,或者是数据库或者是缓存上的这些数据的话,我们不能够同时利用一个机器上的两个对象。否则的话,我们就无法进行很好的升级和扩展。这里是比较典型的一个架构。比如说在这里有两个应用服务器。应用服务器他是没有状态的,这一点非常重要。后面我还会接着讲。应用服务器它会把每一个页面的数据都会分配给它很大份额的一个缓存,因为它有频率很高的随便读取,所以缓存的运行速度也必须非常快。我们知道Facebook运行速度非常非常快。可以看到,所有的工作,很多特别重的工作都是在缓存层来做的。很多很多人尝试的是另外一种应用的服务器。
    这个是非常直接的,也是非常容易的,有非常好的一个表现,用户也非常喜欢这样一个应用服务器。我们可能会针对一个用户在服务器上为它画出一定的缓存。同时对于用户的数据,我们知道这个用户他也有朋友,所以你给用户划定缓存的时候,你也会给用户的朋友划定一些缓存,所以这个缓存会变得越来越大。你可以想象一下,如果每个用户都有一个缓存,如果每个用户的数据缓存,你再给他的朋友分一定的缓存的话,如果每个人有100个朋友,那么这个缓存需要增加100倍。我们在一个缓存的应用服务器当中存储比较难,因为现在量很大。
    这个时候我们会进行处理,每一个缓存只能做一次。当然从应用服务器到缓存当中,我们也会遇到一些问题,但是关键Application Servers它不再是无状态的,通过这种方法我们也提高了效率。我们的缓存服务器它可以帮助我们处理很多的一些随机读取,今天下午我们会就这个方面做更多的详细介绍。
    首先是缓存必须很快,我们花很多的时间,比如说在Facebook花很多的时间保证我们的缓存非常非常快速,这样可以保证每秒可以处理很多很多的数据。当然你的缓存越来越快的话,那么就会遇到其他的一些问题,我后面会具体的讲。主要是一个网络的问题,它会产生一个网络的问题。不仅仅是这个网络的问题,不仅仅是否有足够的带宽,还有就是信息包的问题,信息包的传递等等都会产生问题。
    我们看一下数据互服务器,一般来说,我们会把它当作一个存储服务器。如果我们进行水平扩展的话,你会看到这个数据库的特点,它的数据库可能并不能得到很好的应用。在这里我们可以很方便的来存储数据,同时也很容易存储负荷。我们会去做这些事情,大家如果你把你的数据化成很多的小片的话,那么你的数据库就不能再为你做工作了,你必须自己来做。
    再看一下NosQL,就是不赞成SQL的一种做法。我们知道关于SQL现在有很多的争论,实际上NosQL跟这个是有关系的。如果我们把应用分到很多不同的机器上的话,这个时候我们需要处理各种各样的一些问题。比如说你是否使用的是SQL的系统?或者用的是更为传统的一个数据库。有一些是比较值得做的,但是有一些并非如此。对为重要的,如何把你的数据进行分区,进行划分以及如何进行索引。今天下午也会更多的讲。当然关于我们系统的技术,如果我们有很多的机器,我们有很多如何进行数据的导出。
    假设在扩展的时候涉及到两层,假设我们需要有很多的机器来完成一个工作,那么我们必须把这个数据分配到所有的机器上去,这个时候可能会出现一些限制性的一些瓶颈,需要你来解决。要解决这个问题并不是特别容易,但是解决这个问题还是非常直接的。后面我也会就网络方面给你举一个例子。但是比较有意思的是,系统这个时候的表现方法可能是我们以前所预计不到的,这个时候我们到底该怎么处理故障?对于不同的社交应用,它的情况可能不一样。比如说我讲到很多时候会出现一些同时的要求,那么对于错误的故障的处理,我们知道很多技术并不是特别有用,特别是当我们出现同时上传要求的时候,可能我们现有的一些应用不能很快的来解决这些问题。
    看一下网络的瓶颈,其中一个是我们的缓存服务器。给大家举一个例子,比如说我们有一个应用服务器,我们看到这个数据中心,你看到所有朋友最近的一些pos,如果有100个朋友的话,我们就需要100个不同的机器进行处理。可能会发出100个不同的信息包,这个时候服务器运行就越来越快,大概在几个微妙的时间之内。每一个都会发出我们所要求的数据,之后都会发到我们的Switch,这个时候Switch会出现问题。所以作为一个单一的机器,它可能会指导我们多个机器来进行这种协同的运作。这个时候也会出现问题。可能有人会做一个重新的驱动,当然它也并不是特别有效,主要是出于几个原因,首先是非常慢,当我们重新做驱动的时候,首先是要处理的量可能会增加一倍。如果应用服务器没有获得他所要求的信息包的话,没有拿到它要求的信息包的话,可能因为信息包在Switch丢掉了,也可能因为服务器速度非常慢。服务器很多时候很慢,这个时候我们再发一个信息包,但是实际上它之前已经上传了,我们会再重新传一次。这样服务器变得越来越慢,那么最后会出现很严重的问题。
    这个时候,我们的负荷量增加了一倍,为什么?每个人因为看到他之前的上传没有出来,所以他又重新上传一遍,因此这个量会增加一倍。我们会有更好的一些计划,我们看一下到底有多少服务器它不会丢掉我们的信息包。比如说刚才讲的,它不会丢掉我的信息包,对服务器提出要求之后,看多少服务器能够有回应,给我信息包,我会找有效的服务器,然后反复提出要求,这样就可以实现比较成功的上传。这是非常好的一个例子。后面还会给大家讲不同的一些故障。
    在我们处理故障的时候,我们并不是说要把系统上的这些错误或者是故障完全消除掉,或者是避免掉,这是不可能的。我们希望当系统出现问题或者是出现鼓掌的时候,我们的系统能够应对这些问题和故障,做出一些反应,能够进行一些调整,如果你设定的目标是要避免任何的故障和错误的话,你只有一个选择,就是什么也不要做,不要用系统,不要用机器就好了,那就不会出现任何故障了。当然这个是不可能的,你必须找到一些方法来应对一旦出现故障的时候,如何让我们的系统能够运行下去,找到这样一些方法。
    比如说对于Facebook,Facebook它的运行很快,但是如果大家上传的东西越来越多的话,它会容易出现一些问题,出现一些故障,如果我们使用的东西不是特别了解,如果你建的是一个完全新的东西的话,我觉得并不是说建东西本身很难,你要找出你要建的这个东西当中,哪些可能运行的比较好,哪些可能会出现问题。如果你建的东西,你觉得非常好,如果发现这个东西不是按照你想想的出现故障的话,这个也不是特别糟糕的事情。因为你可能会从中吸取一些经验教训,我觉得这是一个非常好的认知世界的方法。对于我们开发一些产品的时候,也是如此。同时在我们建一些基础架构的时候,我觉得这个也是非常好的一个理念。很多时候人们觉得基础架构很稳定,很快,但是实际情况并非如此。比如说对于Facebook,我们每周会出现一些问题。
   为什么?因为我们知道每一周会有一些用户上传一些新的内容。因此,我们的上传量就越来越大,我们必须找出哪些地方出现了问题,然后要保证我们的系统当其中某一个部分出现小问题的时候,系统也能够应对。当我们在建系统体系的时候,我们希望当系统一旦出现一个小的故障的时候,它也不会让我们为之付出很大的代价。我们通过系统实时的调整能够依然运行下去。出现宕机的情况一般有几种情形,实际上这个是比较典型的一种故障了,就是单点的一个故障。这个也是我们在进行扩展的时候需要关注的。
    如果你进行系统的一个扩展,有的时候你会遇到各种各样的一个单点的故障,主要是因为它不能够很好的扩张。但是有时候软件也会成为一个单点故障,可能这个点就是软件方面的问题。我们知道网站上,Facebook这个网站,有的时候会出现一些问题,但是很多时候我们发现单点的问题是由于软件所造成的。比如说上传片,图片都在文件夹当中,文件夹运行速度很慢,我们需要配置相应的缓存。文件夹很慢,这个缓存花上一天的时间才能处理这个文件夹,因此我们会非常小心的分配我们的缓存,我们会根据不同的网络,不同的应用服务器,根据不同的机器情况来配置我们的缓存。
    当然我们要保证所有的上传速度都很快,但是因为我们同时上传了很多东西,我们发现过了一段时间之后,整个系统瘫痪了,那么这种问题会反复出现。主要因为我们的软件出现了一些问题,但是我们看到它的效果,系统运行很慢。因此,我们必须马上做出一些改变,但是我们在进行部署的时候需要比较缓慢的来进行部署,因为我们现在处理的是几个不同的机器,如果其中一个出问题的话,会带来更大的问题。我们要保证所有的机器上的所有软件能够以一种非常协调的方式来进行运行,如果出现宕机的话,那么软件会自身调整它的行为还适应这种宕机。有时候用户会重新尝试,因为上传一个东西发现没有传上去,这个时候会再传一遍,这个时候会加重缓存的处理量。我们希望这个系统能够正常运行下去,这个也是我的工作。即使你重新上传,我也能够处理。
    但我们是一个实时的系统,如果答案延迟的话,它就是一个错误的系统,这就不能实时的系统。如果尝试了一次,但是并没有拿到我所需要的信息包,这个时候用户就会再重新发出一个需求。如果它没有得到答案的话,它会放弃,用户就会走掉。对于用户来说,希望上传一个东西能够马上传上去,如果不能的话,他会重新上传一次。如果中间出现问题的话,用户会对你的系统比较失望。
    假设我们有很多机器,假设我们有一个仓库的机器,有很多很多的机器。我们会跟踪每一个机器,看它是否在实时的运行,但是有的时候有一些机器会死掉,不运行,有的时候也会出现这种情况。但是如果很多机器都死掉的话,那么这个就是很大的问题了。特别是我们有的时候,在上传的时候,那边处理上传文件的机器,它可能有故障,这个时候会导致速度很慢。如果有问题的机器在处理上传的话,那么用户可能会再重新上传,这样的话它处理的量越来越大,最后会导致这个机器完全死机。最后真正有效处理的机器会越来越少。当然我们有很多一些做法能够保证如果有两个机器同时出现问题的话,也能够解决这个问题,但是如果很多机器出现问题的话,我们该怎么呢?
    我们希望我们的算法要处理两个问题,第一个是如果出现小范围的故障,我们要保证能够处理这个小问题。同时出现大问题的话,如果一个机器出现大的问题,你这个算法要保证换到另外一个好的机器上。如果在上传的时候,30%到40%都是失败的,这个时候应该换另外一个机器了。很多时候我们还会面临流量很大的问题,我们知道很多用户他都会遇到这样一些问题。我们应该保证我们有这样的一个机制来确保当一个机器出现故障或者是几个机器出现故障,我们应该把用户的要求用好的机器来处理。另外避免让这些小问题变成特别大的一些问题。服务器的运行速度需要非常快,当它的速度很难慢慢的话,它会有很多问题在等待之中。
    我们可以做的第一件事情,我们可以缩短我们的等待时间。同时也可以保证我们的服务器不要有太多的请求在等待。我们可以减少一些等待的问题。当然还有更简单的方法来做,我们可以实时跟踪我们的客户,比如说我们会看一下向应用服务器发出需求的用户,我们对他们进行跟踪,然后看某一个具体服务器的线程情况,这个也是一个很好的方法,可以帮助我们来解决问题。
    有一些具体的方法,小问题升级,最好的办法是把他们控制住的方法,在他们小的时候就给它们补丁,第一个就是做测试。听上去非常显然,但是多数人不这么做。因此,我们要建立一些系统,有些东西会让我们睡不着,怎么办?我们要做一个系统的预防。这可能是第一步。做一些测试,看一些体系的反应。最好是在第一个小时去做,比如说在早晨一上班,你利用你的团队,而不要等到半夜时间发生了再去做,真正发生事故的话,你还要把你的团队叫醒。因此,不要当事情发生以后再去做。这样需要你建立起一个良好的习惯,以保证系统的运营。
    另外有一个好的习惯,你会去关注系统的一个部分,你可以让它去超负载,比如说在数据库的层面上,做一些超负载的测试,在真正的过度访问量出现之前,你自己可以先做一个过度访问量的测试。另外就是做实时的检测,对每个方面进行监测,这个也是很多人做的不够的,这个是非常关键的进行系统的监测。而且不要仅仅看普通值,如果仅仅看普通值的话,你会失去很多重要的信息。几个服务器如果崩溃的话,会对周边产生影响。因此,要注意一个比例,注意比例性的问题,也就是说如果几个服务器发生问题的话,就应该进行关注。这方面做的话,都可以使小问题变大之前来解决。
    最后要做的,每次生产当中出现的问题,你就需要花一些时间讨论一下它的根源。并不是要相互指责,目的是要消除问题。因此,最不应该做的就是要去责怪责任人,我们要做的是为什么一些错误会重复?为什么这些错误会变成一种惯常的事情?如果每次都这样做的话,如果再加上其他的步骤。我们在事后去分析是非常有意思的。一方面我们要监测,如果我们做了测试,又做了监测,又发生事件的话,那么事后分析很有意思,说明你的测试跟监测并没有发现一些问题,因此事后分析会让你学到一些新东西,所以事后分析很有趣。
    最后几分钟的时间欢迎大家提问题。我下午的时候也可以跟大家进行互问互答。
    提问:(听不见)
    Robert Johnson:这是很好的一个问题,如果现在开始Facebook,是不是以Mzone作为我们的基础。一开始的时候,我们觉得如果用云计算的话,这样建造Facebook非常快。现在你建造的话,应该从cloud开始,如果我们要用其他人的云,当然效率会更高。我们现在有一个产品,能够非常好的进行登录链接,来帮助你建造Facebook。
    提问:你有没有一些平台服务?有没有一些基础架构提供给其他公司?
    Robert Johnson:我不提供基础架构的服务。我们还有其他很多事情要做。
    主持人:感谢Robert Johnson。
    
    
    
    
  4.19下午
    
  池建强:大家好,今天下午第一个主题演讲马上开始。Jason Brown在上午已经给大家做了一个演讲,上午是一个总体的演讲,下午会聚焦到Cassandra上,新浪微博在用,Cassandra在国内应用并不是特别广泛,我们看看Jason Brown能够为我们带来什么样的分享。谢谢大家。
    Jason Brown:我们很喜欢SimpleDB,它是用NosQL的方法,而且是云计算的技术。问题是有很高的延迟,还有就是在速率上有一些限制,有多域的分布,需要有一个过程。另外,没有预备支持。我们在SimpleDB比原来的设计增加了10倍,所以问题很多。所以我们要转换其他的数据库,过去有SQL,但是很多东西我们没有选,我们最后选的是Cassandra。它跟SimpleDB很像,我们现在是自己托管,大家都是彼此熟知的一种关系,它是以Column为基础,客户反馈非常好,性能也看上去不错。
    我所工作的领域是做AB测试,什么叫AB测试?这里面有一些核心的概念,一个测试是对几个竞争的行为进行试验,看看哪个行为对我们的客户是最好的。在一个测试里面有一些单元格,他们代表了测试里面的行为。还有就是分配,针对客户被分配的一个单元格在这个测试里面。一个客户只在一个测试里面有一个,多数都是不可变的,如果老变会有不同的行为,我们就不知道一个变化是不是对其他的行为产生了影响,我们对值一般不进行变化。
    让大家看一下我们最近做的一个测试的例子,比如说对电影的描述,如果你把鼠标箭头点向一个方格,它只是用文字来描述影片是关于什么的,对这个电影有一个文字描述。但是右边的这个,当你把这个箭头指向一个电影的小窗口的话,它不光跳出文字解释,还一段视频的样本。我们做的测试是在主页上,如果你能把影片的样本做一些介绍的话,这样的话会增加访问量,会增加浏览量。
    在我们实施UI的设计以后,并没有增加浏览量,虽然让大家的视频看这么一段,我们这种测试在Netflix,我们每天这种测试都做,只要是影响客户的方面,都是会做一些测试。
    下面来谈整个的数据模型。AB测试有两组数据,一个是客户分配数据,客户被分在哪个测试里面了,这里面有一些数据群,测试它的ID、名字,还有这个客户的单元格和其他的一些数据。关系模式的分配,当我们把Relationl数据迁徙出来,这个表格太大了,它一共有11个记录,在这个表格里面,每个客户做的一个测试都有一项记录,在这个表格里面,又有一个独特的限制条件,对客户测试的限制条件,不可能安排在不同的单元格里面,作为客户来说。
    关系模式的原数据是一个非常典型的母与子的表格关系,包括有客户的ID、名字。前面那个是母表格,下面是有子表格,这些功能对大家可能没有太多的兴趣,但是这是一个通常的结构。在NosQL的解决方案里面怎么样做数据的建模呢?我到网上求助的时候,大家告诉我要了解数据使用的模式。我认为需要回答的问题是客户处在哪些测试,还有哪些客户被给予了测试。最后需要知道这些数据群如何对它进行询问,然后获得一个持续的模型的匹配。
    做印射,我发现问题可以分成两类,一个是高访问量的请求,还有一个是低访问量的请求。高访问量尽快给我所有客户分配的情况,可能一秒钟有3万次,在高峰期。低访问量的问题主要是一些行政管理的任务,但是也非常重要。比如说你要获得所有的客户在一个测试里面的数量以及找到所有的一个测试里面所有的客户,同时要找到所有的客户的ID,按照日期范围。这样的话,我们可以识别1月1号到1月15号之间进行被备测试客户总的量。
    数据建模在Cassandra里面,我们要采取的是非常规化的做法,找ID要用逆向指数,到NosQL世界里面,这块是非常有意思的,尤其是Cassandra。我们要知道一个测试里面客户的总量,这对于一个项目的经理来说是非常重要的,那么就是非常规化,对客户的数据做这种非常规化,有一个非模式的这种做法。但是如何把一个关系模式转成一个非常规化的这种做法,并没有现成的做法。反规范法的迁徙,并没有一个现成的说法。
    我们看看结果是什么样的,上面这个图表是一个标准的RDBMS的图表,蓝色的是客户的ID,我们看到一个客户有三行,他参与了个测试,包括42、47、49。在非常规的测试里面,在反常规法里面,一个客户只占一行,而不是三行,但是把他安排在同样的一行里面,这样的话就不是三行了,就要跟前面规范法的做法就不一样了。
    在Cassandra里面怎么做?我们最后决定把它组合在一起,但是这里面回来有序列的蠕虫的问题,或者是序列漏洞的问题。有些地方,如果形成一个序列的话,那么可能在整个序列上形成问题。在你找到问题原因前,整个序列可能会产生问题,我以前就发生有这个现象,所以我们不要重复这样的错误。所以说我们就要用一种混合柱的方法,或者是混合列的方法。混合列就是把这个名字做一系列的标记来处理。把这些名字里面的标记做了分类,怎么做?同样客户的ID,比如说在42个测试里面,我们有一个列,把这个名字分成两块,一个是测试,另外是一个标记,能帮助我们识别数据是什么样的数据。这是一个能激活的单元格,42。
    在42里面,我们看单元格等于2,在42激活里面,值等于Y。这样的话就能够避免所谓的clases。要对这个值进行改变,你需要阅读,然后进行修改,这是一种数据的竞赛,我的编码方法,当有请求对这个客户进行分配的话,我们首先阅读看它是不是在这个测试里面,如果不在的话,我们发现它在的话,我们就忽略这个测试,如果不在这个测试里面,我们就开始去写作。当然同样的机器里面,可能有两个线程,也可能是两个机器里面有同样的行为我们先阅读,如果什么也没有的话,我们就开始写,两个机器同样写,但是在AB的测试数据里面,这样做是可以的。只要写作成功,那么就可以抵消这种不一致的情况。
    比如说你要写电子商务的软件,比如说跟信用卡有关系的,跟记帐有关系的,这样的数据就不够安全。我们现在在考虑如何把电子商务的数据从Oracle的数据库迁徙到Cassandra,来处理风险,保证一致性。
    在原数据建模方面,对所有的测试数据做成一行,这是一个合成柱或者是合成列的特点。首先区别这个列里面数据的类型,然后考虑ID的字段。测试的数据有这个人的名字,还有ID,还可能会描述每个单元格特殊的一些东西。我们分配型的数据,我们还有另外一套数据是需要考虑的。
    我们看一下ID,非常简单,就像一个单元格一样,非常简单的数据。如果我们对这种子格进行分配的话,我们在Cassandra里,所有的内容要对它进行数据的绘图,所有的单元格,每一列都有,所有这些分配都已经修改计划,然后有各自的ID,把这些都连起来。
    我们看这些指标,看一下Cassandra非常简单,它有相应的指标。它有内件的这些指标,效果很好,我们对某一列进行命名的时候,它是前后一致的。比如说客户的信息,比如说电邮地址,这一般是最常见的。Cassandra在这里面对它制定指标,很简单。比如说有一个域,这个域是专门留给电子邮件地址的。因为这是一种反常规化的数据,所以我发现有一个问题,没有这种前后一致的通用的命名方法。因为它这种测试可能是不同的测试级。因此,对Cassandra来说要进行编制是比较不容易的。
    最后我们是这样做的,我们自己来建立这些指标体系。在检测的时候,它有反向指标,我们有这种关键的测试和单元格,比如说看客户的信息,我们有时间戳。我们把这些指标,每次给一个客户分配的时候我们该更新一次,关系数据库一般都这么做。其次,我们需要计算一下客户的数量,比如说我们在Cassandra里面对客户的列的分配,IO就是进出,这个数字应该比较容易统计。在这里面有一个Cassandra柜台模式,对这里也进行测试。当然在这里来说,不是说依赖于某个柜台,我们有多次的方法。行为方式显然是不一致的。因此,在我的反向指标里面,只运行一次。
    在实施的时候,101,如果再弄一次的话就是102,它的行为方式每次都是不一样的,最后的值也是每次都不一样。因此,我们在写的时候,有时候对于我们来说也是很有风险的,我们需要仔细考虑一下,研究一下。我们在重建这个指标时候有点不太容易,需要把这个指标重新建一遍,我们有上百万行,这个指标是一种非常简单的指标,比如说100万零1000,有的时候也很让人迷惑,这个重建指标的时候面临的问题。
    我们的部署以及Cassandra相应的一些EC2的工具,我们如何来利用Cassandra。数据是在EC2的区域里面,在美国、欧洲这个都可以用。看底下这个数据也很重要,我们有三个人的一个小组,他们专门做Cassandra,他们主要的任务是做500个。
    刚才谈到了EC2是我们的家,我们在这里运行任何的事情,还有其他一些事情,我们所有的cluster都在不同的区域里面,有时候也要避免出现一些灾难性的情况。如果可获得性下降。cluster是面向全球的,还有面向各个地区的,这些规模是可变的。对这个平衡器来说,它能够更好的控制这种情况。我们在Cassandra里面,一般这个就是3,它的因素是3,使我们能存储这些数据,我们在不同的地区里面,我们可以集中式的存储这些数据。我们看EC2的地区。
    (没翻译)
    看一下测试的反馈,对于数据中心来说,有一些快照,有测试环境,这是一个排错的功能,很容易的。Priam也负责管理EC2的cluster,EC2会找令牌,如果发现有的话,它就拿到令牌,然后把文档读取出来。Priam决定出哪个令牌,它各有不同的可获得性。Prima对Cassandra的部署也是部署在不同的区域的。安全的部门,他们提出了很多要求,对安全性提出很多要求。最后在安全小组里面,在美国东部,他们知道这些IP地址,他们之间是互相共享信息的,只要有一方知道了IP地址,其他的小组也就知道了。在美国东部的这些节点,这些IP地址送给欧洲的一些小组,然后欧洲再把它反馈到其他地方。
    这样的话,在不同的地区内,数据是在流动的,Cassandra可以把这些数据在不同的大洲之内进行传输。当然具体的文档,我不太记得了。
    下面谈一下Java客户。Hector这是最早开始的,它是Java的程序库,在很多年前,那时候Hecdor是0.7版,很快就遇到了流量的问题、可扩展性的问题,有很多错误,设计不够好,这是一个hector早期的版本。后来我们决定自己给客户写程序库。hector是希腊神话中的一个人物,这个也是我们用的一个神话人物的名字命名的。它是一个法国人写的,法国写Twitter的一个人写的,它有一些它自己的功能。首先它是一个比较精细化的,是比较小的一个工具。我们看它有Cassandra的节点发现功能,它不停地会更新,然后会发现这些节点。如果一个nodes特别慢的时候,它会发现,然后找出问题,然后再试一下,还有这些门卫的系统。比如说像Java features,它运行结束的话,不会运行太长时间。今天上午谈到了异步,这样的话,能够想办法把它解决了。它的连接方法,这是一个非常简单的方法,对一个很简单的请求来说,它都会把这些获得。
    问题是,举个例子,你的服务,比如说数据是在token1里面,它不知道跟哪个圆环沟通,比如说ABC,这样有一个协调者,协调者在中间来决定。我们把它实施了,token aware。这些标记的范围,这些knwos都是知道的,你不需要到所有的nodes去找,我们可以到Cassandra的服务器端去,也可以到客户端去。现在让大家看一个编码的例子。让大家了解一下特色,第一行是一个密钥的空间,首先跟用户进行对话,现在是对Cassandra的用户,下面是一个列的家族,跟列的家族进行对话,第一行有Astyanax,这是我的列家族的名称。第三行是带注释的一个混合列,我会用做注释的一个组来做混合列,用一个标准的Java,以及用尽可能多的注释标记,如果大家还记得我这个例子,从我的这个分配的例子,我有测试、研究,还有一个字段,还有单元格,这儿有一个混合列,告诉Astyanax它的字段在哪里。这样的话,把它们加进去了,加到Java里面了。这是活的编码路径。
    我们看到keyspace,你可以了解混合列家族的名字,这样就看整列。非常有趣的是,在字串这块获得的名字,它可能指的是单元格,或者是其他的分配,然后把这些值放到一个域里面。
    最后我要谈一些剩余的问题。分享一两个故事。在我们运行Cassandra的一些经历,Cassandra在EC2里面表现的情况。还有压缩,压缩是Cassandra对自己的运维,我们要每十秒钟做一个存储,这个变化被写在存储器里面,然后被冲到一个硬盘,叫sstoble,过一段以后,不光是几个文件,而是指定的光盘,有两项管理,一个是对sstoble,一个是尺寸分层的战略,是一个标准的做法,把sstoble用类似的尺寸把它进行扩大,还有一种叫水平的压缩,采用的是谷歌的技术。你跟Cassandra打交道进行压缩的话,延迟高峰会发生的,尤其是在阅读非常繁重的系统里,在我这个系统里面,我们95%都是阅读。这样的话就要到光盘里面获得数据。
    我们面临的问题主要是写IO这方面会遇到问题,它可能会转移成30个每一秒,另外再增加其他的Compactions会对IO有争夺。怎么样规定它的大小呢?如果是70G可以利用,这个时候还要进行压缩。这里面有几东西是能够帮助的,如果做要所的话,有一些截流发生,截流的设置在Cassandra1.0里面能够起到作用,其他的一些技术,如果跟Cassandra打过交道,你可能知道主要压缩叫什么,但是通常不要那么做,对于我们的数据模型是比较有用的,但是运行非常频繁。第一个数据群是一周运行一次,如果有一个起点的话,如果没有这种大的压缩的话,你可以用逐渐弥补型的小的压缩。如果一周一次做这种大压缩,它老会回来,从我们的角度来讲,延迟会比较一致。
    调协,有密钥的缓存,还有行的缓存。关键是你必须有一个非常好的边界线,我的经验是如果你对开始的规模不做控制的话,那么会出现问题,比如说caches,我们现在说的是0.7版的Cassandra,1.0的可能有很好的表现,但是我不知道。不用的缓存放在存储器里面,这里面有2900万的空间,这样的话需要回收这些垃圾。但是有时候他们在到处跑,收集就不可能了。这样的话,机器就要做越来越多的垃圾回收。这样的话,也会让其他的任务都减慢。这样的话就会有延迟的现象。总体来说,现在表现已经比以前好多了。
    现在谈分区的问题,分区还是有用的,比如说有一个单列,如果流量特别大,那么它会形成一个热点,很容易形成热点,更加微妙一些的东西是做非常宽泛的行。之所以这样,Cassandra是线性的去看待每一行,它一般是线性的经过每一行。Cassandra很聪明,它可能会负载60K,这样使得宽泛的行会有更好的表现。
    最后是一些要点,我们这个公司正在全球化,要保证我们每一个单元的可靠性。Cassandra是我们依赖的一个对象,是我们云基础架构的一个关键的部分。我们在把我们很多的云平台进行开源化,包括Cassandra的支持和STNX。谢谢大家。
    提问:Cassandra我有一个很好的经历,有一些集群里面有75个konws,所以扩展就遇到了问题,扩展的话,必须把konws的数量加倍,你有什么好的想法?
    Jason Brown:如果要进行扩展集群,我们一般是把rain进行加倍,这样Cassandra非常容易做到,这是一个非常好的迁徙数据的方法。但是要平衡这个rain,这个nodes就比较难实现。
    提问:对于我来说一个难点,是找到75个nodes。
    Jason Brown:比如说一个团队有75个nodes,这会让我们非常紧张,这不是容易的事情。增加rain,这是容易的方法,你必须要自问一下,如果想增加nodes,你需要多大。是增加20吗?并不是越大越好,因为这个涉及到相互抵消的问题,这是一个互相平衡的问题。
    提问:对于未来Cassandra的版本做一些版本,对于rain增加nodes。
    Jason Brown:这个取决于在哪些标记的地方增加这些nodes,以及这些数据如何进行迁移。我们每个nodes的标记范围要一样,因为分布要平衡。
    逼问:我有另外一个问题,我想了解一下最大的nodes有多大?最大的nodes里面数据有多少?
    Jason Brown:我的数据是40G。增加数据会有问题。Cassandra硬盘不会有这样的问题。这方面他们还没有成熟,我们还在挣扎这方面性能的问题。我们要做的就是停止阅读数据,而是利用了缓存。我们现在尽可能的取消这个缓存,缓存让我们的事情更加复杂。这不是Cassandra的问题,而是环境的问题。你可以利用自己的数据库。
    提问:我们这些方面做了一些更改,一个硬盘一个node。不知道Cassandra在这个方面有多大的改善?
    Jason Brown:最终每个都需要一些空间,如果你有三个实例,每个是10G,这样20G给操作系统。
    提问:关于恢复,因为不同的nodes进行上传数据,要做全部的复制,我们怎么保护失去的数据?如果有多个服务器有这些数据的分离,怎么样去进行恢复?
    Jason Brown:这是一个很好的问题。我们怎么样知道,需要恢复的数据有多少。这是一个很好的问题。没有一个好的答案,每一个node,比如说你有六个rain,你需要把标记范围进行复活,在那个机器上复活就可以了。如果复制因子是3,这样的话,你不会失去任何东西。如果3个nodes都失灵了,比如说有持续的nodes,如果nodes不是连续的,你可能就ok了,你要知道这些nodes是不是连续性的,以及复制因子,如果复制因子是3的话,那么如果是三个nodes都没有问题,但是如果5个nodes死掉就有问题了。
    提问:有什么工具来监视,让我们了解恢复是用备用数据恢复还是用什么方法?
    Jason Brown:非常好的问题,如果我们有那样的一个故障的话,我们会解决整个的问题,也就是说我们恢复的时间是多少。主要看你有多少数据,看有多少字节,看下载这些字节有多长时间。非常感谢。今天下午我会一直在这里,大家如果有问题的话可以继续沟通。
    
   池建强:下一个演讲是基于Rails的大型B2B架构优化。
   于冰:B2B的系统,可能大家不是一定特别熟悉,FreeWheel就是做B2B的业务公司,非常典型。我们先介绍一下FreeWheel大概的背景。
    FreeWheel公司是在美国一家视频网络广告公司,总部在纽约,这个图片是在客户的那里拍下照片,可以看到纽约时代广场的大国贸牌,这个能够显示出FreeWheel公司的状况和它的业务。实际上FreeWheel非常简单,左边这个是在线视频,加上我们的系统,就等于大把的钞票。这个图片是撞车,我们主要提供在线的广告和支付平台,原来只做广告,现在还要做支付。也就是帮助在线的视频内容公司全方位的把钱赚上来,再把钱收回来。我们现在已经在美国有30%的在线视频由我们提供流量收入,每天处理数百万美元的交易。这个数据是来自于一个权威的报告。这个是客户的列表,大家可以看到很有名的NBC、CBS、SKY,还有很出名的VEVO,它为Youtube提供音乐视频。我们系统里面有两个很奇怪的名词,一个叫MRM,一个叫RPM。RPM是在广告的交易过程中用来收钱和处理合同的。
    这是我们客户的一个页面案例,大家都看网络视频广告,大概就是这样的,在视频中间插一个广告,这个是NBA的网站,右边还有一些广告。我们的系统架构也非常简单,其实里面很复杂。从客户的广告系统,最左边客户的网站上会来很多的广告请求,并且由我们的广告服务器来服务。这些广告是如何设定的?是由今天的主角UI系统设计出来的,它把设定好的广告信息从数据库推送到广告服务器上。这样的话,客户的网站上可以呈现出非常复杂的广告内容。同时为这些视频来赚钱。如果没有这样的一个系统,大家可以想象互联网的免费视频就不存在了。
    另外,我们的系统里面其实用的东西非常杂,从总前端的广告集成端是用flash,还有安卓,有非常多的平台的集成,所以会有一个组专门做这个事情。其他的部分,后端是以C++为主,还用了很多开源的一些工具。大概就是这些,比如Linux,mySQL,尤其是后端很重的使用LEVELDB,它不是服务器端的存储,它是嵌入式的存储。
    今天的主角是Rails,我们有这么多的东西,这么多的基础架构的东西需要应对一些技术的挑战。其中最大的挑战就是业务模型特别复杂,这是B2B系统里面最有挑战的,我们的业务逻辑比普通B2B公司要复杂的多,并且我们在复杂的业务模型之上还要保持跟流量同步的增长,这个广告不能宕机。另外,我们数据也随着流量增长不停地增长,所以要不停地优化我们系统里的每一个模块,还有就是质量是非常重要的,因为每天有几百万美金的钱在系统里面流动。所以说正确性也非常重要。所以我们有非常强的Uptime,在保障系统加了新功能以后,之前的功能还能保证。
    我们公司从10年开始成立了基础架构团队,这个团队是我们公司里面有任何救火的事情都是由我们来做,我们的成员都是top站的,然后code mokeys,我们一个是做救火,然后就是做架构重构和快速原型。
    UI基础架构就是在这个基础架构团队中的一个重要的组成部分,因为我们公司在UI上面的开发量是最大的,经过几年的开发,这个系统已经非常难以控制了。所以在这个方面,当然也有Ruby Rails的一些问题,就是这个框架自己带来的问题,所以我们大量的精力花在UI基础架构上,它主要负责MRM和RPM的维护,下面主要由赵晓锋同学灿烂的例子。
    赵晓锋:下面讲我们团队的第一次。大家可以看到我们的Rails第一次是在2007年7月份,基于Rails的1.2.3开发的,很多人觉得东西很不错,但是它在大型的系统中没有成功的应用案例,所以我们属于第一个敢吃螃蟹的人。下面是UI系统的代码量图,大家可以看一下第一个阶段是快速构建阶段,因为是第一次,第一次大家比较高兴,写代码也比较高兴,所以写代码很快,基本上在一年多的时间里面达到80万行代码。到了这个代码量以后,一年多以后,我们的业务基本上成型了,很多业务开始出现,进入业务优化期。这个时期,因为客户的需求之多,它的代码量的增加也增加的接近20万行,最后达到的接近100万行的代码量。现在我们客户多了以后,我们的知识、需求变化比较多,我们需要有更好的架构来支撑。按照因为基于Rails的1.2.3,接近四年以后,我们进行了Rails的升级。到最后一个时期是持续优化升级时期,我们代码接近30多万行,后面进入持续的优化时期,但是我们的客户还是在很快增加的。
    我们的团队也做了一些出版物,就是Rails高级编程的中文版,我们本身有一些文艺追求的,但是到做事的时候是不是这样的?我们下来再看一下。
    业务驱动,我们也是基于敏捷做的,但是是B2B业务,我们的业务驱动的比重特别大。首先第一个是公司业务发展非常迅猛。第一张图,这是我们的广告流量,从广告流量进来以后,几乎是一条直线的方式往上增长,最后占到美国30%的视频广告份额。第二个是业务复杂,大家有时候觉得B2B的复杂在哪儿?举一个例子,互联网应用解决1+1等于2的问题,它的量大,但是它的逻辑简单。在我们的系统里面,1+1比较复杂。比如说涉及到我们的货币,1美元加1英镑等于多少,这是我们要考虑汇率。考虑汇率的同时又要考虑时间,在不同的时间段怎么把汇率变换考虑进去,这个就是业务逻辑的复杂性。
    第二,我们的Release周期。尽管是B2B业务,做企业软件,但是也是基于互联网的模式运营的,我们每个大版本的Release平均就是5到6周。在Release过程中,我们5到6周的时间,在Release前两周要开发,实际开发时间是3到4周,每周还有一个小的版本的Release。在开发中还有一个问题,第一个吃螃蟹,Rails当时没有成功案例,都是我们摸着石头过河,并且最佳实践也不完善,我们自己也在摸索最佳实践。
    下面看一下这几年Rails应用欠佳的债务。第一个就是用Rails太早了,业务发展很快,我们没有时间做架构优化。它的版本比较老,造成社区分享困难,开源支持也很少。社区分享困难,举一个简单的例子,我们以前参加QCon,碰到做Rails的人,我们不好意思打招呼,人家都到3.0。另外一个问题,我们山寨的一些解决方案特别多,这样东西的维护性会出问题。第二个就是fat model,变成一个超级肥婆了,我觉得没有人会喜欢。我们业务逻辑复杂度太高,代码可读性比较差,新人培训很困难。还有就是刚开始没有经验,造成了一些逻辑的分散。第三Rails特有的特点,每张表在业务逻辑操作上会产生很多变动,代码犬牙交错,效率比较低。这是我们的一个页面的简单的演示,选了两个中等复杂的页面,缩小以后看起来很规整,但是每个选项变的时候相关逻辑控制会发生改变。
    下面进入主题,我们的架构是如何去优化的。首先,工欲善其事,必先利其器。用业界比较流行的方案,我们首先要把Rails升级。在我们升级的时候,隔了四年的时间,我们在一些Rails的论坛,我们发了一些消息,看看有没有人有经验,结果有一些人给我们回复,他认为我们做的事难了,简直是不可想象的一个事。我们升级Rails,除了刚才讲到跟上时代以外,还有一些Rails的3.0的一些新特性,比如说国际化这些东西,这些东西都是我们需要的,而且把山寨的东西给剔掉。还有刚才前面于冰同学讲到,我们有两个系统,我们RPM是后做的,所以用了最新的Rails框架,我们需要两面知识共享,共享架构。
    在升级的时候,升级到Rails3.0以后,我们做了一次小的版本升级,是Rails3.1,主要是来管理这些静态资源,把它结构化更好一些。最后一个是我们做了一些JavaScript的升级,我们后面升到1.4.4,最新的可能更新了,我们也有计划跟上步伐去做。第二,把前面JavaScript做的内容统一到UI上。
    这是Rails升级的一个大概的工作量,我们花了三个Release的时期,前面是一个小团队在尝试,变更的代码量,总体加起来,两个变更代码加起来是增加了8万行左右,也减少了7万多行,其中把当时山寨的一些东西给剔除出去,也有四五万行的代码,占到总体代码量的30%到40%。相当于整个系统重做了30%到40%一样。因为我们客户很大,流量也很大,上线以后,这次升级还是比较圆满的,我们没有给客户造成什么影响。
    在进行了Rails升级以后,我们也对Rails应用做出了一些改变,刚才讲到我们太复杂了,代码量很多的时候,你怎么提高效率?我们采用分联法,把Rails里面的应用拆分,拆分一些应用,按照它的功能模块或者是按照应用场景,做成多个板块。我们做了一些分层,第一个分层是基础服务,多个应用都可以用到的,比如说单点登录、用户权限,还有全文搜索、搜索服务器等等,大家可以通过代码的方式去调用。第二,是Module,上面有所有的结构代码,它可以独立运行。对于一个应用,像MRM,它就是多个基础服务和Module组合起来,这样整个系统架构就很清晰了,当你做一些升级,做一些单元测试,做很多东西,都可以在一个比较小的范围内降低互相的依赖性。
    下面讲一些具体的细节,我们怎么去做模块化组装。第一个,我们首先是怎么分拉这些请求。在一个大的应用里面,我们在里面做了一些分发,分发到APP上。在开发过程中,我们集成的时候,按照Module的方式引入进来。最后就是把静态的资源文件管理起来,不需要再过多的考虑,可以结构化考虑。
    下面讲业务逻辑模型。对于G2E里面,为什么提出这个业务逻辑模型?因为我们的本身的模型,在不同的应用场景中太多了,造成代码动辄两三千行。我们做这个工作的时候,第一个先做减肥,从里面抽取出来,放在业务逻辑对象里面。第二个就是把业务层面的东西抽取出来,像数据库层面,像DAO那些层面还是会保留着的,因为那个和数据库约束表紧密相关。
    做完这个工作以后,我们架构图就变了,这里面黄色的部分是传统的Rails应用里面一个基础,但是其他的一个蓝色的module,它们对应某一个特定的业务逻辑场景。下面看看旧的module代码,代码少的时候不觉得有什么,加上外部对它有一些调用,这个时候可能会失效,以前最多的时候,一个里面有几十个,就是不同的业务场景适用。第一个是隐晦,可读性变差。第二个就是离散,很不直观,维护起来比较差。第三,堆积。我们只能说按照Rails推荐的方式,不停地把业务逻辑堆积到里面,最后的代码越积越长。
    这是我们新的module,看起来比较直观,也比较简单一些,大家可能觉得没有太大的技术含量,但是这个地方强调三点,第一个是代码的可读性,它对于新来者或者是后面的人,对于大家维护的时候,能够避免一种维护的陷井。第二是独立性,我只是抽了一个,做价格的一些操作,它有不同的模型对应。这个相对于不同的业务逻辑场景会对应,把它们之间给独立开来,这样也形成了第三点,就是一个合理性。我们业务逻辑变了,我们只需要改单个的,而不会影响到其他的。
    这是我们前端的框架。互联网应用,大家也见得多了,一些MVC的框架什么的,我们也是一个MVC的框架。但是我们的MVC框架和互联网不同,我们的模式是比较固定的,但是页面复杂程度会超过互联网应用的页面复杂程度。总体上都是基于事件驱动模型来做的,我们里面的动作都会去响应,也会触发一些事件。在数据传输的时候,是采用JSON。这里面我们做了分层,分为组件和业务控件,到业务控件,我们通过多个业务组件进行一个聚合,然后可以形成一个业务控件,它里面会隐含一些复杂的逻辑操作。
    这是一个大概的Widget的架构,这是我们自己写的,在之上是有控件,控件里面也有分层,上面就是业务控件,这几个业务控件都是视频广告的术语。下面看一下代码实例。这是在使用Widgte代码之前,这个是日期选择的一个东西,大家可以看到我圈的两个地方,都是两个输入的地方,写到代码里,它的可复用性比较差,很多时候不知道哪块,因为代码太乱了。后面用了Widgte以后,第一个是集成,这个是我们粉状的对表单处理的业务,这是各种类型,最后再绑定事件监听。
    前面是已有的,做一个新的输入的时候,我们可以自定义,最后像创建一个普通的类一样创建出来,这个地方讲的例子稍微有点模糊,我们感觉好象这个是不是Widgte控件,这个不是,这个只是里面的一小部分,我们自己的第一行写到的,我们这样去做它的集成这些操作。这是三个小的Widgte,在这个Widgte里面,大家可以看到有一些Widgte里面内部的跳转,它也可以有多个场景去切换。
   最后讲一下对效率性能的提升。以前是用Lighttpd+Fastcgi。后面我们经过调研,我们最后选择了Unicom,第一个特点,它能够支持动态请求这些,2000多行,万一有什么大的,你自己发现的时候也好找。第二,它控制特别好。因为它本身有自己的一些基础,在Unicom里面,它预装载。碰到一些问题,它可以自动的,它的内存使用过高的时候,它可以自动维护。我们选型的时候有一个原因,就是有成功案例了,这个图大家看的不太清楚,这是一个使用,这是两台机器加起来的,80%左右,后面降到了40%,接近50%,相当于降了40多的内存使用,这样意味着容量也上去了。
    我们内部也做了一些调研,现在开使用一些DCI的模式,我们也在尝试应用,看看能不能和我们现在的工作去结合,能够更好的吻合起来。第二个就是提供自动化测试的覆盖率,在我们的工作中,很多修改的时候,它是一个动态语言,你修改一个地方不知道它有没有影响其他的地方,隐藏的调用性,这个地方发现不了。所以我们需要在这个基础上做自动化测试,我们可以放心的去加我们新的一些特性进去。第三个是代码重构。首要任务是控制代码量,我们保证业务继续增长,流量持续增长的情况下,要把代码量控制在一个合理的范围内,像100多万行的代码不能再出现,还有分层结构这些东西也要做。我们现在需要增加一些定制性的东西,这些东西未来都需要支持的,所以我们也要做。最后一个是稍微虚一些的,我们的产品线越来越多,因为随着我们业务扩展,我们要解决我们架构共用的问题,还有就是提供一些定制化的业务支撑。意味着比如说福克斯过来,他需要哪些东西,一些需要的东西,我们给它一个价格,并且给它一些可拓展的结果,就是做完全的SAS的这种架构。
    最后感谢QCon组委会,还有FreeWheel的UI团队。谢谢大家。
    池建强:我和两位演讲者在会前做交流,包括他们PPT的完善,我觉得PPT已经呈现了一个相对完美的版本,这个版本跟他们第一次交给我的版本,基本上是两个东西。包括昨天还在做这个方面的修改。我觉得他们非常认真想给大家呈现一些东西。我们对这两位演讲者报以热烈的掌声。
    提问:我想问两个问题,你之前提到了你们在使用三个迭代的时间,12个人月,对你们的代码进行大的重构,也涉及到代码量的30%到40%。后面看到你们提到目前你们现在的自动化测试的覆盖率还不是特别高。我想问一下,你们在这三个迭代的时间,涉及到代码总量这么大比例的一个代码的修改和架构的一个更改,你们怎么来保证交付的结果不会产生一些大的问题。还有一个问题,这三个迭代的时间,完全地做代码的重构,在业务功能的交付上,不会存在大的压力,如果有的话,怎么样来克服这个东西。
    赵晓锋:先说第一个问题,在我的PPT里面删掉一页,叫整个过程的质量保证。这个不应该删掉。我说的提高是我们想达到80%,但是现在40%、50%是有的。第二个,我们在这种过程中,我们用来解决上一个版本和现在这个版本之间,如果出现问题的时候我们怎么去发现,它是什么样一个机制?我们先拿上一个版本做一个东西,然后把它数据库里的数据、页面抓取回来的代码,我们给保存下来。这个时候上新的版本,重构以后的版本,然后再去跑一遍应用,这个时候再比较数据库里面的数据,还有页面上的代码是不是出现不一致的地方。然后再把不一致的地方找出来,看这个是不是因为升级引起的。这个工作我们都做了,包括测试什么的,我们都在做。基本上我们最后,其实在当时整个升级过程中,只有20%完全是靠手工做的。
    第二个问题,头两个是我们基础架构组,真正的应用开发,它们的功能开发不受影响。到最后一个,我们集中全力把这个升级升上去,我们牺牲了一些特性开发,但是还是留出了几个人来做一些紧急的需要上线的一些特性的开发,其他人是全身心投入到3.0升级上,一个升级就解决了。
    提问:你刚才说的这种方式,核心人员在做架构升级的时候,新特性的开发,它还是沿着老的路在走,合过来的时候,最后一个合过来的时候,工作量不是越积越多吗?
    赵晓锋:每个开发,在他们做新特性开发的时候,他们的代码里面有20%、30%的代码会受到影响,本身他们知道我们在做这个事,大家可以提前沟通,有一些方法调用的时候会特别注意,它有一些是兼容的,我们尽量保证用兼容的方式来做。两个开发新特性,这个代码量,我们整个团队做这个东西还是能够做好的,两个开发特性,每个是百分之百,业务开发是200%,涉及到代码是占40%,就相当于200×40%,80%的代码需要修改,但是80%的代码做的升级,最好正好从数据观点也可以把这个东西给抹平了。
    提问:我刚才看咱们这边是不是把一个大的东西拆分成很多个小的,如果之前有数据交互怎么做?
    赵晓锋:第一种,基于数据库的数据交互。它肯定有一些共享的模型。第二个方式,通过他们之间的模型的依赖,比如说这个模型它有依赖,这个时候可以引入进来做依赖。第三个就是无状态的依赖,通过协议来访问它相关的服务。
    提问:如果通过服务的方式速度慢一些。
    赵晓锋:它少一些,我们打交道的时候多一些。
    提问:更多用的方法是直接读出?
    赵晓锋:对。
    提问:我不知道我理解对不对,我在想它是不是把一些多态的东西抽出来来了?拿业务的逻辑来做?
    赵晓锋:不是的,单表集成,有点像数据库概念的东西,但是比这个高。举个例子,我们好比去购物网站,你去做一个购物流程,购物流程里面有可能涉及到订单,有可能涉及到购物车,也可能涉及到帐户信息什么的。相当于把这些逻辑分别放到了其他的表上,放到了购物车表上,当然这个例子太大了。一个购物车很复杂的。单表集成,这些东西我们其实还是在保留的。
    提问:他们的关系是什么?是通过集成来做吗?
    赵晓锋:不是集成,应该是聚合的关系。我们在这个里面把它们之间有哪些业务转换在这个里面操控。
    提问:跟这个基本的模型关系是什么?
    赵晓锋:相当于一个Search模式一样,完全是从业务人看这些方法都大概知道这些是什么意思,纯业务的人看可能就不明白什么意思了。
    提问:第一个问题,最后模型的抽取,感觉更像G2E结构,原来如果对Rails本身的理解,可能更扁平化一点,你们在JJavaScript没有衡量过吗?
    赵晓锋:人的第一次不一定是理性的,我们选择Rails的时候,是我们公司的美女,他听了一个很信赖人的推荐,现在Rails很火,做起来很快,他听了以后就做Rails了。因为大家对Rails看起来很不错,最后越做出现一些问题。不管是白猫、黑猫,抓住老鼠就是好猫,只要架构问题不特别多就行。
    提问:第二个问题,刚才讲Rails还要搭配其他的。
    赵晓锋:我们不想用Rails那么重的东西,我们本身自己内部测试的时候还是比较稳定的。
    提问:对性能耗用的百分比是多少?
    赵晓锋:应用的场景还是比较少的,具体数据我也不清楚,到时候回去看一下。
    提问:Widgte,在这个结构里面为什么不用help?如果用help包装的东西,理解起来更方便一点。
    赵晓锋:这算是最后一个问题,当时为什么没有用help包装,它的交错现象还在。而我们的代码量,如果100万行代码,这些代码一旦发生交错,他们的数量级本来是N,变成了N平方,所以把一些东西干脆放到N里面解决,只要能够解决了,我们就放到这个里面。你交错在一起,对于一个中小型系统,我认为是比较合适的,推动也很快。但是大型以后,典型的一个例子,一个新人过来找一个错误,最后翻翻,help套来套去,最后绕晕了,简单就是美。
   提问:我提的问题是关于版本决策的问题,有一个问题,刚才一个PPT里面用的是IEE的1.8.7,为什么没有选1.9.3?你们从Rails1.2.3开使用,到Rails2那个时候也非常火爆,有很多新特性,为什么你跳过整个一大版本,到3才决定做Rails大的迁移?这两个决策,背后有什么原因没有?
    赵晓锋:关于IEE1.8.7,我们做的时候,当时我们在做的时候,版本是1.8.7,所以说我们就延续了,1.9.4我们在另外一个产品里面分批升级的,在另外一个产品里面,我们已经升级了IEE的版本,我们不可能一下升级。这个我们已经在做了。第二个问题,Rails2的跳过,架构的问题,像解决一些痛的问题,当你痛的不是很厉害的时候,大家谁也没有感觉,架构是什么。到最后实在痛的受不了,我们就用架构解决,不是说不痛了,只是变成镇痛了,而不是持续的痛。
    提问:如果现在反省一下,如果你们版本跟的紧一点,比如说每隔稍微稳定一点的版本,跟着Rails往上升,会不会每次少痛一点。
    赵晓锋:这是一个不错的建议,我们以后会一步一步往前迈,免得往前跳一大步就跳坑里了。
    提问:Rails的特点就是快速开发,做一个小项目,当它做成像你们这么大规模的时候,它的特性有没有体现不出来?它只是做中小型项目比较快。大型项目的时候拆分还要做想架构什么的,Java有现成的,它的优势就体现不出来了。
    赵晓锋:因为我以前是做G2E出现的,做大项目的时候,Rails和G2E都会出问题。只是侧重点不一样。换成Java会不会很好的解决?也不一定。一个东西,一个东西你不要轻言放弃,Rails本身没有用到极致,就不要说Rails做不到。任何语言,Java设计的时候,大家说太垃圾了,它不断去演进发展。我现在也相信Rails,我刚开始对Rails表示怀疑。经过我们这次架构优化以后,其实很多根本性的问题已经解决了,我们把它给弄简单了,将来我们做更多的新特性什么的会好一些。
    提问:可不可以这样理解,你们当初最早的时候目的跟现在不一样。当初是追求快速把产品做出来。到后来的时候,可能它已经体现不出来快速的特性了。
    赵晓锋:对,你换成Java也不一定。
    提问:没有省那么多力,但是也不会费力。
    赵晓锋:效率都差不多。做一些报表分析的会有,其他的地方相对少一些。对于要求比较高的地方,我们可能会做单独的优化,这些地方我们会比较好的去把它维护起来,让大家都能够看到。
    池建强:感谢两位演讲者,这个主题就到这儿。大家有什么问题可以私下跟他们交流。
    
    池建强:第三场演讲马上开始。主要是由盛大创新院的高级研究员庄表伟为大家带来一个About Login的演讲。在座大部分是开发者和程序员,要么是做过登录,要么没有做过登录,至少见过登录的页面,见过登录的代码。我们看看今天庄表伟能够在这样一个开放平台时代的登录系统设计上能够给我们哪些提示。欢迎庄表伟。
    庄表伟:谢谢各位的到来。非常感谢大家能够来到这个会场,来听一个挺朴素的话题—About Login,希望我今天的分享能够对得起各位的到来。谢谢。再说句题外话,我有一个经验,每次演讲都会紧张,我的经验就是告诉大家,我现在真的有点紧张。
    何谓登录?这个还需要说吗?首先让机器知道操作的人是谁,是我,庄表伟。但是我还要让它相信操作的人是我,所以我要到底他我的密码是12345。我们今天的话题,登录这个话题太大了,我们不会涉及所谓的登录,比如说登录一个服务器,或者登录到某个数据库,都不会涉及。也不会涉及太多的安全话题,那太深了,这个东西没底。单讲一个登录安全估计就可以讲一天。也不会涉及太多的架构的技术实现。所以如果想听技术分享的同学,估计看到这儿就可能会有点失望了,技术不多,可能会讲一些。
    在很久很久以前,登录是这么简单,如果我们看代码的话,它只有四行代码,可能还可以写的再简单一点,我这个写的像伪代码,看不出什么语言。从数据库里把一个用户取出来,看它的密码是不是等于输入的密码,如果是的话,就跳到页面。我不知道各位有没有写过登录的程序?也许最开始写登录就这么一点,也许稍微加点代码,不要写得太烂,但是也就这样了。
    但是,历史的车轮滚滚向前,如此简单的一件事情是怎么变得越来越复杂的?不可阻挡的趋势来源于需求,需求,以及更多的需求。有人说我不想每次都输入密码,我们在里面做一些手脚,来记住这个人,下次再来的时候就直接登录了。但是又有一个需求,如果机器被人拿去了,我之前做过自动登录,那么别人就自动登录了,我还要设置一个时限,超过30天不要记住我,然后加一些IP地址限制,保证别人不会拿这个东西去冒充我等等。
    如果有人忘记密码怎么办?边上有一个链接,这就到了下一个问题,这个问题跟登录相关,如果帮用户找回密码?请问你最好的朋友家的小狗名字叫什么?但是这样的密码常常人让困惑,我自己的密码都记不住,记人家小狗的名字,太难了。而且很有可能忘记密码的问题,我知道,别人也有可能。这样一种找回密码的手段会出现风险的。还有比如说假装是我,我忘记密码,但是密码重置了,当然我会在邮箱里收到密码,但是过两天密码又变了。还有一个比较好的方法,你收到邮件,给你一个链接,点了这个链接过去再修改。如果这个一旦泄露,还会有人把你这个密码改成别的。当然还有更多的办法。所以忘记密码总是麻烦,请把你的身份证复印件寄过来,请回答你之间最近三次登录的时间,请认这些照片,Facebook搞过这个事情,这是你的好友,你说出他们的名字,我才相信你是那个人。只不过为了减少密码被别人知道的危险。但是这都是麻烦。
    因为要帮用户找回密码,因为要让用户登录,我们再涉及另外一个话题,在注册的时候,我们要让用户填写一些什么?密码是当然,密码要他自己定。我们会选择现在比较人性化的一些东西,一边输密码,边有一个密码强度的提示,但是我经常不同的网站看到不同的密码强度提示,同样一个密码,在这个网站告诉我很强了,但是在另外一个密码,告诉我这个密码太弱了,还得再加。所以强弱只是一个相对的概念,你告诉你强就强了吗?这个很难强。还有就是不需要填密码,帮助你生成一个随机密码,你以后再改。但是这个密码通常很难记。忘记密码是一个问题,一开始做密码找回的时候,就是让你手工填,问题是什么,密码是什么。做注册页面的人发现乱给自己填问题和乱给自己填回答太乱了,所以就变成一个改进的方案,你可以下拉框选择一些常用的问题,比如说小学老师叫什么名词之类的,我到现在也不记得了。
    手机号,这个又是一种手段,你填一个手机号,我发一个验证码,你再把验证码填回去,我才知道这个手机是真的,我以后方便给你发垃圾短信。还有生日,SNS网站希望你填生日,这个我不愿意填真的,他会在我生日的时候给我发生日祝福,这个没有必要。还有电子邮件,这个可以推荐,推荐用电子邮件做登录,这是一个不错的选择,在保证唯一性和让用户少记一些东西方面有好处。
    还有昵称,我通常不愿意用这个,一方面是展现的不好听,另外就是有安全问题,别人会拆我的昵称。
    这个现在开始有,关于实名的事情,这个就不说了,也许会变成真的。还有一个问题也跟登录有关,有人尝试登录破解怎么办?他写密码,一次一次的试。验证码、数字、字母、汉字、问答题,越来越复杂。还有一些比较另类的验证码,让你听一段声音,看一段视频,或者是看一个广告,这个广告最低优惠价格199什么的,请你框里面输入优惠价格,这个创意不错,同时可以帮助厂商来推广,这是一个不错的方案。还有更多的手段,比如说盛大创新搞过一个声音认证的密码,如果你嗓子没有感冒的话,它会让你进去。还有密保、指纹等等。
    有一些登峰造极的防破解手段,还有更夸张的,我只是找到了一个,这个我肯定算不出来的,所以我没法登录,这个网站还不是英文的,好象是俄罗斯的,俄罗斯人的数学很强,而且俄罗斯的黑客很强,也许是这个原因,他们要搞的更加夸张一些。
    这是一个很沉重的话题,今天我们演讲当中,我会在这一页涉及这个沉重的话题,如何保障用户的密码安全?绝对绝对不要明文保存密码。但是真的有很多公司这么干过或者还在干着。有很多原因,有一个原因是真的有人打电话过去问,把我的密码告诉我,你怎么能够不知道我的密码呢?有这样的用户。还有一些不可以往深里说的原因,让公司需要保存用户的密码。但是这样带来的安全隐患实在太大了。所以绝对不要这么干。简单的MD5也是不够的,我们把一个用户输的密码做一个MD5的计算,算出来一串支付串,这个在过去行地但是MD5因为有一堆的黑客,他们已经算出了很多常见密码的MD5,它会反向碰撞,然后来检测。仅仅做MD5会变得危险。所以我们需要加一串足够长的,而且有一定的可变性,不能就是那一串,必须加点别的,比如说时间,比如说用户名,或者是一些可变的东西,加起来再做MD5,或者不用MD5,用一个SHA—256的一个算法来算。
    还有就是登录过程中最好走Activex协议,IE这个东西在windows平台有。其实我这个话题没有走完。好象所有的问题都跟密码有关,登录要输密码,忘记密码要找回,要保存的好,不要丢了,都跟密码有关。
    做到这些,觉得做登录太难了。其实登录与认证是两件事情。我知道你是谁,我能不能不通过验证密码的方式呢?能不能这边根本不保存密码,也不验证密码呢?对,我要让机器知道我叫庄表伟,但是我让机器相信这件事情,我找别人来证明,我自己不用证明。第三方认证是一个不错的选择。
    第一种技术,OpenID。我会讲三个技术,这些技术,我相信在座的大多数人都知道的,但是我要说一些大家都知道的东西,来让大家知道我也知道你们知道这些东西。这样我才能够在接下来讲一些你们可能还不知道的东西。openID是一个开放标准,而且特是一个去中心化的网上身份认证系统,它通常是一串表示一个人的名字,它主要的特点是开放,它是一个开放标准,谁都可以做,而且是分散的,没有一个中心的验证机制,它很自由,甚至自己有一台服务器,你也可以自己给自己架一个OpenID,最初是这个人开发的,但是后来有很多家大大小小的公司加进来。这些列出的都是大公司,他们开始支持OpenID。它到后面的发展并不顺利,它火过一阵,到后面越来越少的看到openID。
    现在讲讲它技术方面的东西。它有一些基本术语,比如说End user,就是那一串表明这个用户的标识。还有一个叫Identifier,其实就是身份提供者,这台服务器能够证明我的身份。还有就是Relying。
    这个网站将OpenID界面返回给我,我叫这个ID,它把我这台ID解析以后,发现提供者的域名在哪里哪里,然后跟身份提供者建立一个关联,然后请求健全,这个身份提供者会发一个密码的框给我,我输密码。在身份提供者接受密码以后,确认我是真的我,然后把这个消息告诉网站依赖方,这个就是一个简单的OpenID简单登录。
    但是为什么OpenID不成功?一个是它的长度过长了,不太方便。还有一个,OpenID太开放了,太自由了,一个公开的协议,都可以做OpenID服务。比如说我在A网站创建了一个自己的OpenID,我用这个OpenID登录别的网站,我发现A网站宕掉了,我就没法在其他的网站登录了。我怎么能够依赖这么不稳定的服务?另外一方面,我也可以给自己架一个OpenID,我自己维护的好好的,保证它不宕机,但是这个门槛太高了。大多数网站对于OpenID的支持,说到底还是半信半疑的,不是很坚决的支持,他们还有自己的用户系统。还有一个就是OAUTH的兴起,这个当中有一些比较重要的区别。
    我这个是突发奇想,我自己做PPT的时候,做到这里的时候,我就想另外搞个OpenID,也许可以,也许有人这么干过的,就是基于电子邮件的OpenID,它发一个链接给我,点这个链接就相当于登录了。也许可以,就是时效性差一点。当然也可以换一个办法,输手机号,它给我一个短信,里面有一串验证码,当密码用也可以用。这个都相当于OpenID。
    还有一个区别,就是认证与授权的区别。OpenID关注的是Outhentication,意思是证明是谁。还有OAUTH关注的是OUTHORIZATION,意思是授权,判断这个用户能够做什么。它可以访问,但是它无需用户提供用户命名给第三方的应用,这是一个安全性提高的方面。它的发展历史大概是这样的,OAuth开始于2006年11月,当时一个人正在开发一个Twitter的OpenID实现,发现Twitter要的OpenID不够用了,他想自己另外做一个。他找了一伙人开始讨论,起草了一些规范。然后草案发布什么什么的。这个草案开始纳入了IETF的规范。2010年4月他发表了一个非正式的IFC。这个历程,这是一个比较常见的在国外一个标准成形的过程。我认为这个很值得我们借鉴。
    OAuth的基本术语大概有这么一些,一个是服务提供方。服务提供方,比如说我用新浪微博登录某个网站,比如说A网站,服务提供方可以算是新浪微博。用户还是我。客户端,就是我想登录的那个A网站,大概是这样的一个基本术语。下面还是以简单的画面的形式来展示一下。我访问客户端网站,客户端网站到服务提供方请求一个Repuest Token,首先需要向服务提供方证明自己了一个合法的OAuth使用者,服务提供方会授予一个临时的令牌,客户端获得临时令牌以后,它会传一个指令给这个用户,让用户访问服务提供方。服务提供方会传回来一个让你填密码的一个框,让这个用户选择是否授某些权限给这些客户端网站。最后客户端网站根据这个带回来的一些参数,它会形成一个请求,用这个请求去到服务提供方获得一个访问令牌,拿到了这个令牌以后,他可以不断地到服务提供方那边去请求各种资源,比如说访问好友列表,帮你发言等等。这个请求令牌有各种区别,有一些有时限,有一些没有时限。
    刚才说的属于2.0,OAuth2.0是最近提出的一个新版本,这个版本目前还没有正式成立,但是有一些公司抢先开始支持OAuth2.0了。原因是OAuth1.0不够好,一个是签名逻辑过于复杂。这个签名,那个签名,要保证参数不会被破解等等,要加什么K之类的,对于开发者来说太累,但是我觉得开发者也太骄气了。有一个东西帮你签掉了,还觉得对开发者不够友好。还有就是授权过程太过单一,刚才进的过程是web应用,如果对于桌面应用,这样一个OAuth1.0很麻烦。手机上的应用,它会在手机上一弹,转到手机浏览器,然后完成授权再转到手机应用上,这个太不像一个应用了。完全是依赖于外部一个完全不可控的另外一个浏览器。
    OAuth有这样一个改变,一个是把签名去掉了,改用HTTPS来传输。它还分了两个角色,刚才看到的服务提供方,现在它把服务提供方一分为二,一个是用来提供服务的,一个是用来验证用户授权的。它是两件事情。所以分成了四个角色,剩下两个还是没有变。它会针对不同情况使用不同的授权流程,像刚才我们考虑到的那种web应用之外的桌面应用,它会有一些别的流程,这个就不细说了,细说的话也是一个很大的话题。
    第三个技术,来自于另外一个需求,其实也是人的惰性,我在这个网站登录了,我到那个网站能不能不登录,这种懒惰,这种惰性逼着我们程序员开发一些新的技术。能不能完全不用登录,每天只登录一次?如果有那么几个网站,他们背后是同一个开发者,我登录你这家,你跟他认识,所以他也信你,所以我到他那边去也不用登录。所以有一个新技术叫SSO。它是身份管理与认证系统,最初是出现在企业应用环境中,后来才在互联网应用中逐步普及。
    现在互联网公司越来越多的采用SSO。它有以下六种实现技术,但是我不打算细讲,基于经纪人,基于代理的等等,每一个都可以再画一堆的流程图。现在讲一个比较基本的版本,它有一些基本的术语,User,通常还是我。然后提供服务的网站,还有一个是身份提供者,就是第三方认证的保证SSO能够得以成功的那台服务器。
    典型的SSO过程是这样的,我访问网站1,网站1说你到登录服务器去登录,获得登录认证以后,我再去访问网站1,网站1就认你了。如果再去访问网站2,网站2说先问问登录服务器,如果你已经登录过,我给你提供服务。就是这么简单。如果用户在网站2的时候退出这个网站,这个网站2要多做一步,他不但要在自己的网站做退出,而且还要让登录服务器知道用户退出了。这个用户再访问其他网站也是一个退出状态,这个基本上就是SSO的基本涵义。前面已知的部分我会说的快一些。
    我还是想讲一些我自己想的东西。又要谈到需求,需求是怎么来的?是时代不断进步,不断发展而产生新的需求。社交网络的崛起,现在已经有很多的巨头,在国外有Facebook,有Twitter等等这样的网站,在国内有新浪微博,有腾讯微博,有人人,有搜狐,他们崛起了以后,很多人多多少少都会有这样的一些帐号。第二个,移动的时代来临了,智能手机、平板,带来了更多的需求。人们更不愿意登录了,因为登录在电脑上有一个键盘,在手机上比较烦,不愿意输。还有一件事,用户越来越刁了,但是在谈论用户体验,什么叫用户体验?不就是懒嘛,不就是怕麻烦嘛,人家叫用户体验。还是我们累嘛,没有办法。大家都在谈论安全,安全要保证,不保证这个也很难看。还有大家在谈论隐私,好象都开始重视起来了,以前好象都不懂,现在懂了,反正也是被教育,有一些厂商会说安全很重要,隐私很重要,大家都谈论这个。
    所以在这样一个现实的社会,在现实的需求的情况下,如果我来设计一个登录的架构,我要考虑一些什么?先来一张大图,这张大图还会出现,所以不要紧。大概的意思,大家先看,中间的那个是我,左边的那些是帐号和设备,或者叫终端,右边的那些是身份和网站,我会一个一个的页面来解释。这张大图差不多能够表明我能够想设计系统的总的架构。我是谁?这里不讨论哲学问题,太复杂了。我是那个在电脑、手机、ipad或者是什么什么设备后面的操作者,我曾经注册过很多帐号,我曾经还给自己起过很多名字、外号和昵称,我访问了很多网站,使用了很多服务,我同时拥有手机不只一部,我的记忆力在日渐衰退,我的惰性在日渐增加。所以我在那个中间。
    什么是帐号?我已经注册了太多的帐号。我个人最常用的帐号有以下这些,这是真实的,大家可以通过这个方式找到我,也希望通过这个方式跟我继续探讨关于登录的这些话题,如果这个PPT放出去以后,我期待结识更多的朋友。我只需要记着这几个帐号就够了,再不要更多了。事实上我至少在上百个网站注册过帐号,我是一个互联网的众多用户,凡是有新的服务出来,我都会注册一个试试看,因为注册新的,所以我不会创建密码,这些密码都一样。去年密码泄露以后,我非常被动,我在网站上下密码库一查,真的有我的。我花了两到三天的时间改密码,那叫一个郁闷。我在太多的网站有同一个密码,那个密码都不用了。
    终端。任何可以用来访问网络的软件都是一个终端。任何平台上面的浏览器,无论是手机的,还是电脑的,还是平板的,手机app,平板app,这都是一个终端。浏览器最方便的登录帐号是什么?是借助一个已经登录过的帐号,比如说另外开的窗口已经登录了新浪微博,我现在再登录第二个网站的时候,我就用新浪网站登录,因为我这边已经登录过了,我这边点一下,用新浪帐号登录就可以了。手机上最方便的登录帐号是什么?手机号码,我什么都不用输,只是发一个短信给我就可以了。在各种桌面客户端与APP登录只是麻烦的事情,如果只登录一次,以后就不用再登录就好了,APP不会有那么多打开的事情,所以只登录一次就好。
    再来回顾这张大图,我希望能够做到的效果是,我无论在哪个终端,无论用哪个帐号登录,都证明是我,而且是同一个我。有一个系统能够记住这些事情,无论我在哪儿,用什么帐号,他都能够知道,都能够认得。
    身份,别名叫马甲,在网游里面叫角色。这是我们行走江湖常用的字号,有一些人习惯实名,有一些人习惯花名,不一定。我们还可以在一个网站里面注册多个马甲,以扮演不同的角色。有一些人自觉的在不同的网络使用同一个昵称,比如说我,我在任何一个地方都叫庄表伟,要么是拼音的庄表伟,要么是汉字的庄表伟。而且我的头像一致,ID一致。但是其实我在那么多网站,注册了不同的用户,我没有一个办法汇集自己的网络行踪。怎么说呢?有些身份其实是我愿意公开的,比如说在所有的技术社区都用的同一个名字,在不同的技术社区发过言,回答过问题,跟别人争吵过。我愿意公开这些部分,如果这些部分帮我汇集起来,别人就可以全面了解我在技术社区到底关注多少技术问题。但是有一些我不愿意。
    关于我,这是一种尝试,它最多是一个ISS的一个聚合。还有一个东西,这张大图里面提到过一个权限,因为我们越来越多的第三方登录会选择OAuth,不仅仅知道你是谁,还可以对你干些什么,因为你授权我了,不是乱来的那种。比如说你用Gamil登录,意味着我可以查看你的联系人,如果你授权。如果用Twitter和微博登录,我可以查看你的好友、粉丝。如果用这些帐号登录的话,这些权限相当于你授予给我了。而权限的赋予是由身份来决定的。我们来回顾这张大图,我用不同的身份登录不同的网站,跟身份绑定的是不同的授权,也就是说当我以身份1,是一个技术人的身份去访问那些技术类网站的时候,我可能会愿意它绑定我的新浪微博,凡是我在人家那边回答过的技术问题,都可以帮我同步到微博去,挺好的。但是我用另外一个身份,比如说我打游戏,我作游戏里面跟人家PK,或者在游戏论坛里面跟人家打的你死我活,这是另外一个名字,我不希望这些东西弄到微博上。这是另外一个授权。
    所以网站与服务,右边的这些,他们所面对的是我的某一个身份,以及身份背后所代表的权限,而不是那个我。那个我对他们来说是不公开的。网站面对的是某个身份。SSO,刚才我们谈到的那个只登录一次的需求,在我的这个系统里面不是跟着身份走的,而是跟着我是否登录来走的。一旦我登录,我的每一个身份都登录了,只不过我去访问不同的网站,可能会切换不同的身份。也许有这样的一种情况,我有一个身份1和身份2同时会访问这个网站3,那么当我到网站3的时候,也许我要选一选我到底哪个身份网站3出现,或者在网站3上面先用身份1发言,然后再换一个身份,用身份2发言,我有这样一种很奇怪的需求。
    而用户的成长是记录在这些身份上的,我不知道大家是不是玩网游?如果我们玩网游的话,我们会在某一个游戏里面创建一个角色,我们用这个角色去行走江湖,去砍砍杀杀,去打怪升级,我的成长记录在这个角色上,也记录在这个身份上。而网站的信息想要借助SNS网络,则需要从身份入手。因此,我这个系统需要建立某种统一的消息与访问机制。同时,网站也有可能是资源的提供者,也就是说在这张大图里,右边的网站,有可能同时是左边的某一个帐号,如果我再把右边的划到左边,这个图就太复杂了。但是意思要讲清楚。
    接下来我要介绍的一个项目,就是我刚才这张大图,如果做出来,我想给它起个名字,叫Open SSO,这只是一个暂用名,这个名字挺怪的,不是很时尚的名字。为什么会想到做这个项目?有一些原因,我不是凭空想的。因为我们在做一些网站,我所在的创新院在做的一些网站,下面这三个网站都是跟开发者相关的,一个叫SNDACODE,还有一个叫TEAMHOST,还有一个网站叫OPENPK。我们就在想这三个网站,我都要做登录,这三个网站我面对的是同一群人,这三个网站如果说一个开发者他在这边参加比赛,在那边又参与开源项目,他能不能把他的成长记录在同一个身份下面?这是最初的设想。
    另外,我跟一个网站的创始人吕国宁做过一些深入的交流,当然可能是我在忽悠他,可能忽悠的没有这么细致。这是一个Ruby的社区,它本身是一个开源项目,它可以把原代码克隆出来,自己架一个社区,比如说叫ruby—台湾,有人就这么做,因此,我跟他说,如果你的这个开源项目能够支持第三方登录,能够有一个办法把你的技术社区全部打通,让那些开发者访问所有Ruby—中国的时候,让他们的成长记在一个身份上,对你的开发者来说该有多好,一下就高兴起来了。他说对啊。我是啊,你去做吧。
    然后吕国宁很愿意去做,他们公司有一个牛哥。这个包大概可以支持几十种以上的第三方登录,都可以支持。所以我跟吕国宁聊,我说搞一个吧,咱们一起来弄,我去盛大申请了一台云主机。他现在正在做这个项目。而且我们希望能够把这个项目除了完成登录认证SSO之外,我们还希望做更多。
    这个特性叫带tag的感性,来源于谷歌+1。它排什么用处?比如说在一个社区,你回答别人的问题,别人说你这个问题帮我回答的太好了,我要感谢你一下,我可以点击加1,感谢你。但是我们的感谢不是泛泛的感谢,我们有指向。比如说你帮我解决了一个C++的问题,我感谢你的是C++方面的帮助。当我点完加1以后,会有个浮动层,让我现在tag,或者是自己输入tag。因为这个用户它是以同一个身份跨越多个网站。因此他可以在多个网站收到不同的感谢,在不同的地方收集到各种感谢。
    所以,我们能够把这些感谢汇集起来,变成一个更好的关于我。我在社区有多活跃,我收到这么多的感谢,每个感谢点回去都可以知道是谁在什么问题上因为什么原因感谢我。比如说我在一个开源社区,我提交了一个东西,开源项目的作这感谢我。我在一个问答社区回答了一个Rails的问题,别人又感谢我。因此这些感谢全部可以汇集起来,这些感谢就是一个很好的自我介绍。我们可以做成一个柱状图,这个柱状图表示每项能力有多少,也许将来这个是一份更好的求职简历。
    因为我关于架构方面的东西,基本上已经说完成了,因为这个设想还没有做出来,所以只能说设想,还不能给大家看到真实的东西。昨天晚上写今天的演讲自我介绍,我说大家很希望听干货,不希望听水货,希望一个演讲里面的干货多一些,但是我这个只能叫鲜货,还不能叫干货。我这个是新鲜的,刚刚出来的,还在想的一些东西。所以属于鲜货。想闲聊几句关于架构的问题,我在创新院内部跟同事聊天,他也是一个非常资深的技术同事,我全部说完,他的评价是什么?他说庄表伟,你是一个非常优秀的产品经理。但是你说的这个东西不是架构。我说好吧。这其实是刚才我上面说的都是产品设计,听上去就是产品。当然这个产品,做产品设计的人估计是设计不出来的,因为他需要太多的技术上面的理解,他才能够设计出这样一个产品来。而我想说的是什么?我想说的是,一个好的架构,从根本上来说,它首先是来源于需求的,没有凭空而来的优秀架构,一定是来自于需求的,从需求来提炼,来总结,然后再考虑各种技术因素以后的架构。
    另外,还要考虑到架构设计的一个,我刚才说的最多算一部概念车,因为它还没有出来,它从可以跑到可以真实的在生产环境中应用,那可能算是量产车,当中有太多太多的细节要考虑。而这些细节,它必须要求架构师自己去也代码,所以我忽悠吕国宁写代码的方法是错误的。我应该自己去写。因为我跟他关系很好,而且那台服务器,我也可以登录,所以我们一块来写,我回去会做这个事情,我不应该让他一个人把这个活干掉,这个不厚道,同时对这个架构也不负责任。关于架构或者说架构设计,这是一些感想。
    还有一个感想是关于标准的。OpenID都是开放标准,我们能不能搞一个?我们国内开发者没有搞过什么标准。我们一直以来都是标准的学习者、使用者,最多最多是参与讨论,我们能不能变成是标准的创造者?老外是怎么干的?他们第一件事情,先开源。第二,开放。第三,不同的公司,不同的利益团体,不同的人,坐下来先讨论,先写文章,先写草案,然后把这个东西写出来。然后用不断商讨的办法去推动这些标准被尽可能多的厂商接受。
    我最近在看一本书,叫《罗伯特议事规则》,讲的就是一个委员会如何坐下来开会,如何把会给开的有进展,能够通过讨论得出一些有价值的结论。下面两个例子,是我来之前,在16号的时候,我17号到北京,我16号有朋友看了这个PPT的草稿,然后发给我链接,说有人做类似的东西了。当时我心里一凉,我还以为这个东西只有我一个人在想,然后我就去看了看,这两个都有地址,大家也可以去看,这里面就不细介绍了。
    但是我想说的是,其实国外有人在思考同样的东西。OpenID,这个也是现在的草案,它也是一组思考,跟我说的SSO有接近的地方,但是也有区别的地方。他们的做法就是把草案先写出来,然后大家来讨论,可能会做一个参考实现,然后开源,然后再怎么怎么样。这样的事情有没有在国内做出一两件来?我是要求主动来讲,我想讲讲我还没有做出来的东西,我希望能够做出一些开放的事情来,做出一些协作的事情来,做出一些大家吵架,最后把一个东西做成的事情来,能够打破一些隔阂,能够跨过一些利益上的障碍,大家一起来做一点事情,也许会有一个更加开放的、更加美好的未来。谢谢大家。
    提问:其实我是来自多说网的技术人员,我们已经在国内做了一个实现出来,我们做的是未来支持的各种通用版网页里面插入一个代码就可以实现评论的工具。在这些网站里面,只要登录一次,比如说社交上登录一次,就可以在所有的支持网页里面做评论。我们也支持登录之后,你的网站也登录,但是中间遇到了非常多这方面的思考,我们之后可以一起分享一下。
    庄表伟:太好了,我发现不是只有一个人在想事情,有很多人在想类似的事情。
    提问:国外有很多个产品已经上线了,有一个网站,它在很多技术社区都在使用,就是在您的概念叫SSO的东西。
    池建强:感谢庄表伟。
    
    池建强:今天最后一场演讲马上要开始了。最后一个演讲来自腾讯的大项目经理马明给我们带来腾讯社区搜索架构的优化演进。腾讯总是有很多事情,看看马明今天能够给我们带来哪些精彩的演讲。
    马明:谢谢。首先感谢大家冒着万神吃饭排队的风险来参加我这个分享。谢谢大家。
    我今天分享主要是来给大家分享一下我们腾讯的社区搜索的一个架构演进过程。腾讯社区搜索主要有几个产品,像Qzone搜索、微博搜索、还有手机上无线的社交搜索。这几个搜索,目前我们使用一个统一的架构在开放。
    这是我的一个个人简介,目前我主要负责腾讯社区搜索的项目管理工作。今天分享的主要内容有以下几点,首先简单介绍一下我理解的社区搜索的一个基本概念。接下来重点讲腾讯社区搜索架构和演进以及演进过程中遇到的问题,以及新架构是如何解决的。最后给大家讲一下未来的一个演进发展方向。
    大家所熟悉的搜索引擎可能是这些,谷歌、百度以及soso。随着近年来社交搜索网站的兴起,像国外的Twitter、Facebook,以及国内近两年微博的兴起,以及涉及网站像人人这种。搜索的社交化成为一个发展趋势。因为我们社区的产品,它产生的资源有以下几个特征:首先内容非常丰富。像Facebook网站,它的注册用户数现在已经达到了8.5亿。它有8.5亿的用户为它分享上传资源,而且资源传统的搜索引擎得不到。微博搜索是一个更明显的特征,前段时间发生了一些政治事件,在网页上得不到这种消息,可能只能在微博上搜索,当然在屏蔽之间是可以搜索的到的。
    首先看一下文字上的直观定义。这是一个百科上的定义,因为目前没有一个标准的定义。社区搜索,是以海量的社区资源为信息基础,组织起来的一个搜索引擎。我们认为它是搜索的一个进化过程。为什么这么说?因为所有的这种社区资源,它通常存在一个问题,它不是开放的。即使现在像百度搜索,已经把微博的内容集成到网页搜索里面,但是它的时效性不够。
    下面通过腾讯的Qzone搜索来说一下社区搜索的几个关键特征。第一点就是它的关系链。这是我在写PPT之前搜索的一个例子,搜索北京,前面会把我在北京的关系链信息优先展现出来,比如说我在北京的同学、好友,他在北京工作,这些信息首先优先展示出来。第二部分,好友发表的关于北京的相关文章,在个人关系链后面会展现出来。第二,它的一个时效性的特征。微博搜索现在可以达到秒级的实时检索。你发生了一个热点事件,有人发表了关于这个事件的文章或者是评论,我通过社区搜索马上可以检索到,因为它是一个内部封闭的一个论坛,这种网页抓取其实是实时抓取的。第三个特征,综合它的个性化,整个网页是体现了一个个性化的一个搜索,每个人的搜索可能不一样。你的关系链跟我的关系链肯定不一样,我们搜索同样的关键词,反馈给的结果肯定不一样。
    我们认为社区搜索关键特征,第一个就是关系链。第三个就是时效性。第二个就是个性化。社区搜索架构演进也是围绕这三个关键特征来发展的。接下来给大家介绍一下腾讯社区搜索平台如何支持这种个性化搜索的。
    整个社区搜索的一个架构演进,目前是有三个阶段。第一个阶段在07年。当时的需求比较简单,就是想做一个论坛内部的搜索。其实跟网页搜索没有什么区别,只是把论坛的资源,搜索一个关键字可以检索出来。当时第一代搜索架构就是基于这种传统的网页搜索发展起来的。简单地说它就是一个博客搜索。在09年的时候,随着社区化的发展越来越明显,我们这种基于传统网页的搜索已经无法满足需求了,我们需要引入这种个性化,我们要满足社区搜索的关键特征。09年我们第二代架构上线,主要的一个特点就是基于横向复用的。11年的时候,第三代架构上线,它主要满足快速响应的需求。09年的机构还是基于传统网页基础上发展的,所以它存在很多限制。就是说社区搜索和传统网页搜索,其实需求不一样,社区搜索,产品需求变化很多,传统网页追求的是搜索的准确性、相关性,搜索一个结果只要把有用的结果反馈出来就可以。但是社区搜索更多围绕关系链产生的,说白了就是人的圈子。在11年的时候,第三代架构上线。
    整个搜索架构的演进过程,说白了就是随着需求的不同变化而不断演进。我们目前在考虑第四代的一个架构。
    接下来给大家介绍一下1.0架构的一些特点,还有1.0架构遇到的一些问题。1.0架构在09年开始启动,但是当时引入背景比较简单,就是要做出一个体现社区化的一个搜索引擎,我们必须引入关系链。在Qzone里面关系链很明显,就是QQ号、QQ好友,我们要把这些信息引到社区搜索引擎里面去。当时开发团队6个人,工期要求比较紧张,要求三个月上线。所以很多的细节,在架构设计的时候是没有考虑清楚的,这也导致我们1.0架构有一些约束和限制。
    这是1.0架构的一个总体架构图。首先它是一个分层比较明显的一个架构。从上面这三来看,这是一个在线处理的过程,用户输入一个关键词,通过检索模块来处理,是前面三层来处理的。它是一个在线处理的过程,后面这三层,传统的传统网页也存在,通过数据抓取、倒排、顺排,然后做一定的排序,存到我的集群里。这个属于离线处理的部分。
    看一下这个架构是如何支持社区搜索的三个关键特征。首先是关系链,关系链在检索处理层体现,用户输入,因为在Qzone社区搜索,本身就带着QQ号信息,存储集群里面存了你的关系链信息,我会把你的关系链信息查到之后,再检索处理层进行处理。这个就体现了我们一个关系链处理的过程。另外一个是时效性的处理,大家如果做过网页搜索的话,可能比较清楚。因为网页搜索信息量非常大,假如说你做一次全量的顺排、倒排,可能需要几天的时间,因为中文网页量大约是几千亿,我们Qzone社区搜索的文本量也是很大的,大约是几百亿的流量,做一次全量的顺排、倒排,大约需要两到三个小时,这样无法满足时效性的需求。比如说当前发生了一个热点事件,你要马上搜索到,你两个小时才能把它弄到索引里面。这个时效性不好。我们在存储层做了一个特殊处理。使用内存存储来做一个小型的存储库,我们在内存里面保存两天的一个最新数据。这样我可以做到在分钟级别内顺排、倒排,这样它的时效性好很多,这个就是小库和大库的概念。
    整个1.0架构,其实是一个基于横向复用、数据统一存储的架构。为什么这么说?我们所有的数据其实是统一存储的,没有区分业务,Qzone社区搜索有很多业务,比如说关系链查找,这个其实要带你的好友信息。另外有一些认证空间的专家数据查找,还有一些个人数据的这种查找,比如说刚发表了日志,我想查出来,我们没有区分业务。另外业务处理也是没有按照业务进行区分的,都是一个层次的支持所有的业务逻辑处理。
    这其实也是1.0架构的一个特点,也可以说是它的缺点。接下来介绍几个1.0架构的关键技术。首先是关系链处理,其实关系链处理在社区搜索里面是贯穿整个搜索流程的,首先看离线处理的部分,你平时新增QQ号、删除QQ号,你的关系链会变化,在线处理部分,是整个的搜索检索过程。举一个例子,比如说你搜索的是北京旅游景点,QQ号是12356,它的处理过程是什么样?首先检索代理模块,会去关系链索引库里面查找相关信息,然后代理模块会做一个初步的检索识别。比如说北京旅游景点,认为查找的是旅游类相关的信息,但是这个检索意图识别是对非常明显的词,会区分这种比较明显的检索词。第四步,检索代理模块,会把你的关系链信息和你的这种检索意图带给检索集群。这里面有一个分发机制的问题,我们1.0架构是基于传统网页的架构产生的,我们的分发机制没有做改变,它的分发是基于ID做分发的,这样其实有一个问题的,第四步检索处理的时候,我无法知道用户关系链相关的数据存在哪个集群,所以我没有办法,只能向所有的集群进行分发,这样会带来一个效率的问题。
    检索集群处理完以后,会把结果返回给检索代理模块,它会做一个默认处理,然后反馈节用户。整个检索处理过程是这样的。关系链处理是贯穿始终的。
    1.0架构另外一个特点,就是高排重。如果大家平时使用社区有一个印象,很多文章,比如说搜到一个文章,我比较感兴趣,摁一个按纽,然后就变成我的转载,转载文章比例非常高,做了一个统计,1:5左右。我们利用这个特点,我们1.0架构做了一个排重处理,如果我认为你两篇文章是重复的,我在存储集群里面存储一篇文章,我会把差别信息做出来,比如说QQ号、ID号等等。做了这种处理之后,我们存储的空间可以节省大约80%。
    1.0架构另外一个特点就是高复用。数据是统一存储的,业务逻辑处理在每个横向上也是统一处理的,没有区分业务。
    1.0架构经过三个月的开发上线以后,产品的数据表现相当不错,首先PV、UV不断上升,最终在上线的出了问题前一周,我们日均PV可以达到6000万,日均UV达1500万。这种数据表现,大家感觉还是很美好的,当时我们觉得搜索,也体现了搜索社区搜索的个性化需求,数据表现也不断上升,线上表现也很稳定,当时1.0架构上线了半年,基本上没有出现一起网上事故,大家准备庆祝一下,大家知道腾讯有旅游文化,我们准备申请公款去旅游,结果在旅游前出问题了。首先用户不满意了,在一段时间内PV、UV出现明显的下降。主要的问题两个,第一个是刚发表的日志怎么检索不到,我在空间里发表一篇日志,但是我搜索日志的关键词搜索不了。第二个主要问题,搜索结果太烂了,这个文章里没有这个词,结果你给我返回回来,这个问题经过开发定位,也定位了比较长的时间,修复起来非常困难,在1.0架构的基础上想修复这两个问题比较难。第二个问题,我们的产品经理不满意了,当时我们开发结构是一个月一个迭代,他们一个版本上线需要一个月到两个月的时间,产品需求至少一个月以后才能响应。为什么这样?1.0架构横向复用带来的问题,局部调整影响了全局。
    很明显,我们的开发周期是跟不上产品的一个节奏的。第三个问题,因为1.0架构基本上是社交搜索的一个雏形,社交搜索很多的个性化需求,产品经理不断提。但是我们在1.0架构上进行添加比较困难,比如说想增加名人数据,大家用微博,有很多的实名认证,他们发表的文章也好,或者是评论也好,或者是微博也好,我们觉得都很权威,我想把他的结果优先展示出来,比如说搜QCon,比如说在座的各位专家的言论,我觉得对优先,我想把搜索结果排名靠前,但是这个无法做到。因为我们的数据统一存储,1.0架构大家也看到了。
    另外,我想把我们的说说的排序规则改变,说说其实跟微博差不多是一个东西。其实它的时效性要求比较高,我想按照时间的这种顺序进行排序,但是这个也是比较难做到的。产品提交的一些需求,我们开发评估之后都觉得比较难做到,我们修改起来难度非常大。
    下面我为大家分析一下为什么。总的来说,我们1.0的架构还没有脱离这种传统网页搜索的框架约束。因为它基本上,我们1.0架构只是在网页搜索基础上的关系链的处理。这样很多网页搜索,为网页搜索而设计的这种框架,我们是没有进行修改的。整个来说,不够敏捷化。因为网页搜索,它的个性化需求没有那么多,它可能追求的就是一个搜索准确性、相关性。
    第一个问题,导致的原因是什么?复用带来的限制,前面的架构图大家可以看到,每层的复用非常高,数据存储也是复用,又做了排重,每个层次之间的联系也是通过接口实现的。所以说这种个性化的需求比较难以满足。比如说我想对个人数据管理的时效性做特殊处理,这个是用户反馈的一个比较大的问题,刚发表的日志搜不到。我们当时有一个方案,我们想对这种用户的个人日志做一种实时拉取,搜你空间的日志,我直接去QQ空间把你的发表的日志实时拉取。但是由于数据统一存储,每层的架构又统一复用,想增加这个比较难。第二,我们想对名人搜索的特殊排序,这个也无法做到。
    第二个问题,也是我们当时1.0设计引以为荣的一个机制,其实反过来正是我们1.0架构的一个大问题。排重导致搜索结果准确度差。这个只是在特定的搜索场景里才会出现。我们讲一下这个例子,假如说一篇日志发表完了,上面第一文章是ID001的文章,下面ID002的文章是我的一个朋友发表的,文章内容大体相似,但是就是有几个词不一样,经过我们的排重算法处理以后,我们会认为这两文章是重复的。因为排重算法不会对一篇文章做百分之百的排重,我们只是做一个相似度的计算,达到了一定的阈值,我们就认为这两文章重复。很多转载文章,可能会加一个什么转,肯定基本上内容一样,我认为完全一样。这样我们存储里会出现这种情况,只保存了第一篇文章,我发表的这篇文章,腾讯社区搜索什么的。但是去好友空间里面搜腾讯这个关键词,这个时候会把他这篇没有腾讯相关字样的这篇文章搜索出来,在腾讯搜索空间,这两篇文章是重复的。只是把好友的QQ号存储下来了。这样导致搜索的准确性很差。
    因此,我们1.0架构需要改变。整体的思路,我们需要一个灵活快速响应的架构。首先是需求开发周期长,我们把业务做了拆分,比如说个人数据管理、名人检索、关系链处理,把业务处理进行拆分。无法支持这种个性化需求,我把数据进行拆分,比如说把关系单独存储,把名人检索单独存储,每种业务可以做单独的处理,总体2.0架构设计初衷就是做纵向的拆分。
    其实这个思路产生之处遇到了很大的挑战,为什么?因为大家可以看到,我1.0的这种架构复用会节省机器成本。排重可以节省空间80%,如果做纵向拆分之后,每组数据都独立出来,其实之中数据之间有重复,关系链数据是一个全局的数据,因为每个人的好友信息,你建索引之初是不知道的。另外名人数据涵盖在关系链数据里面,还有其他的数据,比如说个人数据等等,这些数据都是重复的。
    另外1.0架构有一个排重的问题,2.0架构不想排重,这样节省不了20%的空间怎么办?在1.0架构讨论初期,这种PK是不断的,但是大家讨论讨论,也感觉没有别的好的办法。最终决定我们放弃成本。这样2.0架构就是在这种争议的讨论中上线了。
    我们2.0架构,对于这种核心业务处理做了纵向拆分,首先关系链数据做了单独存储,名人数据也做了单独存储以及个人数据。核心业务逻辑处理也做了纵向拆分。2.0架构如何体现设计搜索的三个关键特征?第一点关系链,这样在2.0架构里,只是这一部分处理关系链数据了,把关系链处理逻辑独立出来。第二个时效性没有变,采用二级存储架构,整个的个性化是一样的。所以这种2.0的最关键,做了一个纵向拆分的检索架构。
    下面简单介绍一下2.0一些关键技术,因为2.0做了纵向拆分,所以很多数据搜索能够应用的一些技术是可以使用的。大家可以看到前面把名人数据独立出来,那么我们利用这种专家挖掘技术,这个原理也比较简单。大家知道Qzone空间里的关系链就是你的用户QQ好友关系,每个用户可能有好多的好友,也可以关注很多人。我们认为你是某领域的牛人,你关注的人,至少跟你这个领域是相关的。
    我们看一下这个例子,假如说第一个用户是A领域的专家,我们设置A领域的权值是100,他又有两个好友,比如说用户2和用户4,用户2和用户4评分它的权值,每个得到50。用户3也关注了用户2,用户3A领域的权值是12他分享给用户2的权值,这样下来,用户2在A领域的权值关系是54。这样一个处理过程在系统内循环,这样我们设定一个阈值,这样会把某个领域的专家挖掘出来,大于50的都认为是某的领域的专家,或者至少你是这个领域的人。
    这样我们把这种挖掘出来的信息利用在搜索结果里面,通过一定的检索意图识别,比如说刚才那个例子,我们搜索的是北京旅游景点,我认为你是旅游相关的信息,那么我会把系统认证的这种旅游专家的结果优先展示出来,这样搜索结果会好看一些。另外就是相关性可能会很大,因为领域专家发表的文章,通常和你这个领域相关性非常大。
    第二个关键技术是QQ分发的技术。刚才介绍了1.0架构没有做这种关系链QQ号的分发,它是基于文本的分发。2.0改变的1.0架构的一个约束,把它检索集群分发机制改成QQ号。这样带来的好处是什么?比如说检索关系链处理,一个用户的关系链就是一系列的QQ号,1.0是向所有的检索集群发检索请求,查一下关键字,再匹配QQ,有没有你的关系链信息。这样有很多问题。我们改成这种QQ号分发之后,其实就是每个检索集群处理一定的QQ号段,这个用户只有10个QQ好友,我们只向一个检索集群进行分发,这个检索集群处理这个检索请求。这样检索效率提升的比较大。因为我们的检索集群,整个大约有200台左右,向所有的200台进行分发,而且这种丢是并行计算的,它同时处理希望的检索请求,这样系统内部性能消耗比较大。
    2.0改成QQ号分发以后,单机计算性能提高了200%。这个解决了前面争议比较大的问题,当时1.0的单机索引量在1亿左右,但是单台机器的性能达不到1亿数据的检索要求。当时单机的性能在500个,如果支持1亿数据检索,一定要达到2000到2500这种性能要求才可以。但是1.0架构我们无法做到这种,所以我们采取了一个机器复制的方式,比如说我通过四台机器并发来提高整体的性能,这样同一份数据复制了四份。整体机器成本也上升了,但是2.0通过这种性能提升,1亿的数据可以通过一台机器可以达到这种检索请求的要求。这样综合来说,我们当时PK的成本上升的问题,在这里得到了缓解。
    2.0架构的另外一个特点,纵向拆分。大家可以通过前面的架构图可以看到,整体的业务逻辑都是独立处理的,首先关系链检索系统、名人检索系统都进行了独立的业务逻辑拆分。各种数据也分开了独立存储。这样带来的好处,我想对每个业务做一些特殊的需求处理,其实是很容易做到的。比如说你的关系链数据,其实就你的好友信息。我想把关系链数据的权值提高,那么只是改变关系链逻辑处理,如果想怕时效性增强,那么只对个人数据检索集群进行处理。整体纵向拆分带来业务处理的灵活性。
    第二个就是快速响应。对业务进行拆分之后,内部团队就可以形成一个一个的纵向的团队,每个特性可以独立做开发,开发周期最终达到两周一个迭代,发布节奏也变快。因为每个横向是可以并行处理的。
    2.0架构解决了1.0架构的问题,并且在拓展性和灵活性上有很大的提升。大家可以回顾一下1.0的一些问题,首先第一个,它的时效性差,这个是针对个人数据管理的。2.0架构把个人数据管理处理逻辑独立出来,我们做一个实时拉取的处理过程,可以达到秒级的检索。第二个问题,它的重复性差,排重导致的搜索结果不相关,我们在2.0架构里对关系链检索集群不进行排重处理,这样解决了1.0架构的问题。另外,它的开发周期的问题,我们通过纵向拆分,2.0的开发周期达到了两周。
    总结一下2.0架构取得的一些成绩。首先,需求响应的速度提高了,开发节奏快起来了,当时我们最快的时候是每周发布特性版本达到5个,每个特性都发布版本。第二点,产品的数据表现还是比较好的,PV目前可以接近1亿,UV达到2500万。第三点,运维上的一个方便。各种业务独立部署,互不影响,原来是上线一个需求,那么大家都是临阵以待,各个业务模块集中在一起处理,大约两个小时才能完成一个版本上线。现在各个业务自己处理完自己上线,比如说关系链处理增加了业务,那么你自己上线,你也不影响我的业务,现在可以达到20分钟内完成部署。
    下面简单说一下1.0和2.0的架构对比。首先是单机性能2.0比1.0有很大的提升,因为我们做了纵向拆分,也做了基于QQ号的分发机制的改变。单机容量上没有大的变化,还是支持1亿的索引量。成本上,其实2.0架构经过性能优化之后,反而比1.0下降了大约30%左右。这里其实有一个矛盾和对立的过程,因为我们平时的思维感觉,我把一个架构做纵向拆分,肯定它的成本也好或者其他的方面,比如说这种代码的复用会下降很多,但是我们通过2.0的实践来看,纵向拆分非但没有造成成本上升,反而下降了。另外扩展性和严重性,2.0比1.0有很大的提升。特别是安全性,日志如果只对好友公开,那么别人搜索不到。但是1.0架构没有把这种关系链数据独立出来,这样处理一些权限的问题比较困难。很多只对好友公开的数据,我无法得到,因为我检索的时候可能不知道关系链信息。这样在1.0架构上,很多权限处理的过程,你假如说日志设置访问权限,那么所有人都检索不出来,只有你自己能够检索到。
    简单介绍一下整个架构演进过程中的一点心得。第一点,这种系统复用度高不一定是这个系统最优的解决方案。为什么?追求高复用,很可能有一定的背景,比如说人力限制也好,或者是成本限制。但是你虽然拿到了高复用,最终会造成一些约束和限制。
    第二点,系统拆分和系统横向复用,结合可能是架构最优的一个设计方案。这种系统拆分的架构设计方案,其实是当前比较流行的一个发展趋势,像Facebook也是这样处理的。
    另外,架构演化也是一个不断迭代的过程。其实互联网的很多架构,我觉得最开始可能无法一次把它想清楚,因为需求是不断变化的,如果最开始想设计一个大而全的架构,可能比较困难。总的来说,架构设计也要敏捷。
    最后介绍一下社区搜索平台未来的演进。首先要做一个公司内部的社区搜索平台,目前我们这个平台其实已经服务了几大社区,像微博、Qzone以及无线社交。
    第二点,我们会做一个开放式的平台,能够为外部论坛提供检索服务,比如说你想用QQ号的关系链来达到这种社交搜索的目的,我们提供这种检索服务。整个社区演进过程就是这样的。谢谢大家。
    提问:你好。我有一个小问题,刚才你提到在社区搜索实时检索的时候,采用的是拉取数据的方式来支持秒级的检索。
    马明:对。
    提问:拉取是指服务主动去获取?
    马明:假如说你搜索个人日志,我们只对个人日志检索做处理,你搜索个人空间里的日志,我们会向Qzone后台请求你发表的所有日志,这样可以把你刚发表的日志拉取回来。
    提问:这种方式可以说是应用频繁的拉取获取最新的数据?
    马明:对。如果访问量比较大无法做到,在Qzone空间里面做个人数据检索,PV访问量比较少,所以我们用了这种机制。
    提问:为什么不采用推送的方式来做?
    马明:就是空间不断的推送?
    提问:对,有新数据产生的时候不断推送。
    马明:这个对空间服务器要求比较高,要不断推送,一次全量的顺排、倒排也需要,大概需要10分钟左右,还是无法达到实时检索的要求。
    提问:刚刚听了你的讲座,最开始你们有一个统一的高复用的架构?后面看到演化的时候,它是统一的社区搜索,我想了解一下,最开始的复用没有统一,跟现在的统一有什么区别?
    马明:最开始针对的是一个,比如说Qzone社区搜索,针对一个业务的复用,后续是为各个不同的业务,比如说微博的搜索、Qzone搜索,你有自己的独立业务,你可以独立处理,提供一个平台接入不同的业务。
    提问:开始是代码复用还是什么复用?
    马明:Qzone社交搜索里面有很多不同的业务,比如说关系链处理,个人数据检索或者说名人检索。
    提问:你刚才说存储是在一个集群里面?
    马明:是的。
    提问:你的单机检索是一个亿?
    马明:对。
    提问:硬件配置是什么样的?
    马明:硬件用的都是S6的机器,基本上最高的那种配置。
    提问:比如说内存有多大?
    马明:内存应该是160G,其实就是这种机器的硬盘和内存是不匹配的。
    提问:内存特别大?
    马明:就是说CPU处理无法满足这种数据存储的要求。
    提问:看到你刚才讲社区搜索主要是个人搜索、关系链搜索、名人搜索这几块,但是如果它再提一个需求,比如说微博搜索里面,既不是自己发表的及也不是名人,也不是我的好友,但是我就想把它搜出来,比如说那个政治事件,我朋友没有提到,但是某些网友提到了,你需要对整个全网进行搜索,这样一个荚果,根据QQ分发的话……
    马明:我的检索集群,首先会做一个关系链的查找,这样会查找QQ号信息,比如说关键词匹配之后,再和关系链进行匹配。其次做不带关系的查询,这样会把非关系链查询结果反馈回来,然后把这两个结果反馈给用户。
    提问:好比你刚才举的例子,搜苹果的时候,数据是分开的,还有名人的,还有微博的,搜苹果,怎么知道是哪种东西?怎么查询的?
    马明:在搜索结果页里有这个选项。
    提问:如果没有选项的话,你怎么去识别?
    马明:默认是所有集群都分发,同一次搜索,既给搜索关系链数据,也给搜索名人数据,也搜索非关系链数据。
    提问:如果搜索的人想要苹果手机或者是苹果电脑,但是你给他显示的是吃的苹果出来。
    马明:这种比较难做到,目前也没有好的办法,相当于你要做一个用户的非常准确的一个用户画像,我认为你是IT人士,你比较热爱手机,你搜苹果就认为你搜苹果手机。我们系统没有做这个处理,只能说把苹果手机内容给你多一样,把吃的苹果权重调低一点。
    提问:就是做一个分类,选一个,再给他实际的一个结果?
    马明:对。
    提问:关系链的索引,它既然是索引,或者说是增量索引需要多长时间?
    马明:增量索引就是顺排,顺排比较快,倒排一次是全量的倒排,全量一次大概在两个小时左右。我们通常定时一次,可能10分钟做一次,10分钟发表文章,也就是万这个级别级别或者是千级别,这种比较快。
    提问:如果你顺排表10分钟建一次,10分钟之前刚好加了一个好友,这个好友发表了这篇文章,我想把这个文章搜出来,在顺排表里面搜不出来?
    马明:这个没有办法做到,这种情况,用户感知不会那么明显,你刚加了一个好友,你去搜索一个关键词,你可能不会关注好友发表了什么文章。
    提问:就是有10分钟的延迟?
    马明:对。但是微博我们可以做更实时的处理。
    提问:排重出现了一些问题,导致输入某个词,我们在2.0里面是怎么解决这个问题的?
    马明:在关系链数据库,因为纵向拆分,对关系链不做排重。这样带来的结果,它的存储空间不大,通过性能优化,相当于综合了这个处理。
    提问:2.0的架构和1.0的架构最大的特点是纵向切分,针对不同的应用,它是相互隔离开,避免相互之间影响。但是这样会不会有一个新的问题,每一个相当于子业务线,它有自己的特点,有自己的需求,不停地演进,它也会对架构提出新要求,这几个架构慢慢发展下去,它们互相之间出现一种各自一套独立的系统的情况?
    马明:因为我们只是把检索处理和存储做了拆分,像检索代理层和预处理层没有做拆分,还是合在一起的,是复用的。
    提问:需求会不会变?每一类需求都是不一样的。
    马明:随着发展,也是有可能的。
    提问:考虑到怎么解决这个问题了吗?
    马明:尽量把一些公用处理做到复用,个性化的处理可能还是局限到你的检索处理层去,不会把你的一些其他的特殊需求做到检索预处理层给你做一个特殊处理。
    提问:还是尽量考虑平台复用?
    马明:对。
    提问:关系链搜索那块,关系链这个关系的数据特点在顺排和倒排里面怎么体现的?
    马明:它有一个基于QQ号做一个顺排。
    提问:在倒排索引中,能不能具体说一下。
    马明:每个倒排会把关系链信息放进来,因为倒排、顺排都是基于文本的,我会有一个字段专门存QQ号信息。其实就是经过两次的一个交集,首先文本搜索,然后和关系链信息做一个交集,这样才能得到关系链数据。因为你的排序,所以会带来QQ号信息。
    提问:当你好友特别多的时候,我加了数百个好友,他的搜索条件会不会拼接的非常非常复杂,造成搜索效率比较差?
    马明:有成千上万好友的情况,这种搜索效率会下降的。
    提问:大概能够多大的好友范围内性能上能够容忍?
    马明:2000以内可以,我们可以做到秒级的这种,通常都是毫秒级的检索。
    池建强:再次感谢马明的精彩演讲。今天所有的日程到此结束。
    
   

4月19日 上午
主持人:大家好。昨天在微博上看到有的同学对昨天上午的主题演讲不是特别满意,我想说QCon的演讲比一天更好,大家听了今天的主题演讲之后,一定会跟我有同样的感受。接下来给大家介绍今天上午的三个主题演讲。今天上午第一个演讲是Joynet公司的Bryan Cantrill,他获得的成就包括华尔街日报和USENIX多个奖项。Node.js相信大家很了解了,目前Node.js火爆跟Bryan Cantrill大力的推广分不开。我相信Bryan Cantrill对系统深厚的开发功底,相信Bryan Cantrill能够给大家带来很多的启示。
    今天第二个演讲是Jason Brown带来的利用云技术实现Netflix快速规模化的增长。Jason Brown的演讲会告诉大家说怎么利用云平台实现Netflix的快速增长。Jason Brown带领的团队负责AB测试的基础架构,而且在亚马逊EC2平台上,使用Cassandra作为系统的生产数据库,现在是Cassandra项目的积极推广维护者。Jason Brown还获得了音乐创作硕士学位,而且最擅长弦乐四重奏。
    第三位演讲是来自于ThoughtWorks的首席咨询师Fabio Pereira。他的演讲题目是“敏捷软件开发怪诞行为学”。《怪诞行为学》,发表这个题目跟这本书有关系。认知心理学,包括行为经济学的发展,就是帮助大家去看待人类的一些怪诞的行为,会有一个更好的理解,包括在决策制定过程中的一些诱导效应等等。通过本演讲,听众将对一些敏捷价值观、原则和实践背后的前沿后果有更多的了解,从而对我们这些敏捷的实践者和应有者,也能更好地帮助我们了解如何在实际工作中应用他们。你要了解了一些驱动因素的话,你可以做的更好。我本人对这个演讲也非常期待。
    接下来把麦克风交给今天下午的四个主持人,首先是瑞友科技IT应用研究院副院长池建强,请他介绍。
    池建强:大家早上好。非常荣幸又一次来到QCon大会,在去年的四月份,也是在这个会议室,我主持了架构这样一个主题。去年我们的架构主题叫设计优良的架构,这个是去年的一个主题。今天我们想已经设计了优良架构,我们接下来做什么事情?在架构的主题里面,我们把它定义为优化你的架构设计。你在第一次版本里面设计了一个优良的架构,这个架构需要不断迭代,需要不断改进。所以我们在这次的架构设计里面,我们邀请到了五位演讲嘉宾,首先是Jason Brown,刚才已经做过介绍了,他给我们带来的演讲是将数据迁移到云平台上,这个也是Cassandra在Netflix中的应用。第二个演讲主题是两位演讲者一起来为大家做呈现,来自于Freewheel的赵晓锋和于冰。第三位是来自盛大创新院的国际研究院庄表伟,我们叫他老庄。在2011年在IT业界发生了很多安全事件,涉及到协议、用户数据、登录。在这个细节上我们看如何优化我们的设计。他为大家带来的是开放平台时代的登录系统设计。最后一位是来自腾讯的马明,高级项目经理,他给我们带来的是Qzone社区搜索架构的优化历程。什么样的搜索是社区搜索,这个需要马明来为我们回答,我们如何优化基于社区搜索的架构。我们下午在这个主会场,五位演讲者已经虚位以待,希望大家光临交流指导。
    主持人:接下来有请阿里云云手机开发者运营负责人鄢学鹍介绍。
    鄢学鹍:大家早上好。非常高兴能够给大家介绍一下HTMLL5和JavaScript这样的内容。今天从这几年前端领域发生了很多变化,最近几年大家讨论非常热的就是JavaScript这样的内容,从手机到Ipad,到电视,多终端,企业需要多个解决方案。另外一个梦想用同一个语言解决了用户的界面和程序实现问题。今天我跟大家一起来介绍这个话题,主要是我们所有的跨平台解决方案里面最重要的两个语言。我们一共为大家带来四位演讲嘉宾。第一位是来自豆瓣的石岩,他给大家主要介绍因为浏览器的发展导致出现一个问题,前几年在讨论一个很有意思的话题,Web已死,应用已生这样一个话题。今天石岩这个话题以豆瓣阅读器来讲,这是一个非常有意思的话题,昨天晚上在交流的时候,很多人问我,到底是做本地应用,开发安卓应用,还是做一个统一的应用。这是一个很有意思的话题。第二位是来自以前淘宝的玉伯,他现在在支付宝做整个前端的平台。玉伯在前端业界还是非常地活跃的,他在很多的会场讲了很多议题,今天他从一个非常小的角度,大家知道最近最流行的就是Pinterest,这里面有很多很有意思的解决方案,玉伯今天会跟大家一块来交流,我们通过小小的脚本看到它如何来处理整个世界的哲学。前端已经往自动化的方向发展,这里面不仅仅是写脚本,还涉及到整个流程的优化等等,会从整个专业化前端开发的角度跟大家探讨一些问题。第三位是来自腾讯的郑苏波,效率有两种效率,一个是开发者的效率,一个是应用的效率。他会拿腾讯目前已经做的,特别是在mobile领域很多的案例跟大家分享。最后一位是来自百度的吴多益,他是百度前端整体的技术负责人。我们看到很多前端的性能优化,我们讨论的加载层面最多,到今天随着浏览器的发展,随着各种各样技术的发展,我们讨论的是执行和渲染层面。这中间不能绕开的一个话题就是Node.js的解决器。非常期待大家到第一会议室来探讨前端移动积极性能方面的所有问题。谢谢大家。
    主持人:下一位主持人是某大型网站基础平台架构师曾宪杰。
    曾宪杰:首先很高兴,某大型网站是百度。我介绍一下会做分享的四个嘉宾,下午1点钟我会给大家带来一个分享,题目是大型系统的Java中间件实践。我希望通过这样一个分享跟大家去讲一下淘宝大概从07年底到最近Java中间件的一个过程,包括Java中间件部分的一些特点,还有遇到的一些问题和发展问题等等。接下来是来自易贝的祝文兵,他给大家带来的是ebay的分布式数据访问实践。对于易贝来讲,当时易贝有大型的互联网实践,我们学了很多东西。对于易贝分布式数据层我非常感兴趣,但是以前没有很好的机会近距离了解,今天下午对于我来讲是一个很好的机会,我也希望大家有兴趣的话可以过来多听一听,包括跟他做一个很深入的交流。第三位嘉宾是Chuk Munn Lee。他有超过20年软件开发经验,96年就接触Java的开发。他分享非常有激情,能够把技术和产品的细节讲的非常清晰,他这次会给我们带来的是web应用的开发和调试。这块主要围绕ADF框架跟大家做一个介绍,ADF是提供给开发者方便大家做G2E应用的框架。包括提到跟调试相关的部分。另外也会跟大家讲怎么样减少应用的资源消耗等等方面的内容。最后一位嘉宾是Bryan Cantrill,他技术非常强,获得了很多荣誉,他在今天下午给大家带来的是跟调试相关的内容,跟第三位嘉宾可能会站在不同的角度,会给大家带来不一样的内容。下午我们演讲主要是在第六会议室,期待下午大家的光临。谢谢。
    主持人:第四位主持人是张凯峰,是我们InfoQ的编辑。
    张凯峰:我给大家带来的主持内容是敏捷实践的秘密。这七年间对于敏捷的学习和讨论从来没有停止过,真正的民间践行者,他们已经不再谈论什么是敏捷,而是怎么做到在软件开发中消除、浪费,然后把软件质量提高到极致。今天四个演讲全部来自于一线的软件厂商。第一位是来自于上海贝尔的袁店明,他的主题是敏捷教练如何运用欣赏式探寻,他会分享来自真实团队的一次寻宝之旅的全过程以及经验的分享。第二位来自支付宝的廖光明,他主要从事持续集成、代码度量和单元测试框架,主题是持续集成之代码度量模型应用。他会讲支付宝系统的业务和需求在快速扩张的同时,如何保证复杂的系统是同时具有实时管控和高质量的代码。第三位是我的同事Fabio Pereira,他演讲的题目是浅度测试—可伸缩的TDD/BDD。第四位来自于诺基亚的秦之远,他的主题是3000万代码行敏捷项目的每日发布。这里面涉及到一个问题,当持续交付的期望和复杂的通信领域业务相结合的时候,之远和他的团队如何解决非常棘手的关于成本和分布式的诸多问题。值得一提的是,之远和他的团队,他们的工作在2011年获得过诺西杰出贡献奖。Fabio Pereira的演讲在第六会议室,其他的都在第七会议室。
    主持人:谢谢。我们InfoQ8月份深圳的全球架构师峰顶,这个也是三天大会,地点放在深圳的度假避暑圣地大梅沙。8月份看完海,10月份给大家提供公款去西湖旅游的机会,非常适合去看看印象西湖的表演。接下来有请Bryan Cantrill为我们带来演讲,题目是“Node.js用于数据密集型实时应用”。大家掌声欢迎。
    Bryan Cantrill:大家上午好。我是要戴上同传接收器,听听他们翻译的速度,我说话的速度很快,翻译听见我说话的速度,他们简直要白热化了。我要戴同传接收器,这样我就能够控制我说话的速度。
    在此之前,我讲的尽可能简单一些,我今天讲的话题是即时网络的话题。即时网络是一个什么意思?这个概念实际上已经出现了几年了,但是我觉得很多人对它还不理解。什么叫即时的系统?是一个什么概念呢?即时系统是非常简单的,这个系统是即时的,如果即时就不正确了,如果系统延时就会出错,这个就是即时网络。如果结果是致命的,对于整个系统来说,如果系统不能再往前进了,如果一个时限错过了,我们就把它称为是一个硬错误。如果时间非常重要,如果延迟的话,就会造成生命的丧失、财产的丧失,这是一个非常致命的问题。
    相反来说,如果你最后没有时限,没有造成致命的结果,只是说出了一些小错,给别人带来一些心烦的感觉,这就不是一个致命的错误。我们知道延时并不是致命的。
    因此,有一类东西叫软性的即时的系统。我们看到在网络上,以前过去的网络都是一些净内容,包括视频跟音频,还有文字的材料。你们这些人有谁打造过即时网络?或者说即时系统?请举手。可能人不是很多。你们有多少人建造过web的?我在这儿要跟你们讲,web本身正在改变。每一个举手的人,当我问你们是否要建造web的时候,你们将来都会碰上建造即时网页的时代的。好象多数都是软的即时网页,因此如果有错的话,也不知名。但是它也是即时网页,为什么有这个变化?因为终端和浏览器现在越来越强有力了,随着HTML5部署的越来越,因此客户端也越来越多的即时东西,还有移动设备,它们本身就是小的电脑。两种现象加起来,我们就需要建立更多的即时系统。因为不像过去那样的即时系统,你总是用物理的应用软件,但是在这块的即时网页上,数据都是即时的。我们一起来玩互动的移动的游戏,我们有这种动态的互动。你的数据发过来太晚的话,我们就没法玩了,这个会造成致命的错误。
    因此,数据变得即时性了。这种现象的出现,我觉得需要给它起一个名字,作为软件工程师,如果碰到重要的现象,我们给它一个简称。因此,我们就要建造一些书写词。我们现在有很多的书写词,然后又出现了CAP,它是过去10年理论的一个最终研究结果,如果你不知道CAP的话,就要好好学习。CAP告诉我们在一个分布式的系统里面,可获得性,还有耐受性,CAP是一个非常重要的理论。因为它会给实践者带来很好的好处,我们以前很愚蠢,我们觉得什么都能获得,这实际上是不可能的。CAP并不是因为它是一个缩略语,但是它确实是一个缩略语。
    我要给大家讲的是数据即时性的系统,它有缩略语,数据密集型的即时系统,形成了一个段语,变成了一个缩略语,叫DIRTy。因此,现在有一种新的DIRTy应用软件,它给我们带来一些新的挑战,有好的一面,也有坏的一面。在美国我们通常说你想听好消息,还是听坏消息。听好消息,好消息是最终实现是软的,最终我们会谈游戏、社交网站这些需要互动的东西。但是他们对安全并不是一个致命的东西,这些即时系统是软性的。不好的方面,我们谈坏的消息,最后期限是软的,但是里面有人在这个里面,人就是人,如果你要有一个即时应用软件,人们喜欢,人们爱,他们就会告诉其他的人,这也就有传统网络扩展的问题。当你建造这种网络的时候,满足人们的需求确实非常困难。我们需要一种控制来建造即时系统。因为有人的介入,因此你的控制是非常困难的。在中国,在美国,有一个常用的软件,叫手持对话系统,比如说手机。这个也是以网络为基础的应用,它也是一种DIRTy的应用软件,美国人称为手持对话,这个软件大家非常喜欢,创始人也非常喜欢。
    在美国有一个广播节目的主持,在克利夫兰,他说这是一个新的应用软件,大家应该好好的应用这个软件在手机上进行手持对话,结果马上有很多人开始应用,其中有35000人喜欢听音乐节目,他们马上开始应用这个软件跟朋友进行手持对话。后来我们发现用这种软件的很多,在一个月里变成几百个用户。如果没有即时性,人们就会不喜欢,因此我们要解决一些问题,建造即时系统,同时要解决传统的可扩展问题。在传统的应用里面,在传统的即时系统里面,我们控制一些变量,这样的话,我们可以建造一种方法,来控制延迟泡沫,延迟泡沫是可以控制的,延迟泡沫把它称为延迟气泡,因为它会对整个系统产生影响。我们是基于网络的系统,现在越来越复杂,现在很难去处理这些延迟气泡。
    因此,传统方法就不灵了。如果你采用传统的做法,在建造即时系统的时候,我们现在遇到了新挑战,过去传统的控制方法不灵了,我们需要把我们的关注点做一点转移。我们不能够去除这些延迟气泡,但是我们能够预防,不让它们升级。什么意思?我们让它们在对阵不对我们的运维产生影响,不要对其他的运维产生影响。因此你要进行预防。比如说有延迟的发生,比如说光盘可能会出错,他们的行为出错的话,你就很难建造即时系统。比如说有一定毫秒局部区域的延迟。比如说500到800毫秒的延迟,就需要操作系统重新启动,也许会出现一些异常值导致的这种情况。
    我们有一个延迟的异常值,按照传统的架构,就有一个人在等待这个事件,然后还有一些线程的,其他的人也在等待资源的到达。在这样一个架构里面,这样一个延迟会渗透到其他的地方去,所有的线程在工作的,都会被延缓,只是因为现成在一个光盘上出现了问题,这不是理论上的问题,这是实践中发生的问题,我们必须要预防这一点,这是挑战。因此,我们就要减少系统的同步性,要采取异步的方法,我们要告诉系统去做工作,做完以后回来告诉我,而不是阻碍。回来的时候你再把我唤醒,在历史上这是一个挑战,你开始运营,当它完成以后你要把这个状态捡起来,在过去是挑战,比如说在Java是挑战,它能够进行异步化,我们叫Node.js,大家有谁听说过Node.js的?有不少人举手。有多少人用过Node.js去编写过软件?Node.js非常好玩,非常容易,我鼓励大家开始多多利用Node.js。Node是什么?它是在服务器的Java,为什么它重要?这个是很重要的,为什么它能够提供异步的支持?因为它是从浏览器上生成的,如果它不能支持异步的话,就可以把整个浏览器给拿走。因此,浏览器,有这种问题有很多年了,来预防延迟气泡,来渗透到其他区域。它之所以能够做到。JavaScript是非常强有力的语言,它是一个功能性的语言。我们用一个Hello QCon演示,我来运行服务器,我们用一个终值点,它实际上是一个服务器,大家通过这个就可以看到Node的好处,如果JavaScript对异步进行支持,为什么我们花这么多时间来发展Node?
    只是进行同步是不够的,我们还希望这些JavaScript有足够高的表现。我们希望有一个比较好的表达方式,像谷歌,它是一个非常好的实践者。它在谷歌上面做虚拟机已经做了很多年了,主要用的就是JavaScript。这是非常重要的。因为在这些虚拟机上,一定要得到足够专业的表达。我不是说对菜鸟表示不尊敬,因为这是非常复杂的,而且是非常困难的。今天只有两个虚拟机,为什么他们需要,而且他们为什么在专业上表达比较好,就是GDM和VAT,还有其他的一些虚拟机,但是我觉得不够好。对这些VM来说,如果你表现不够好就没有意义了。
    另外,CORR,还有微软,加上微软可能就是第三个了。我微软的朋友可能给我发电子邮件,他们在哭呢,对不起,你怎么能这样说我们,对不起,我这是从专业的角度来谈问题。如果我们的表现足够好的话,这是我们的第二个趋势。
    第三个趋势,我们需要什么样的Node?非常非常宝贵的这些密码。如果喜欢用Linux系统的话,我们要用一些小的工具,做一些非常好的工作,把那些工具拿在一起,用一种新的方法组合起来。这在历史上是一种重要的软件开发的一种思想。但是随着时间的发展,大家做的东西越来越复杂,Linux跟Node的观点基本一致,就是小,不复杂,比较容易。要做非常强大的编程,我们可以看一下文档。这三个方面,我们说到上帝,上帝跟我说,大家都非常清楚,就是我们的延迟一定要小,也就是说上帝说系统要小,一定要好。因此,Node是一个很好的工具,我们来做这些事,我们如何来确认这些系统就是你想要的?我们在做DIRTy应用的时候,我们要有确认系统,就是它的延迟。当建这个系统的时候,我们一定要测量大,这样还不够,只是测量还不够,我们不能用传统方法去测量它,就是我们对每一个运行进行单独的测试,比如说一个传统的单独的网络应用对它进行测试。我们看这个图形,这个不够,因为对于这些运行,它可能会很高、很大,各种原因都可能发生,也可能变小了,有各种各样的原因,有时候可能会掉线。有时候10秒钟才能有响应,有时候就没有了,可能每10秒钟停一次,有很多很多的原因,我们不能用秒为单位来测量他们的表现。
    我们要测量延迟,我们看延迟的时候,用平均数据去测量它不够,有一些特殊情况发生的时候,数字是非常高的,这个就是延迟。我们面临着非常大的挑战,我们系统的延迟有多少?我们如何来测量系统整个的延迟?传统上我们要编一些代码,然后测量一下,这样还不够,我们要测量延迟的话,当一个运行开始以后我们要测量,当运行结束的时候也要测量,我们要测量整个的过程。首先我们要在两端有代码,更重要的是我们要一直关注运行的过程。每一个运行步骤,如果你放进系统里面,系统会变慢,这个就不够好了,不能这样做,我们应该用另外一种方法来做。我们还需要对深层的系统进行测量,底层对它延迟的可能性降低,我们要进行实时的动态的测量。
    DTrace多少人听说过DTrace?大家听的不多。给大家简单演示一下什么叫DTrace。首先介绍一下我们如何开发的DTrace。当时我在另外一个公司的时候,当时有一个问题,有一个非常大的机器,为什么这个机器表现不好?是系统太差?我们不知道为什么。我们当时写了DTrace。给大家简单演示一下,我们先运行一下,命令行。如果没有运行的话,减去L,我们看每一个运行,看一下WC,我们看到有很多行,这个是对系统进行不同的测量。我们再看下一个列表,把这些逗号分割开,看系统里面整个的内容,测量的时候看一下,我们看没有测量过的、完全优化的整个的运行,很有用,但是还不足够有用。一块一块都显示出来了,有什么用呢?谁做的?哪一个应用做了这些?DTrace把这些信息都收集到一起,我们希望它是随意发生的,而且用编程的语言。我们看每秒钟它有哪些运行?把名字输进去。实际上正在运行的这些应用,看到没有?大家能看懂演示的是什么?我们看到自己了。这就是系统,整个把系统内的东西在屏幕上都显示出来。大家用过TOP吗?运行一下,这是好现象,我们把数据进行收缩,我们每次把数据加总,这肯定是TOP问题,肯定哪个地方是有问题。
    看TOP能够做哪些?我们用TOP加总看一下,系统的叫做TOP的运行,现在可以了解,在系统里面哪一部分正在运行,而且为什么是这么运行的?这是一个非常简单的问题,当然还有很多。DTrace和Node,DTrace可以进行系统性测量,我们如何把这两个结合起来?我们在这个系统底层这些东西的发生,和Node结合起来。在Node进行用的时候,我们对整个代码的模式进行测量,我们叫USDT方法。举个例子,我们看QCond服务器,我们对此进行测量,对服务器有一个请求,再看对这些服务器的请求,对每一行进行一个测量,这是地址,是Node的。我们看到99%,就是斜线后面的内容。编程是在这里的,程序在这里,在这个程序里面没有测量的步骤,我们实际上对这个进行实时的测量,但是不在这个程序里面,我们可以测量我们真正想测量的东西,就是延迟。这是一行脚本,我们从Node里面可以看到一个非常重要的步骤,我们只能找到一些问题,从这个上面可以找到相应的问题,DTrace可以找到下面一部分的内容,我们有一个Node DTrace的提供商,我们看到前面在Node里面有一些显示,这儿有一个网址。另外我们用视觉化的现象来表达这些测量。
    平均而言,我们看这些延迟,这是我们的一个热量表,跟刚才那个表完全不一样,我们看获取的时间以及它的延迟,我们看哪些地方发生了弯曲,这时候给我们提出更多的问题,哪些地方发生了延迟,为什么发生延迟?我们才发现,我们可能有这些数据,可能从不同的角度来看这个问题。我们用这些颜色来使你们知道从不同的角度看问题。这些是相关的,从桌面延迟都是相关的,这些热度表是非常好的方法,使人们可以用视觉化的现象来了解哪些地方有延迟。我们很透明的进行比较,不是用你们的编码,而是我们在屏幕后面做的。对这些开发者,这都是一些实时的应用,非常动态化的实时的,这是非常关键的一个步骤。
    在一年多前,我们已经证明了大家对新的DTrace应用是非常关注的。我们现在可以看有哪些延迟,如何来测量,如何视觉化的表现出来,这样就能够利用我们系统内的延迟,我要跟大家说的是,大家都不完美,但是我们有一个方法,Node里面有一个方法。但是我们考虑到Node的时候,我们Node它是一个简单的步骤,你们应用的逻辑,在Java脚本里面,总体上来说这不是个问题,因为有些正在做的事情,它就是我们以前做过的这些东西,比如说像网络、数据库等等,这都是以前做过的。如果我们把这些转一圈,我们看一下CPU的运作,我们看到延迟的话,这个时候可能对后面每个人都有影响。
    我们看到Nodes额,当然有时候我们不想谈这个问题,我们想使大家能够排除这些问题,只要这些问题出现了就把它排除掉。从历史上我们要翻译这种语言,从历史上来看都有这些步骤,我们在这个环境看到这些问题,大家就会了解我们当时的情况是什么样子。我们现在所做的就是在上面加上一套制度,使你可以把这个系统的问题和现在的情况连接起来。
    我们看刚才的演示,这个可能稍微复杂一些。如果说hello QCon时装城是什么?我要运行小的应用,然后在这儿敲击一下,用一个虚拟参数,然后再敲进一个数字,把它写成两秒,让它旋转时间更长一些。我们在看这个箱子里面,它正在进行旋转。98%在CPU里旋转,我们应用DTrace来应对这个问题,用一个工具,每秒99次,我们看到哪个在运行。我们看Node的过程,我们有keed进行集合,是71149在做这个事情,我们把它进行保持,我们现在属于什么位置?用F100、F6,另外要对这个人物进行定义,因为他是早到的,但是在这儿我们看到。真正的问题,中间这块是什么,这是最难的,历史上我们不能够回答这方面的问题,在Node里面,我们增加了这块,运行一秒钟,现在我们看到有哪些框架增加进来了,我们看到了内部编码,然后还有数据跟位置,这样就找到了我自己的编码,看到的是我的编码造成了这些,为什么有延迟,做了一些非常有趣的发现。
    我们看到Stacks,我们来了解相对的频繁性,这些堆站可以进行可视化,以前我们无法做到这可视化,这是Node的一个基本特色。我们刚才说Node.js非常重要,它能够典型的帮我们做即时系统。当你部署这些Node为基础的系统,还要帮你了解这个延迟来自什么地方。我们用DTrace的方法,做吸引的可视化,放到云计算跟软件里面,这样有非常好的生产支持。非常重要的一点,Node只是把原件进行连接起来,可能Node是你的问题,也可能不是,在过去两年的经验,我们发现问题往往是Node连接的对象造成的问题,比如说里面的存储,还有分布式的存储,所有的东西需要集合的去理解。你可能会花更多时间了解延迟。因此,当你选择Componets的时候,你要去了解,把这个作为一个方法,对进行Componets评估,在做Node的时候,你会说这是JavaScript。因此,我要尽可能用到JavaScript的人员就行了,不是这样的,你需要系统人员,你需要工程师了解系统Node,它是非常容易学的,任何人都可能学会。但是你需要一个系统的思维,学Node的并不难,关键是你要有一种思维,你要了解Componets相互的关系,当你建造团队的时候这是需要考虑的问题。谢谢大家。
    主持人:大家再次用掌声感谢Bryan Cantrill给大家带来的精彩掌声。
    主持人:接下来进入今天上午的第二个演讲,由ason Brown带来的“利用云技术实现Netflix快速规模化增长”。
    Jason Brown:大家好,我是Jason Brown,我来自加利福尼亚的一个公司Netflix。我会给大家讲讲我们如何利用云计算的技术帮助我们技术增长,而且是全球性的增长是如何实现的。
    我为Netflix工作三年半了,我是一个高级软件工程师,过去18到24个月,我关注的使用Cassandra,帮助我们实现更高的性能。我们用Cassandra做一些测试,做基础架构的测试。我还喜欢打棒球、羽毛球。我们成立的公司有点像市场推广,给大家介绍一下我们公司做什么?我们有23000流媒体的人员,在美国、加拿大、拉丁美洲、英国、爱尔兰,我们全球领先的成员制,我们是给成员提供底片给电视剧下载的一个公司。一开始我们是邮购DVD的公司,在93年的时候,你把钱个我们,我们给你进行DVD的邮购,几年前开始进行流媒体服务。我们在宽带比较便宜的情况下,使得家庭成员能够充分利用。2000年我们开始进入了流媒。我们的流媒体在700种不同的设备上运营,包括电视,还有电视摇控器,还有其他的下载服务。目前来说,Netflix我们占美国网络电视流量的33%。我们现在还做DVD邮购的业务,我们很快在扩展我们的服务和内容,而且扩展到全球,在美国跟加拿大、北美。我们在拉丁美洲扩张也是非常快的。
    下面会谈一下我们技术的堆站,98年的时候我们只用一个网络应用软件,我们继续在增长,一直在增长,现在我们有更多的数据库,而且有相互的连接,而且是多事件、多事率的。通过用Databases连接的方法,而且是多主机的复制。在2008年的9月份,我们放弃了原来的数据库,但是我们又增加了新的数据库。通过我们用单点来进行数据库的迁移。我们那个时候开始做了一些重新思考,我们成长了10年,我们到了一个关键的点,在市场来说,在Netflix,他们进行了重新的思考,大家开始对我们的业务模式做重新的打量。我们把我们的服务做了更多的细分,建立了更多的7到10人的团队,有传统的架构,还有新的工程师的团队。我们意识到运行我们的数据中心不是一件容易的事。
    这时候我们就开始研究云技术的利用,我不希望有一个零部件有问题整个系统就瘫痪。我们为什么建立了 CLOUD?我们不能很快建立数据中心,有很多的硬件的约束因素,我们利用别人做好的工作,就是云技术,来给我们带来一些优势。我们知道硬件虽然很重要?但是对于我们的业务来说,这块并不是最关键的,我们不喜欢规划我们的产能,我们不喜欢事先获得准许再使用别人的服务器。另外,我们也不喜欢有程序,我们也不喜欢等待。因此,我们就开始选择了AWS。AWS首先是非常大的公有云。我们知道公有云的提供商,它有它自己的一些特色,当我们需要每小时有几千个事件的时候,我们就需要利用这样大的公有云。
    我们是一个基于用户的,是提供影片的下载、DVD的下载,很多人都是晚上的时候要用我们的服务,所以我们的访问量最大的时候是夜间,而不是白天。因此,我们的服务器,白天跟晚上需要的数量大大不一样。因此,我们就要好好利用云计算的技术,利用这个公有云。这样的话,我们就可以减少我们的支出。我们要跟踪流量,比如说到顶峰时期的时候,我们可以看到它的流量。
    举一个例子,亚马逊我们输给它的服务,可以看到它对规模的控制比较好,随时可大可小。还有EC2,大家可能比较熟悉这个服务,AMI,它是一种事先已经做好的这样一些请求就比较容易使用。他们对规模控制比较好,对流量来说,流量随时增加或者随时减少,有很好的适用性。另外就是库存非常大,看SimpleDB,这是我们最早使用的工具。这些都是亚马逊提供的。我们看如何开发应用,然后最后把它们布置到云上去。
    首先要建立一个应用,请工程师写代码,然后提交。我们有自动的一些建成的这些代码,这个自动化的完成,这样它做成不同的组件,有的可以直接下载下来用,RPM,这个应用可以在应用上展开。
    我们把这些代码先发布出来,在亚马逊上,他们有一个自动的对流量的调节。一般来说,我们自己不需要做很多的配置,他们已经配置好了。我们一般喜欢这样,我们不愿意做太多的配置,因为他们有一些固定的套路。要不然自己写的话,有的时候可能会不匹配,不协调。有的时候是代码有问题,有的时候是配置有问题。我们决定做改变的话,做一个新的改变的话,跟过去要保持一致,要及时的更新。这样的话,希望我们的服务器能够了解我们这些行为。
    我们对AMI,我们把它叫做烘焙的过程,我们把它和其他内容放在一起,存在AMI上,在实际的应用过程中,这是一个Linux的技术系统,有Java,有6或7,我们开使用Java7,Tomcat,这些都是现成的,都是可以马上用的,有现成的脚本,我们很容易理解它的语句。
    我们在应用部署AMI的过程中,我们有很多的程序,但是对于工程师来说,实际上就是一个发布代码的过程。我们先有一个基本的自动的对流量控制的组,我们看它是上升还是下降,我们对这个自对的流量有一个连接。在实际的过程中,AMI在运行的过程中,脚本会自动的对流量载量进行平衡。我们看中层,它是一种中层的服务。还跟一个平衡的流量平衡器进行连接,他们可以提交这些清就。大多数的情况下,他们都很快的,也就是在60秒之内就可以完成。这是一个红的、黑的系统,是这样一个部署过程。首先,我们有以前运行的系统,比如说它版本1正在运行,这时候会出来一些结果。一般来说,版本1,有时候几天,有时候一个小时就换掉了。我们觉得这个系统还是非常好用的。比如说现在正在版本1的时候,版本2也开始运行了,如果觉得版本2就问题的话,在几十分钟内还可以修改一下,然后把版本1拿出来。这个时候可以早期发现问题,继续用早期的版本。把版本1换成版本2,如果我们觉得版本2不错了,就把版本1全部结束。有的时候多,有时候少,有时候运行小一些。
    我们看一个召见,在两年前,我们做这些网络应用的时候,我们先打开一个服务,叫做ASGARD,非常好听的一个名字。举个例子,红旗的布置,对于这些用户来说,他们在这个上面可以做出自己的选择,可以做出调整,他们觉得46不好,用47,46不够好的时候,47的版本就上来了。如果把版本1拿掉的话,那么就把版本2拿出来进行使用。过了几天以后,我们可能把47版本停止了,就开使用新的版本,48。
    看右边这个大的图,我们在用下一个服务部署的时候,有三行,有AMI的ID,很容易就能够看出哪些服务是有问题的。可能一次有9个提交,也可能有四五个提交。我们详细看一下它现在正在运行的一些情况,哪些地区是好的,是可以使用的,有的是不可使用的,非常详细。
    我们有一些策略来进行部署,首先的一个原则,任何事情,第一个请求都不运行,主要是为了考虑它的弹性。我们能做多少,什么时候可能系统就不行了,一般我们让开发者,一般都有两版或者三版,对服务的第二版或者第三版提出来,像亚马逊云的TOP,比如说有一个在美国,有一个在欧洲,在新加坡,在东京,不管是在哪个地方,每个地区都有自己的一些能力,他们有自己的数据中心。亚马逊对每个地方的代理都是非常详细的,细节都可以提供给我们。我们把这些请求提出来,在不同的地区之间进行部署。在每个地区它都有它自己的请求,比如说某个地区不行,系统不行,我们再用其他的部分,这样的话,把流量调过来。它还有自动的规模调整,规模可以变大,也可以变小。对自动调整来说,它可以对一些问题进行自动的解决。一般来说,是应对大流量的情况,如果流量有问题的话,那么就解决这些问题。
    看一下我们对一些能力的改变,CPU的利用。有一些请求,系统有时候高,有时候低。看看核心的云服务,首先是发现。这是一个集中化的服务,每一次有一个新的服务提出来的时候,重新开始运行的时候,我们都是集中式的发现。之后我们有协议,每30秒把这个服务进行一个提出,我们要看哪些在运行,哪些没有运行。这个发现过程能够跟踪这些流量,跟踪这些服务、这些请求,三个连续的,如果说中断的话,比如说有三秒钟没有连续三次运行的话,这个服务就停止了,我们对它进行过滤。DNS,云上面并没有DNS,起码现在还没有DNS,现在有各种各样的情况。
   另外一方面对客户的服务,NIWS客户,我们对客户内部网络的服务,在发现过程中,我们看每个请求的IP的这些请求内容,我们看有哪些服务,我们就会想出来,DNS需要哪些服务,我们及时来跟踪,来避免一些问题。我们看一下它是否跟服务的提供是在同样一个区域。
    配置的管理,我们有新的AMI。这是一个集中式的管理,我们要做快速的特制服务,我们看这些核心的数值,把这个数值进行比较、配对。每个服务,Past Properties这是一个服务,我们看它的系统延迟,不同的地区有不同的情况。这张图是内容的显示,比如说名字、技术服务,比如说对亚马逊云上面的内容进行对照。
    安全问题。首先是AKMS,AKMS是亚马逊的关键指标管理系统。我们在亚马逊服务的时候,对客户来说它是一个简单的服务,我们把这些及时的进行更新。我们可以把它重新指向AKMS。另外一方面就是Crypytex,就是有加密、解密的过程。实际上是对密码钥匙进行保管。如果没有加密的密钥的话,EC2这些,就是对于高敏感性、高安全性的数据是无法应用的。对于一些Crypytex是进行中等的加密,很少情况需要这种高程度的加密。
    这个也是一个发现的过程,如果发现了的话,把它关掉,叫EV的缓存,任何时候可以停止,也可以重新回来。要使它发生作用的话,也是用亚马逊云上的服务,我们对它的区域进行了解和限制,95%的区域都可以确认。
    如果有两个区的话,这是一个很快的图表,比如说A区它有客户端来跟地方的云相连接,同时它有一个跨越,跨越两道B区,数据在B区也是可视的。
    Cassandra,我花了很多时间去研究Cassandra,它是云计算里面非常好的数据库的技术,它可以进行横向的扩展,同时它也是内在的多数据中心,它非常容易跨越多区,也可以多数据中心在区域里面。另外,对于Coludbese可转换。
    我们可一些使用实例,一个是关于我们客户ID的使用,我们一秒钟可能有很多请求,而且往往是跨不同的物理区域的,包括在美国、欧洲。同时还可以让客户了解视频电影的访问历史,我们做了很多工作,包括有一个登录的文件。同时我们对客户的行为有很好的记录,这样的话可以对他喜欢的电影做推荐,做判断。在上面做了很多客户行为分析的工作。我们围绕着Cassandra的工具,形成了一些新的工具,还有Priam,它是Cassandra的共同程序,还有一个Cassandra的浏览器,它是浏览集群。
    我们看到这些圆圈,都是Cassandra的数据中心在运作的情形,有200多个生产集群,有些是在工作中,有些没有在运行,比如说第二行的第二个圆圈,有些红色说明它正在运行。因此,我们可以很容易的看到哪些在运行,哪些没有在运行。
    我来谈一下监测云的可靠性,我们LOG文件有多种,我们一开始是做快照的方式,我们每过一定的时间就有一个快照,然后把它放在100个集群里面。有时候有延迟,比如说15分钟的延迟,这样的话就增加了成本。现在运行的是Biopsys,另外对Java的library经过不阻挡,它内部有很多加密,这样的话会形成一些瓶颈,所以说我们采取了一些新的方法,使得扩展性更加容易,更加能够满足我们的需求。
    这是Biopsys的一个快照,左上角看到有一些集群,右上角是搜索选择,对选择显示了不同的条件,可以把条件输入,选择好以后进行提交。对于我们来说,帮助我们解决非常即时性的问题是很有用的。
    监测,对系统发生什么是非常重要的,我们对一些进行监测,不光是低层面的东西,还有带宽的利用,其他方面我们也进行监测,我们这个监测做的非常好。另外,我们还有应用系统的一些矩阵,包括计数器,还有最终其,来进行显性的编码的测试跟调整,我们用一个中心的系统,我们还有服务层面的协议政策,我们把它整合成两个系统当中,一个是叫RAD的工具,这些整合就整合成两个系统,对我们来说非常有效率,给我们带来很大的好处。
    在监督这块,你要有个警告提醒的功能。因此,我们有一个通用的警告体系的门户,叫CAG。如果是一个小的违反政策的,我们通过自动繁琐邮件的方式,如果是大的,我们就会通知工程师,我们跟旧金山的一个公司进行合作,他们给我们提供工程师的服务,向他们发出请求,然后来他们来给我们提供帮助。
    弹性,为了解决这些错误失败的发生,我们建立起了所谓的猴子,我们把它称为猴子大军。很快就会进行开源的工作,第一个叫处理混乱的猴子,把这些混乱终止,能够把一些实例终止杀死,这种情况可能一天会发生一两次。我们也需要一定的弹性,这个问题是比较容易处理的问题。还有处理延迟的猴子,来减少在远程呼叫的延迟的现象。另外还有保持一致性的猴子,处理延迟的猴子,我们专门做了很多工作,我们觉得死的服务器比慢的服务器还要好。因此,在A对B做回应的时候,我们可以做一个随机的延迟测试。可以把延迟进行组合,变成一个组合的回应,让我们对这个服务更好的了解。一致性的猴子大军,它是一种工具,来保证服务器上所有的实例。还有看门人的猴子大军,它可以提醒工程师关于死掉的没有使用的一些实例跟资源,通过发邮件告诉工程师来进行清理。
    关于延迟,当系统变慢的时候,我们有一个团队,是负责外围的API的,我们建立起了一个容错的模式,当他们获得一个请求,比如说来自一个浏览器,来自于一个设备,他们会向其他的15到20个服务端进行通知,进行呼叫,如果有一个回应减慢,其他的回应都会减慢,这样所有进来的呼叫请求都会被延迟。因此,就建了一个突破回路的模式,能够控制1次到0次。我们通过建立一些默认值的方式,在左上角,比如说有一个请求进来,我们进行执行,如果线路是开放的,也就是下游的服务表现不好,我们就会让这个行为进行回滚。
    自动化,我们尽可能做更多的自动化,包括Builds、Release等等,我们都进行了自动化,把所有能够延迟我们的都进行自动化,API是比较新的,他们有工具箱,还有很好的物理结构。
    一些要点,Netflix使我们所有的零部件进行分布,并且是容错的,我们在国际上增长我们业务的时候,我们有云平台的开源的部分,包括Cassandra的支持,我们建立了非常坚实的基础架构。谢谢。由于时间问题,大家私下再向我提问,我今天全天都在,大家任何时候都可以找我。
   

时间:2012年4月18日
地点:京仪大酒店
    主持人:我是InfoQ联合创始人,作为东道主非常感谢大家的光临。因为今天我是上午这个时段的主持人,我对今天上午的整体议程做一个介绍,给大家一个简单的议程,看看下午对哪个专题比较感兴趣,也方便大家了解今天给大家带来什么样的内容,方便大家选择。今天我们非常荣幸邀请到InfoQ的创始人,如果说没有什么例外,他每年几乎都要到中国来这么一趟,一方面想和InfoQ中文站团队进行交流,另外希望和中国的技术社区做一个交流。接下来让我们在座的各位和我一起用热烈掌声欢弗洛德(音)做一个简短的致辞。
    弗洛德:谢谢。中国的情况都在这个片子上介绍了。很高兴我们QCon在全世界都举办这个活动。大家知道软件把世界变成了一个更好的世界。我们公司的目的,要鼓励软件开发,QCon也是这个目的。谁经常上我们的网站呢?我们想举办这类会议是让实际工作的人员参与这个会议,不仅在中国,在全世界都是这样的。我们把新的策略,新的概念推广开来。我们QCon的这些内容主要就是创新,我们现在做的就是这些,也不是给菜鸟级的人准备,是给有经验的人准备的。
    我们每年都会在美国举办这样的会议,大家可能来这里也不光是有会议内容,也有一个见面的想法。我们是一个遍布全球的网络,我们在英国、美国也都举办类似的会,大概每次会都是上千人参加。就像现在在北京举办的这个会。我们是InfoQ这个公司支持的,我们现在在中国也有100多家合作伙伴。我们InfoQ是非常独特的,这些内容都是我们这些参与者提供的,在全球都是这样。在空余的时间可以把这些内容翻译成中文让中国的同人了解。非常谢谢大家参与今天的会议。
    主持人:我们关注的主题已经做了非常大的变化,从前的主题是时刻关键企业领域软件开发与创新,但是后来发现,如果关注企业软件开发,可能对于中国来讲并不是非常合适,在中国,如果说你要给别人讲什么是企业软件开发,你用半个小时讲的都不是非常明白。我们顺应形势,根据中国社区发展,改成促进软件开发领域知识与创新的传播。这样我们关注的范围更加广泛一些,另外关注的领域从原来的Java、架构、运维,调整成语言和开发、架构和设计、过程和实践、运维和基础架构、企业架构。可以看到,其实InfoQ虽然在变,但是它关注的主题基本上是面向中高端的技术人员,是面向架构和项目管理的。
    另外一个,简单分享一下InfoQ中文网站的梦想,我们是促进软件开发知识与创新的传播。刚开始一直在北京做QCon,但是后来发现很多南方的朋友,如果深圳、广州的人要到北京来,他的差旅费会大于门票的费用,我们希望通过北京的会议能够覆盖华北的人员,我们做的杭州会议能够覆盖整个华东地区的人员。今年8月份我们会在深圳的万科国际会议做一个关于全球架构师的峰会。对于大西南地区来讲,我们也在考虑有一个计划,如果有可能的话,可能会和杭州联志在成都做QCon的分会场,希望通过不同的方式能够覆盖整个主要地区的研发人员。
    下面简单介绍一下今天上午的主题演讲,今天上午有三个讲师。第一个是John Davies,其实他软件过好几个软件公司,包括有一个公司是cl4。他今天给我们带来的主题,虽然和现在热门的技术相关,包括缓存,包括NosQL,这些技术早银行业已经试验过了,但是它的好与坏怎么去进行对比,今天John Davies在上午主题演讲中会给我们介绍这个话题。
    肖伟是我们好几届的QCon讲师了,他一直致力于百度云的介绍,他会介绍一下百度下一代云平台,这里面可能有大家需要关注的一个话题,百度的云是面向开发者的云计算平台,过度成一个面向个人云计算的平台,在整个的里面,百度云基础架构设计有没有做变化,他们对云计算的趋势是怎么考虑的,肖伟会做一个整体的介绍。
    Alex Papadimoulis也是一个国际知名的软件开发专家,他会讲一些大家现在比较关注的话题,他会告诉大家软件研发不仅仅是技术集成。今天下午在大宴会厅是知名网站架构分析,这个也是QCon北京常设的专题,我们每年都会设这么一个专题,大家对于知名网站的架构是怎么设计的都是比较感兴趣的。今年邀请的嘉宾也比较有代表性。
    曹政在网上比较知名,他们如果经常用微博的话,根据他的介绍,他在整个软件研发领域混了差不多14年,他今天给我们带来的主题是比较传统的,但是其实又是我们经常反对实用的一个话题,就是分布式数据以及反范式的设计。
    我们还邀请了电子商务类的代表团队,蘑菇街,也是去年包括今年成长速度非常快的。如果说你想去创业,或者是关注创业团队,他的话题比较有意思。岳旭强是淘宝的架构师。刘晓飞,他在一个比较神奇的网站。他在下午给我们介绍一个话题是互联网高弹性架构,他们设计了一套弹性非常大的架构,在下午晓飞会跟大家分享这么一个话题。最后一个是来自去哪儿的朱翔。大家在出差旅游的时候,经常用的一个网站,好象其他的搜索引擎并不能满足他们的需要,于是他们自己研究了一套,就是QSearch。朱翔今天下午会跟大家分享一下整个设计的原理,包括在设计过程中遇到哪些问题,他会跟大家进行分享。
    有请来自来自腾讯架构平台部的吴悦给大家介绍。
    吴悦:大家好。我叫吴悦,我带子于腾讯架构平台部,昨天晚上我问今天参加会议的有多少?说大概有1000人。其实我还是有点压力,但是没有关系。因为我现在还是很有底气的站在这里,因为今天下午分享的这个专题内容确实很给力。我们今天要介绍的主题是大数据跟NosQL。要说明的是在大数据的这样一个时代背景下,对这种非数据库的一种统称。从这个意义上看,大数据跟NosQL是非常注重实践的专门领域的技术。具体而言,下午具体分享有四个分享。第一个是分享如何在社区产品中应用NosQL的一个技术,分享者是来自于腾讯的吴悦,就是我本人。第二个分享是去分享如何在数据计算跟分析领域的一些新的技术成果,主要是介绍在数据计算分析领域新的一些技术成果和应用,分享者是来自于百度的杨栋。第三位分享是来自于著名的国际友人John Davies,他会给我们分享或者是回顾NosQL在过去的发展,如何去构建一个高效的NosQL数据库。第四个分享是介绍一下目前国内比较有名的一个开源的NosQL的项目,以及介绍一下Tair这个项目在淘宝的具体应用,分享者是来自于淘宝的杨成虎。我们今天下午内容是非常精彩的,所以大家一定不要错过。会议的地点在第一会议室,在目前这个会议的大厅的斜对角。今天下午非常期待各位技术专家和同行对NosQL和大数据的这样一个专题做分享和讨论。

    主持人:下面有请来自IBM的程序员,也是InfoQ的编辑赵劼给大家介绍下一个话题。
    赵劼:大家好。我是赵劼,在社区里一般叫老赵。我现在是在IBM混日子。我的工作,其实我是一个程序员。我也想调查一下,如果您平时的大部分工作是有在写代码或者是审查代码,而不是纯粹做一些架构、分析这样的工作,能不能举一下手让我看一下。差不多一半的人和我一样。在前年的QCon也有一个关于语言的主题,当时我也是主持人。所以简单地说来,这两年我其实没有什么进步,还是在做一样的事情。QCon是进步了,因为它在不断地吸收新鲜血液,当然不要把这个理解为这一届讲师就比两年前的讲师好很多。
    来看一下这次的四个主题,第一个大家比较熟悉,是许式伟,他之前在各个技术会议上分享他技术方面的花蒂。这次我们把他邀请来分享个够。老许是在国内go比较知名的一个推广者和使用者,他对go的喜爱程度,大家在下午也可以体会到。他现在在创业,主要使用的语言也是go,他说go是互联网时代的c语言,很显然他对go寄于多大的希望。
    第二位是Alex Papadimoulis,我想在座的各位,甚至于世界上也不会有太多的人在一些丑陋的代码会比Alex Papadimoulis有更多的经验,他每天就是和大家提交上来的那些丑陋的代码打交道。大家可以从他的分享中来看一下他对代码之丑这个东西怎么看的。如果看到他在InfoQ网站上录制的视频演讲也可以发现,他的观点是代码之美,各人有不同的观点,但是对于代码之丑这回事,大家比较容易达成共识。
    第三位是黄毅,之前这个栏目不叫程序设计,叫做函数式编程。他之前也写过如何编写代码。
    最后一个主题是曾冠东,如果在网上经常看到我说话,Java这门语言是声嘶力竭的,我这个人对于Java平台吸收喜欢,它的生态系统也比较活跃,但是对这门语言是比较落后的。
    这次主题四个演讲都是贴近大家每天写程序的生活,如果写程序是你的安家命之本的话,这个话题大家一定要看。
    主持人:下面有请段念介绍下一个话题。
    段念:我没有办法用华丽的语言描述这个专场,至少跟大家介绍一下比较实际的。量体裁衣的项目管理专场,这么多年来没有听到有多少变化,但是一旦项目管理遇到敏捷之后,就会发生很多变化。有人会觉得敏捷的过程中是不是需要专职的项目管理师,我们整个团队都是用敏捷的方式来做的,在这个专场会有四位来自一线的两方面的经验的人来跟大家分享,在一个敏捷的环境里,在一个互联网环境里面如何做好相应的项目管理。第一位是乔梁,他在持续交付领域有研究。乔梁会给大家带来一个打造面向服务的比较团队,是基于对于持续交付和持续集成的一个概念,打造一个面向服务的敏捷团队。第二位是李靖,他给大家介绍的是一个务实的主题,如何在弱矩阵下做好项目管理。他一直在讲他的故事,从一个完没有项目的横向的组织里面,到建立一个具有一定的弱矩阵的项目经理本身并不具有太大权限的环境下,怎么样把项目经理的作用发挥出来,怎么样在组织过程中持续推进,如果大家遇到有跟他一样的困境,我想这个可能很有启发。第三个是来自soso的钱安川,如何在soso这样一个互联网中间运用敏捷的项目管理。钱安川的ppt非常漂亮,更多的是他自己经验的分享。最后一位是来自吴浩刚,他大概有10多年的POM方面的经验,他带来的话题是敏捷团队的项目质量管理,重点是如何做质量管理。在跟他做这个主题的时候,一个是跟需求有关的,如何在敏捷团队中做好需求管理。经过我们两个再三讨论,最终定在敏捷项目团队的管理,在快的过程中如何保证产品的高质量,吴浩刚在这个方面会跟大家分享经验。下午大家可以到这个专场来看一看。谢谢大家。
    主持人:下面我再用两分钟的时间给大家讲一下注意事项。每一场演讲结束之后,大家可以针对这场的讲师可以进行评价,如果大家认为这个讲师讲的不错,可以贴一个大红花。特别感谢我们的战略合作伙伴百度。特别感谢金牌赞助商天翼空间,我们希望获得业界的支持,能够让整个活动比较顺利的进行下去。接下来让我们用非常热烈的掌声欢迎John Davies给我们做第一场演讲。
    John Davies:我不能讲中文感到非常抱歉,我只能说四门语言,但是中文不是其中的一门,我在香港待过两年,想学中文,但是没有学会。因为发现这个中文非常地困难。所以说中文我不会讲,对不起,但是我尽可能讲的慢一些。因为我不是美国人,所以我的英语比美国人好一些,所以这是比较好的事情。
    下面让大家看一下我们今天谈的话题,我是个技术专家,所以说语言不是我擅长的东西。大家可以看一下,我在Java方面的背景,我自己是做企业架构的。我也经常在飞机上写幻灯之类的。
    我做过不同公司的CTO,主要是Java类的公司,这是我的背景,我今天给大家讲的是网格技术,以及网格计算发展新的情形,这些技术现在又渗入到了银行业方方面面日常的工作。主要是由Java占主导,会议完了以后我要去新加坡,这些技术全世界都在使用,我现在要做的是给大家介绍一下这些技术的背景,为什么我们使用这些技术,为什么现在有NosQL,还有现在面临的规模,尤其是在银行业,我会举一些例子,关于数字方面的例子,看这个规模有多大,为什么要使用这个NosQL。
    SQL是一种语言,大家都很熟悉。在数据库方面,SQL是非常有用的,使得文档直接进行相联,非常好的语言,已经用几十年了。既然SQL这么好,为什么还要搞NosQL?我举一个例子,为什么它那么好,同时也会谈谈它的缺点。如果你们在这个行业里面都混过的话,你们对这种文档都很熟悉了。这其实是文档小小一部分而已,不是整个文档。每个图表都代表我们要找回的信息。这些信息我们都是要提取的,要把不同的图表连接起来,SQL可能会很大,由于这种结果,而且复杂性也会很高。
    因此,我们现在就有了一个新的术语,叫NosQL。为什么要有NosQL?我会跟大家做一些探索。我们会不会说noJava、nowindows?但是为什么我们要用NosQL?为什么NosQL这种技术现在变得非常通行?
    大家跟着我一起看一下,看一下NosQL的作用所在。我们看到NosQL在做一些任务的时候是非常容易的,比如说有一些常见的文档,它可以同时运行很多的数据。对这种目的来讲,这种工具还是非常有用的。我们是否可以用Java来代替SQL呢?我们还需要进行翻译。比如说我们举个例子,向在分布式系统里面使用Java软件。有个问题,比如说我们在CSV有100万行,我们在伦敦、北京互相之间传输这个数据,1G的数据,1G的数据我们要一下传输。你觉得需要多长时间才能把这个数据很快的传过去?我们一般需要30秒到1分钟,还是20到30秒?10到15秒?谁认为是10秒钟?大家都觉得1分钟以上才能完成这个传输。实际上我们在运行这个数据的时候,我自己看的时候,比如说我们用Javanio,100兆是1.2倍,1G的数据需要12秒。如果我们用Java可能会有问题。
    比如说我们用Javanio的话,所以说Java也不是魔法,能够把一切问题解决。现在可能这是个问题,就是关系型数据库,这是一种架构化非常复杂的数据。这种复杂性在关系型数据库来处理的话,也是无法解决的。
    这是金融数据的标记语言,跟我们其他所使用的一些技术都是非常相近的,上面画的乱乱的,就是这个,一笔金融交易可能要涉及到这么数据的传输,我们看一下这个结构。也就是说用SQL会有问题,这个图上会看出来用SQL无法解决这个问题,如何在这么大的数据库里面解决这么多数据问题?我们要存储这些数据,存到数据库里面去。然后再提取这些数据。所以,我们不用SQL,我们用NosQL。所以从目前来看,SQL无法解决我们的问题。
    再举一个例子,数据量非常大的例子。在银行业,不管是在北京、香港还是上海,比如说人们用某种价格来买卖某种产品,一般来说每秒钟会有10万多个报价,每秒钟,在芝加哥商品交易所,每秒钟报价是5到10万。这个数据量是非常大的。还有一些情况更复杂,一般来说,投资者有上万个投资组合,比如说我们买这些股票,卖出那些股票等等。这些投资组合都要以某个价格报出。因此,每秒钟数据的传输非常大。买还是不买,可能很快会决定有100万个这样的决策做出来。
    这些数据、计算只是他们这个组合中的一小部分,我们大概通过这个就可以了解它的规模有多大,要考虑到这么大量的交易,我们需要考虑一下。不能说以秒计算,而要以毫秒计算,价格只要一变化,全世界的银行都要来决定是否买这个股票。你一定要使自己的银行在第一时间能够买到这个股票,这是竞争,是数量非常大的竞争。在伦敦某家银行,跟其他地方的银行规模差不多大,这些大多数的方块内都是他们一些线性的决策,对于银行来说,把他们的支票如何做登记签入,一般用的是Java的或者是Scala语言。这是它们的功能组合,非常大,非常复杂,也很洋气的一个组合,银行里这么多功能组要发挥作用。这是个例子。大家看价格在顶部,一行一行往下走,这些交易可能需要花三天的时间,先是价格,然后进行风险分析、计算,到底下我们来进行清算,最后是清算。每一笔交易都是这样一个流程。我们看现在有不同的银行,比如说上海的,还有各国的银行,他们都要参与其中,这样的话,复杂性进一步增加,有人从上海买,同样他在纽约还会卖出。所以,所有的这些东西都要连接起来。
    现在我们这些连接性能就好很多了,把这些银行都连起来,这是一个很标准的做法。现在大家能够了解这么多的复杂性,也就是说我们在做交易和处理的时候,银行业就是这样做的,每一秒钟数十万个信息进行交换,每天可以做数十笔交易,交易都涉及到上十亿人民币、欧元、美元等等。因此,这就是为什么我们要把这些技术进一步推到这些行业。
    还要考虑风险,有很多的失败因素,在西方我们可以看到,有些人愿意面对风险,有的人无法理解这些风险,就是说他不能接受失败。如果真的失败的话,他们把很多钱交给银行了,让银行来处理,如果银行弄错了的话,可能会损失重大,银行也要赔款很多的。但是我们知道有的时候,比如说有些事故发生,像东京、旧金山发生地震,我们必须进行风险的计算,我们用这些技术来解决这些问题,比如说用虚拟机,把这些交易从交易所挪出来,这也是一种风险。如果不挪的话,可能有很大的金融的损失,会有很多数据计算等等。我待会儿给大家讲一下为什么要这样做。
    我们看一下规模,关于规模的增加我们要了解。计算机越来越大,我们不停地买设备,IBM也许会愿意把大型机卖给大家,大多数机器用的都是服务器,可能有8到12个处理器、核心的芯片,机器就这么大了,那么如何用这些机器来应付大规模的需求?因此,我在这儿想说的是,我们不是说把电脑变得越来越大,我们想做出一些改变,我们要把编程做出一些调整。当我们在编程的时候,可能是用Java等等,我们有时候会忘记我们要做一个分布式的模型,如果你总是假设你的编程都是在本地完成的,那么这个就无法扩大它的规模,只能是最大利用你机器的能力,而不能扩展你的能力。
    我们现在做编程的时候,我们要想到我们现在在做的编程,可以在任何地方的任何一个机器都可以用你的服务,不断它的位置在哪里。我们不应该再假设在我们自己的机器上或者是本地的机器上。比如说一个序列,这个数据可能不在本地机上,比如说1T的数据上,你需要把它分布在不同的机器上,我们要逐渐改变我们的编成的模式,这样的话,我们把它的扩展能力就扩展了。如果你可能是一个小的服务器,比如说我们有一些社会网络,或者说你要发很多的微博,你要想把它的规模扩大的话,我们就要用分布式的环境来做。
    我们再看银行业,10年前的时候,Grid计算,有可能是两个,十个或者是多少个电脑,我们有本地的网格,也有远端的网格,现在我们把它叫做云。云计算对于银行来说,可能有100台电脑,或者两万台电脑,把所有的这些放到一个大的楼里面,然后用一个总机器把它们都管起来,我们还要做私有云,用本地的机器联系起来,我们现在要做编程,在本单位内完成这个编程,你在编程的时候,我们还可以看到公有云,你可以用EC2,这样比较容易应用,而且也比较成熟,大家在这里都可以用得起,很便宜。可以把自己的架构布置到这里面去,编程、测试都可以使用,还可以使用亚马逊的语言。
    我们看这个云,这个现在比较常见了,它有一个键在进行工作,我们可以在微观体系下来做,我们都可以用它来部署这个云。
    我们看一下别的技术,这些就不详细讲了,简单提一下,回头再讲。这个是编程的接口,希望下午有机会给大家演示一下如何来使用,我们如何进行信息的提取,我们用分布式的存储系统来演示,这种技术我们下来也把它作为云计算的一种。每个都可以讲很长时间,像GemFire、Neo4J。他们有类似的技术,会做虚拟机的这种复制,做的非常好。他们有一个开源的版本,所以说很容易接触。还有GiagSpaces,有非常强有力的缓存,主要用于穿过EGP的低效率。12年以前是这样,那么12年以后通过努力,这种低效率已经没有了。还有Neo4J,主要用在社交网站,这个是非常好用的,今天下午我会谈Neo4J的细节,有一些是免费的,有一些是需要收费的。
    我让大家大概看一下,大致有一个了解,我们还有其他的数据库,他们不是关系数据库,我看到在银行业用的最多的是MongoDB。你可以做一些技术的隐藏,这不是一个义务,但是这是有用的。HBase也是非常有用的,还有Cassandra,所有这些技术都用的越来越多,它们各自有优势,也有缺陷,就看你是不是需要建立关系数据库来取舍。我们如何比较,这是很难的。多数技术的存在已经有10年了,至少是8到10年。在6到10家银行,他们其中的每一家都已经采用了这些技术的多数,我打交道的这些银行,有十几家,甚至他们的客户,甚至是20多家,每一家公司至少采用一种技术了。
    有一点我注意到,他们投资很大的是这些技术,所以说他们银行采用很多人员来下载,来比较这些技术,取决于他们的程序,还取决于经理人,每次测试的结果可能有所不同。因此,每一种技术,有时候会显得很好,显得很有效。所以每次比较,可能怎么操作会导致结果有所不同,我在这儿要说的是,不是一件比较容易的事,我也不能说这其中哪种技术是最好的,它们都有优势,有它们独特发挥专长的领域,就看你怎么使用。
    刚才已经给他们看这张幻灯了,我改变了几张幻灯的顺序,我把几张幻灯删除了,这样保证我能够及时地做完我的演讲。我给大家讲过了,Gemfire,还有Terracotta,它用的是虚拟机。
    我总结一下我的演讲重点,首先NosQL,这是一个每天化的技术了,它速度非常快,每一秒可以发出几十亿个讯息,这个技术也不复杂。如果有兴趣的话,你可以用你的笔记本编程,用Java、Scala或者是用其他的语言都可以进行NosQL的编程,而且对于企业来说非常容易使用。企业主要是指大企业,你处理的数据量很大,还有社交网站也是如此,银行业也是如此,我觉得这种技术非常激动人心。谢谢QCon,谢谢凯文给我这样一个演讲的机会。
    主持人:下面用热烈掌声欢迎百度基础架构师肖伟为大家介绍百度下代的云平台。
    肖伟:非常激动能参加这么一次盛大的聚会,今天给大家带来的是百度下一代云平台的介绍。首先自我介绍一下,我以前是基础架构部的架构师,现在是云移动时代的架构师。
    先简单介绍一下百度云的发展。在百度来说,到底有几朵云?大家觉得百度是一朵云,其实是不对的。首先百度有一个专有云系统,它是支撑百度的内部业务的,有一些功能和服务是可以开发出来的,让第三方开发者使用,这些人可以支持百度的宽计算以及他们自己可以搭建一个网站和业务逻辑,于是我们将这个技术开放出来。
    当我们在做开放平台的时候,我们发现了一些问题,开放技术和开放资源并不是开发者想要的,或者说只是开发者需求的很小的一部分。
    第二个,纯粹做开放云,纯粹做公有云计算的这么一个企业,它的盈利模式非常单薄。所以在国内纯粹做开放云的企业,其实生存也很困难。于是我们想结合公有云和开放云这两套系统推出百度的个人云活动,能够非常有效解决企业的开发动力和开发者的需求,我们提供给开发者的不仅仅是技术和资源,还有更多。
    先介绍一下百度专有云的系统架构,就是支撑百度内部业务逻辑的,包括搜索、广告和社区。专有云由两部分构成,一部分是百度的硬件基础架构,包括自建的数据中心、网络和服务器,服务器是我们自己定制的。上面一层有我们的软件基础架构,底下是大规模数据存储和大规模数据计算构成的,下面做了一个云平台和数据智能,云平台支持在线业务的快速开发,计算是分析迭代。下面这个框是百度的专有云计算,这块的技术细节就不讲了,主要讲一下百度专有云的几个特点。
    第一个是百度的计算类型。我们在做大规模数据计算的时候,我们只是把它当做通用的批量数据处理的一个模式来做的,还有一种是高性能计算,它是适用于大规模的学习。这个时候大家可能会问这么一个问题。数据的总链非常小,如果用Map Reduce,每一轮迭代把数据写到磁盘,整个的通讯开销是非常大的,不利于我们多轮迭代。因此,我们需要做一个高性能计算,直接将数据通过网络传到下一代。我们把它叫做高性能计算系统。
    有了这两个计算系统,我们认为不够,还有第三种模型,叫代理计算。在去年的QCon上是一个主题演讲。百度现在有大量的机器,但是这个机器现在的负载不是百分之百的,它可能只有50%的负载,甚至更低。为什么?因为百度的服务是不允许出错的,我们为了保证服务不出错,必须保证两倍的冗余,比如说有一个机房挂掉了,百度不能出错。在这种情况下,一台机器只有50%的压力,剩下50%怎么用上?你不能用,因为你不知道什么时候会出错,一旦有一个机房挂掉,这个50%的压力就上来了。我们为了利用空闲的冗余资源,我们提出了代理计算的模式。当我需要计算的时候,将这个计算节点部署到空闲的机器上去,如果这台机器突然有人上来了,我的代理计算会发现这台及其的负载变高了,那么我就进行自杀,把这台机器的计算杀掉,或者是调到其他的空闲机器上去。但是由于代理计算这种不确定性,我不知道这台机器的负载什么时候很高,什么时候很低。因此,代理计算使用类型是那种计算密集型的。这个就是百度的三种计算模型。
    基于这三种计算模型,基本上能够涵盖百度现有的在线分析业务。再讲一下大规模处理系统。大规模处理系统分1.0、2.0、3.0。
    首先讲一下百度的1.0存储系统,我们分了三类,一类是在线KV存储系统,另外一个是海量的高吞吐的网页存储。这两个有什么区别?一个是实时的,一个是离线存储的,就是写进去不一定能够马上读到,大概延迟几秒。但是这套存储系统能够把网络带宽给打满,能够保证整台机器完成利用上去。第三个是离线的数据备份。
    1.0系统在很早以前百度就已经用了,去年开始我们研发了百度存储技术的2.0,今年已经上弦了。1.0跟2.0的区别在于什么?我们将这种离线的、实时的存储合并成一种新的存储架构,我们在新存储架构提供了表格系统、文件系统以及KV存储系统这种访问模式。另外我们还可以提供了分布式数据结构,这是纯粹内存型的。这个是存储系统2.0的一个特点。另外一个显著特点,就是跟新硬件的结合,以前我们看其他公司开放出来的发现,他们的存储系统设计的很牛逼,他们从来没有考虑到硬件。如果考虑到硬件的话,可能是一种很低级的使用方法。你在使用硬件的时候,没有考虑到存储系统本身的特点。举一个例子,我们设计快存储,它分两块,一块是索引存储,一块是数据存储。索引存储是一种随机访问的,访问频率比较高。快存储属于最终的数据存储,它的访问频率比较低。我们要考虑哪些数据放flash,哪些数据放硬盘。我们还才能了一个低功耗的处理器,使用这个低功耗的处理器,能够使整个能源消耗降下来,从而能够提高存储密度。现在已经做的差不多了,大概在今年就能够体现出来了。
    下面说一下百度存储技术的3.0的发展。从去年开始,我们在华东、华北、华南建了三个IDC集群。以前我们在谈分布式存储的时候,都是将分布式存储放在一个IDC里面,但是现在一个IDC放不下了,这个数据链一个IDC存不住,因此我们需要做一个多IDC的统一存储系统。
    现在说一下IDC现在的状况。在做这个IDC,我们分三块做:过去、现在、未来。过去,百度当时很小,主要是租用其他第三方机房,那个时候也就1万台左右的机器。今年去年我们主要以租用为主,自建为辅。到明年,我们今年已经开始工作了,明年将以租用非辅,自建为主,我们采用一些创新技术,更注重能源的效率。百度现在机器增长是每年翻一番的,如果不考虑自建机房,没有一个机房能够装的下百度的机器。这些数据已经得出来了,第一,服务器的单机功耗是降低15%,成本降低5%,整机的电源损耗、分散损耗,电源成本能够有效降低20%到50%。
    百度有着非常好的技术积累,希望能够开放出来来回报社会,就是给开发者用。这个时候就有了公有云到开放云。开放云,我们有一个分布式的云环境,我们提供了大量的IDC服务。这个是业界比较流行的云计算平台,我们在这个基础上还提供了开发环境以及对业务的支持。另外我们将百度的API也开放出来,能够让开发者直接在这个平台上使用API,包括百度帐号、贴吧的帐号等等。我们在开发云的时候,发现现在云平台没有对手机做很好的支持,所以我们提供了一个手机开发支持的APP。
    百度的框计算,它展现出来的APP跑在我们的云平台上,大家输万年历,地区页就是万年历的APP,它是跑在云平台上的。另外将这个云开放平台给发布出来,今天百度的展台上,我们带了几百个邀请码过来,大家可以去领。每个邀请码免费资源一年有2000块钱左右,能够扶持一个比较小型的应用。另外这个云平台,还是国家863计划的云专线,也是参与了国家云计算标准的制定。这个是开放云平台的首页。
    我们在做云平台的时候发现一个问题,业界的云计算系统过少的考虑了移动的整合,无论是亚马逊也好还是谷歌也好,在开发一个应用的时候,都觉得是一个网站。而现在就是一个手机应用为王的时代,我们现在是不是有一种云平台能够支撑手机的开发?支撑手机开发要解决一个问题,就是云到端的问题,手机访问云有什么问题?第一个问题是耗电,第二个问题是连接不稳定。第二个是耗带宽。我们希望用一种技术将手机和云建立一条稳定的连接,这样能够帮助手机省电、省流量,而且帮助手机做更好的适配。比如说里在开发云上面,开发出这么一个杂志的应用,如果我是一个手机用户,我去浏览这个杂志,那么他打开的不应该是个网页,而应该是个APP,这个杂志展现出来的效果应该是手机上显示的效果,它应该有触摸屏的特效在里面,这个功能是我们要支持的一个。我们通过重动,以后数据在重动过程中的加工,将一些不适合手机浏览的直接变成在手机上能够非常舒服的浏览和感知到的应用。这就是这条线是重动,端跟云之间建立了一个可靠的连接,能够帮助手机省电、省流量。我们看一张图片,如果这个图片经过重动传过来了,比如说你在4兆的图片,在手机上浏览只能是适应手机分辨率大小的图片。你在看一个视频的时候,看一个土豆的视频,土豆的视频很大,虽然它是1024的,但是也有一两百兆,但是手机浏览的时候,我们会根据重动,我们把这个压缩,这样你直接在手机上播,非常省流量。
    重动还有一个比较好的特点,PC端访问web端,都是PC端直接发起的,比如说一个用户给我发了一条短信,你不可能天天去轮巡,在传统手机开发很难实现,但是重动就很好实现了,一旦手机和云建立有效的连接,重动可以把云上面的消息直接推给用户。这个是开放云在手机端、移动端的考虑支持。但是我们想,完备的一个技术实力只是开发者需求的一部分,作为一个完整的开发者,技术固然重要,但是不是全部。开发者面临四大环境,研发环境非常复杂。比如说开发一个APP,我们不仅要会写服务端的代码,还要会写Java的代码,整个研发环境非常复杂。另外变现能力非常有限。第三个问题,终端分裂非常严重。第一个特点就是数据分裂,比如说这个应用,我用了ipad去玩,结果数据存在ipad。如果用手机玩它,结果数据存在手机上了。另外一个问题就是营运推广很困难,写了这个APP以后,我怎么推广它?用户怎么看到这个APP?
    百度有非常好的渠道,能够帮用户去风向。我们怎么帮助开发者把这个问题解决掉?所以有了从开放云到个人云的这么一个项目。我们在谈这个的时候,个人云到底是什么东西?个人云的受众不是开发者的,而是用户。个人云是一个产品,是由百度提供的个人云平台,百度在个人云平台上面提供了云能力和数据。什么是云能力?云能力包括BA的能力,还包括重构的能力,以及冲浪服务,还提供离线下载、指纹识别,还提供百度用户的数据。这些数据我们也是可以开放出来的。开发者在这个云平台上,他去整合这个能力和数据,用户在百度上提交很多图片,这个时候有开发者觉得需要开发出一些相册,能够很好的展示这个图片,那么你就开发一个相册,做的很酷,很炫。如果有开发者觉得需要出一个办公软件,因为用户数据已经在云端了,那么只要解决文件编辑和阅读功能就可以了。我天上班的时候写了一个PPT,写到一半下班了,我把电脑一合就走了,在路上很无聊,于是我打开手机继续写,因为手机屏幕比较大,你可以继续写。写着写着到家了,手机写着很憋屈,那么就重新打开家里的电脑继续写。整个过程是由百度和开发者一起完成的。开发者只要开发一个office软件就可以了,这样的话,用户可以在多端正上跑起来。
    百度和开发者一起做这个生态系统,让用户生活云中。我们做一个比较,开放云平台和个人云平台有什么区别?简单想象一下,开放云平台是面向开发这的服务器,我给开发者提供一台抽象的可以任意扩展的服务器。但是现在从服务器的提供商变成个人电脑提供商,我们要做一个面向用户的计算机,百读不怎么会给开发者提供一台服务器了。这个东西就像机器制造商,给你一台服务器你去玩吧。我们先给用户一台云PC,用户有了电脑之后,他想玩它,上面大量的应用是由开发者开发的,开发者开发出应用以后,用户很自然的去用这个,那么百度和开发者就能够得到收益。它是面向用户的产品,它到底能给用户带来什么?
   这是用户可感知的界面,这是我们幻想的场景。用户一进去以后,云就长这样了,它有用户交流,有APP,有数据等等,你可以用手机打开这个桌面,你可以用网页打开这个桌面,也可以有电脑打开这个桌面,都可以。
    给个人能够带来什么?首先将用户的数据存到云端去,由于数据在云端,我们能够做到非常好的分享。还有就是人机交互,因为我们生活在云端,我们能够通过云将好友很好的结合在一起。这个时候开发者是什么角色?开发这研发出满足用户需求的产品,然后通过百度的渠道进行推广,通过百度的变现能力进行盈利。首先它有百度5亿的用户,另外借助平台已有的数据,而不是从零积累数据。
    接下来介绍完个人云平台之后,我们再看个人云平台是怎么实现的。这个实现要依托于百度的专有云技术和开发云技术来做的。我们在这个云平台上面会做几个子系统,一个是云存储的子系统,这个已经开放出来了,在三四月份的时候,我们的系统会开放出来,大家可以在上面玩,你的数据存在云端,可以在网页上打开这个数据,这个存储系统已经上线了。还有通讯系统,通讯系统分两块,一个是人与人的通讯,一个是人与应有的通讯,人与人通讯这个非常流行了,比如说QQ微信等等。但是人与应用的通讯很特别,我在开发云上写了一个APP,传统我们访问的模式只有一种,打开它的网页去访问,但是如果它部署在云上,别人说你今天在机场上不了网,你可以发短信给金山词霸,那么就用短信进行交互,这个是人与APP的交互。我们以前传统访问一个网站的模式,你现在把应用放在开发云上就可以用手机短信进行访问,也可以用传统的web进行访问。这是百度自己提供的子系统,还有业界非常成熟的微支付,比如说有图片和语音识别,然后提供API,让用户上传一个音频,我们翻译成文字。另外还提供广告投放的API,另外还有LBS。我们还会提供多终端的平台,我们还提供一个新的交互方式,叫HCI,就是人机交互。我们的云能够做什么?能够做风险。今天我们去交换名片,交换名片这个动作,如果是自然的交互,你拖给我,我拖给你,通过手机来完成,我们会提供这种交互模式出来。
    介绍完整个云的系统层次架构之后,我们再讲一下云生态的部署。系统架构归结为云平台,这个云平台上面搭建了一个生态系统,第一种就是百度的盈利模式,这个盈利模式有四种。一个是广告,广告的盈利模式大家比较认可,通过点击进行收费。另外一个是增值服务。什么是增值服务?比如说你用的百度的云存储之后,给用户开发了一个相册,用户用你这个相册需求之后,它有扩大自己云存储空间的需求,这个肯定是收费,这个就是增值服务。还有app应用支付模式,你下载这个应用就可以得到支付。比如说做游戏,游戏里面有游戏币之类的,我们提供微支付手段,你可以直接购买。
    我们还提供系统参加,如果百度的相册做的很糟糕,你可以不用,你可以用数据写一个相册放进去。还有第三方开发的APP。
    介绍完整个个人云平台系统架构以及生态架构之后,大家比较关心这个东西底层的核心技术是什么。我归结为三块:一个是云存储,一个是云引擎,一个是云通信。一个系统的核心,存储非常重要。我们在做云存储的时候,我们从文件系统开始说起。个人云的文件系统是一个什么样的东西?在讲文件系统的时候,我们在学操作系统的时候,这个文件是怎么存储的?用户的文件怎么存储的?我们文件分成两块,一个是Meta信息,一个是Chunk,这个时候我对文件进行切片,meta存了这个文件的切片信息,这个分布式就是一个KV存储。这个时候用户访问这个文件的时候,得到了这个  meta数据。分布式的Server,它的性能和它的数据扩容是没有问题的,我们给用户提供这个文件可以支持海量的存储。当然做一个文件系统,有一个文件是不够的,我们需要一个分布式目录服务。我们在设计这个的时候也考虑很久,这里面有两种设计场景,一个目录下面存几千万、上亿的文件的,如果用一个目录树结构设计是不对的,因为一个目录下有1000万个文件,你肯定要挂的。但是这个文件系统是面向用户的,一个用户的目录,我们认为不会有太多文件。但是我们有非常多的用户,所以只要跟用户做一次分布式切分就可以了。我们的目录设计非常简单,一个目录节点挂的文件非常有限,这个目录树是比较好设计的。
    另外就是支持权限,这个权限,我们的权限很重要,不仅要保护用户的隐私,而且还要考虑分享的便利性。这个跟传统的文件系统不一样,传统的文件系统是读写,还有普通用户,但是这个文件系统加了一个功能,就是分享功能,能够将这个数据分享给其他人。
    下面说一下另外一个特点,就是预览功能。这个预览包括缩略图服务、文档转化服务、视频转码服务。开发者将他的文件存到云存储里面去的时候,他不知道用户要在手机端浏览还是PC端浏览。我们现在是将文档转化成flash,能够手机端非常好的阅读它。PPT转码非常糟糕,我们经过转码服务之后,那种画图的工具能够很好的展现出来。app开放给开发者,开发者可以自己用。
    介绍完文件系统,我们介绍一个云存储的系统。它是基于文件系统所提供给开发者,给用户的一个东西。首先有一个PCS,每个用户都有一个根目录,下面都有我的音乐、我的文档、我的视频图片。其中应用是给开发者的,开发者每个应用都可以在应用数据里面写一个文件夹,比如说用户使用了云通讯录,那么他有一个云通讯的目录,用户可以对他设限制空间。云通讯录,比如说云通讯录,你只能访问我的数据下面的云通讯录,你只能在这个目录下读,你不能读其他的目录,这是权限的控制。
    比如说我今天拍了一些照片,这个时候出现的泰山的目录,因为有LBS,然后就会知道你这个照片在哪里,这个时候看一下目录,有图片1、图片2。比如说你现在在玩坦克大战,结果你玩的很高兴的时候,这是开发者开发的坦克大战,完了之后用户打了一个很高的分数,于是他做了一些截屏,然后数据会自动流到我的目录下。用户在使用百度帐号登录坦克大战的时候,用户会对坦克大战进行授权,是允许坦克大战访问自己的图片。于是坦克大战在产生一个高通关的照片的时候,他会把这个照片自动的同步到我的相册里面,这个时候照片能够很方便的分享给我的其他用户。比如说我是一个微博的开发者,我在开放云上写了一个微博,我是一个坦克大战的游戏开发者,我在坦克大战上写了一个游戏,这个时候坦克大战提供了一个功能,就是截图功能。这个时候提供API,这张图片能够通过微博直接转发出去。这个就是云存储系统。
    今天给大家介绍个人云平台的时候,涉及到一个端的概念。云是看不见的,但是给大家贴了一幅图,这个东西就是端的东西,既然是端的东西,肯定要用到硬件,比如说它的有可能是个浏览器,有可能是个PC,有可能是个Ipad。另外它有云的概念,我们在手机上打开一个相册,它可能里面跑了一个微吧,你用Java写的,你跑着跑着会发现,有一些功能放在云端做更好,比如说图片压缩,通过端的调度,将这个需求发给云端,云端有相应的引擎跑这个逻辑,基本上如果是个F1,就是统一的一个程序员的话,我们在云端有微吧引擎。云端执行图片压缩之后,再回给端,端再展现出来,云在处理一个逻辑的时候,突然发现有一个功能,它在端做更适合,比如说云要获取一个摄象头,这个摄象头只有端有,这个时候就把这个任务扔弃端。我们当时在开发者大会的时候给出这么一个东西,我拿了一个手机,这么拍着,这个时候我的屏幕能够看到我拍的一个东西。为什么?因为我把手机当成摄象头了,我开发摄象头的应用,手机摄象头捕捉到用户数据以后,在显示器上能够展现出来,这个时候能够把手机当成摄象头。
    云的进程,云的东西可以调给端,端的东西也可以调云。它是怎么做交互的?我们有一个云Java,云跟端的交互,是通过事件驱动的,我从端给云发一个事件,告诉云要做什么事情,然后云就做了。做完之后,然后云再告诉端我做完了。这个能够将并发性和性能做的更好。但是都要解决一个云跟端的连接可靠性和节能问题。我们通过重动技术能够做到优化。
    我们有了这么一个端和云协调工作机制之后,端利用安卓客户端,我们给端提供一个SDK,然后直接开发APP就可以了,它只是一个SDK而已。用户用SDK开发出端之后,它在云上会对应一个云的PC虚拟化。这个时候,我们在内部有一个系统,将用户真正的程序影射成Linux进程。这件事情一定要做的。我们发现机器负载,这个开发应用负载很高的情况下,你可以丢到其他机器上去。这个就是我们云引擎做的东西,是端和云的进程调度的结合。我们用了云的Java去做。它最终在云端变成一个分布式的进程。
    第三个核心技术,云通讯系统。有一个比较重要的技术是我们的重动技术。我们在端和云通讯的时候,比如说我们是可以根据短信进行通讯的,无论你根据什么通讯,我们必须给每个APP分配一个入口。如果你想用短信跟APP通讯,我们必须给每个APP分配一个手机号,这件事情是由百度跟运营合作方来谈的,过几个月我们会给每个APP分配一个手机号。用户分配这个APP,就可以给这个手机号发短信。短信是发到服务器上,我们服务器会解析用户的手机号和内容,将手机号和内容在云端转成IPC的服务。访问到你的服务之后,你就提交请教,然后把这个结果转成短信的形式下发给用户。邮件的交互也是一样的,我们需要在云端部署一个协议的解析的机器人,这样能够做很多事情。但是邮件跟短信不一样,短信的来源是可信任的,比如说短信给云端发一条信息的时候,我们知道这个用户是谁,因为号码是确定的,但是邮件不行。邮件的发件人是可以伪造的。我们邮件做端应用交互的时候,我们是不信任的,我们是建议用户做一些通用服务,然后转码。比如说你把这张图片压缩一下,你可以把图片当成附件发给云。我们基本上邮件在做这种交互。这样用户可以做很多非常有意义的事情。
    另外我们还提供了Clentap,手段端直接访问的时候,我不希望用HTB协议访问,这个时候我提供的客户端能够在浏览器接受服务,我还提供了安卓的客户端,但是在手机上,每个应用如果维持跟云的连接,这个是有问题的,因为如果手机有大量的连接,每个连接的性能会变得很差。第二,如果手机维护大量的连接,这个手机耗电会特别快。于是我们提供了一个终端Agent技术,我们能够建立可靠的连接。第二,所有流量经过agent能够进行压缩。这样我们会节约大量的流量,这个也是我们能够做的事情。第三个就是省电。虽然对每个app来说,它维护大量的连接,其实对外速度只有一个连接,这个时候能够比较有效的节省手机的消耗。同样,现在客户端有这个Agent,我们需要一些东西来支持这个服务。另外我们还提供P2P机制,回到我们刚才说的个人云的应用,我们两个人靠在一起,手机一划,然后把图片划给你,这个数据从云交互比较好,还是从P2P交互比较好?不知道。因为有可能这张图片是本机的,本机走点对点交互比较好一点,因为先传给云,在云上下载比较慢,这样就无法出现划的效果。不仅要建立端跟云的连接,而且还要建立端跟端的连接。这样能够把数据很平滑的传过去。点对点的应用,由云做媒婆。P2P有视频播放以及这种大文件下载,也是需要P2P的,我们这种技术提供给开发者的。
    我一直强调人跟云,人跟APP怎么应用的,我再强调一下人跟人怎么交互,开发者不需要开发一个人类工具了,而是直接使用百度的好友系统以及百度手机上的一些客户端,直接用就可以了。这样就完成了人与人的交互。个人云存储系统就涉及到云引擎技术,然后构成了一个个人云平台。我们结合变现、系统及服务以及第三方开发者服务组成一个生态链,就是数据和技术、百度的渠道、百度的变现能力,这样使开发者做APP研发过程中能够做的更好。
    我们知道个人云现在正在开发中,等开发出来以后,我们相信随着技术进步,尤其是光纤入户,随着嵌入式系统的普及,我们可以想象一下,有一天我们能够做到我们的端直接给我们的设备进行通讯。设备包括微波炉、电视、热水器,因为他们只要装了安卓,我们有能够通过多种方式操作他们的工作。大家可以到我们百度展台上体验我们说的这些产品。
    
    主持人:第三场演讲来自DailyWTF.com网站的编辑,他今天演讲的题目一开始的时候也介绍了,他关注持续集成,他们同时认为软件研发不仅仅是持续集成,接下来我们用50分的时间听听Alex Papadimoulis是怎么理解的。
    Alex Papadimoulis:谢谢诸位,谢谢QCon给我这样的机会,这是我第一次来中国,我感到非常兴奋能够有这样一个机会。今天我的话题是CI++,就是要超越持续集成。我想给大家做点背景介绍,我以前做过什么,我的经历有哪些。
    很多人了解我都是通过DailyWTF.com网站了解我的,我们做一些灾难故事和错误编码,做一点好玩的东西,有时候我们也来点严肃的内容,就像今天一样。
    从我的职业来说,我们是制造软件的平台产品,叫Buildmaster,所以对持续集成这方面的理论也做很多研究。除此以外,我以前也给大小服务公司工作过,包括医疗卫生的,还有制造业的。我注意到很多公司有一些相似性,不管是医疗卫生还是制造业,他们软件的研发过程都是比较类似的。在谈持续集成之前,我先做个调查。你们当中有哪些人采用了持续集成?差不多20%吧,通过我的观察。有哪些计划想用持续集成的,但是还没有用的?还有哪些人没有听说过叫持续集成的?好象一只手也没有,让我很高兴。这证明很多人都知道什么高CI。最起码听说过一点。
    在做扩展演讲之前,我们需要对它做一个定义。我第一做CI演讲的时候,我犯了一个错误,让听众定义什么叫CI。就像你们一样,他们一开始以为自己知道什么叫CI,但是实际上并不真正确切的知道。因为CI是一个很广泛的概念,很多年以前,在90年代末或者是21世纪初的时候,有几位他们想搞一些EXTREME,这里面有一个持续集成的概念。在数据里面,在他们的实践里面,在他们的文章里面,他们都对持续集成做了定义。但是从我来说,持续集成是一个演变的概念,我们原来所发现的东西,原来有的东西现在已经不再真实了,已经发生演变了。我觉得我们还是要用一个比较实际的定义。持续集成,有两个字眼进行定义最好,就是持续跟集成。有人说做定义不能用字面这个本词,但是我觉得还是用这两个词最好。
    我们谈所谓集成,首先来讲讲集成测试,这是作为我们软件开发的一个部分。实际上有两个层面的意思。第一,代码层面的集成。这是最广泛意义上的含义,在编码层上做集成,要保证尽可能的在原代码增加尽量少的代码,而且不让它崩溃,也就是说在你添加这个新的编码的时候,要尽可能的少,同时不让整个的体系崩溃。这是谈编码层面的。还有零部件层面的,当你对这些零部件做一些变化的话,那么就会引发其他单元块的变化,甚至整个体系会崩溃。因此,我们就有了一些所谓静态的测试工具。但是Component测试,要保证每个单元块能够很好的协同的运作。因此,在概念上来说,做测试非常简单,我们要做三样东西,一个是要获得这个代码。然后我们建造代码,它能够告诉我们代码的编辑是不是有问题。第三步,进行编码的测试。
    这就是集成,什么叫持续集成?持续集成,当然指集成是持续的。持续集成实际上并不是真的持续的在做,只要一个做完以后,下一个就继续开始了,它可以按照计划来进行。按照计划进行持续的集成,可能是每天一次,也可能是七点,也可能是六点,对于编码进行集成。
    对于他们来说,这种激发式的持续集成,只要你嵌入一个稳当,这样的话就有一个新的Builds,这个时候就激发了持续的集成。我们可能有不同的来源。这样的话,定义相对比较宽泛一些。我们要知道如果没有这种自动化的过程,这个是无法实现集成的。不仅是在CI适用,而且它本身就很重要,不可能说找个人每天早上去看是否要完成集成,比如说你对这些原代码进行检测,看什么时候需要。可能很多人对这个概念很熟悉了,很多单位都在使用,比如说我们今天做一个测试的话,大家都知道CI有真正好处?为什么CI能够带来这么多好处?它有一种敏捷的生产流程。你在做集成过程中要考虑到风险的控制,只要做一个改变,可能就有两方面的影响,比如说你做一些小的变化。
    我们做这些精益生产或者是敏捷生产,要考虑到这是一个尝试,你改的越多,变化越多就也容易出错。现在如果编写软件的时候,可能有很多不同的组成部件都要同时进行。我们再讲一个想法,如果现在你还没有开始做这个CI的话,你现在应该开始了,今天就应该开始了,因为这个很容易。你要有一个CI的服务器,你可以在自己的工作站上逐渐开始。有些系统崩溃的话,你就说有些系统崩溃了,不仅仅给自己用CI,这个是在写的时候就可以写进去,如果其他人想用的话,那么也可以使用。
    我们现在说一下CI++。我们要考虑到改进、提高。首先要做一个全面化的,要完整详细,这是一个纵轴,我们要考虑到这个概念,用同样的方法要完成更多的内容。很多的行业都要考虑到我们做事情要完整,要全面,还有很多人考虑到这个范围扩大的不够广,我们可以自由的发挥,把它的范围扩大。但是实际上要做出改进的话,我们要考虑到横轴和纵轴。先考虑一下纵轴,就是全面完整。我们刚才谈到了CI是什么,它是如何来的。这个人是最早开始做CI系统的。如果有一个课本上对CI的定义,当然这个不仅仅是课本,它不是一种非常学术化的东西,它是一种操作性非常强的东西。这个人说了很多具体的方法,能够使自己的CI更好一些,做出更多的改变,这样可能会更好一些。
    如果失败的话,它会回滚。这样把Builds失败了,代码回滚,会回到原来的状态。但是这个也比较复杂。如果里再潜入一个东西,这个时候会做一些改变,改变它也会有回滚。这都是一些比较好的情况。
    我们刚才谈到了自动化,我们还有很多的集成是可以自动化的。比如说测试,测试本身就是自动化的编译。对于静态分析来说,很多人比较熟悉。举个例子,我们看片子上显示的做的静态分析,你不知道它是否存在,然后你用相应的工具,静态分析的概念,使你每次做CI的时候能够做出一些改进。我们看单位测试,大家也都很熟悉了,我们在做CI的过程中会很熟悉这个单位测试,当你使用某一个工具的时候,做测试的时候,或者是做代码覆盖,这都是一些比较常见的代码。哪些做了测试,哪些没有做?在我们的代码覆盖的工具上,71%的数据都被覆盖了,还有61%是简单覆盖。
    我们看这些数字,当然也会有一些风险在里面。我们要开发出一些代码来,这些数字告诉我们,这些代码它们有多么好,现在是61%的好,但是也可能做的更好一些,可能做到85%。有些人对这方面考虑比较长远,他们的方法是,如果你没有达到百分之百的代码覆盖你就不够好。这个观点还是要求比较高。那么你们在做单位测试的时候,可能要做一些比较好的回应,要求你一定要达到百分之百的覆盖,如果达不到百分之百就不高。
    我们在做测试的时候,比如说医生给一个病人做检查的时候,不必要说把所有的项目全都检查一遍,只要把这个病人的问题解决就可以了。因为如果你要把所有的测试做完的话,这个成本会非常高,而且意义不大,这样做出的诊断就相对比较少了。当然从医疗的角度来看,它就是一个比较好的例子来我们达到百分之百,我一会儿给大家举一个例子,几年前我买了一个房子,这个房子不够好。这个房子质量当时比较差,在市场上卖了好几年,没有卖出去,所以买过来以后需要做出很多的装修、调整。
    大家看这是卫生间,这是厨房,我们要装修,要把好多功能调整出来,使人可以居住。我们把房子里面好多东西都拆了,通过这个装修过程,使我对建筑了解了很多。就像软件一样,当然从建筑业来说,我已经很长时间不接触了。现在我通过装修过程,我理解了很多,把那些东西拆了拿走。当时是用做软件的方法,然后把这个房子重新装修了一遍。其中有一个人,我们要让不同的人做不的工作,其中跟我合作的一个人是我的一个木匠。这不是我真正用的木匠,是从网上找了一个照片。老房间改造有一个需要注意的地方,有很多问题需要解决,比如说很多不是眼睛能够看见的工程,在房间里面,在墙里面的内容。这样的话,要请一些专业人士,比如说木匠,要让他们对房间先做一个摸底,把比较暗的工程解释清楚。
    举个例子,这个木匠给我做了一些活,我说你再给我做几个书架,我当时在头脑想的就是这么一个很简单的东西,我可以请他做,也可以去市场买。我觉得当时做一下比较便宜,像这种钢铁的书架就很容易移动。我的木匠做活比较细,他把自己做的这些书架全部油漆了一遍。最后做出来的效果非常不错。我说你为什么不做成可移动式的?他说他不愿意做那种可移动式的书架,他觉得不够好,他觉得这种传统的比较好。他希望他做的活能够得到大家的喜欢,他是参与到这个过程中来,这是手艺人的想法,他有非常强烈的愿望,他希望把自己的活做的非常好,非常完美。所以他对自己的工作做的非常完整、完善。这是纵轴。
    再看一下横轴,就是可扩展的范围。在现实中,这些高质量的代码,有的时候也没有什么意义。一个好的软件,它不仅仅是由一些代码组成,不是说我们不想要这种高质量的代码,而是说仅仅只有高质量代码无法形成一个好的软件。我们是想让大家知道这个编码只是做成软件中的一部分工作。我们刚才谈到了CI,就是持续的集成,它实际上也是整个软件测试的一部分,软件测试包括很多了,它只是软件开发的一个步骤。我们看每一行,这都是软件开发的一个组成部分。只要其中有一个部没有做好,那么可能软件就是一个差的软件,就不够好。
    我们看底下比较简单的内容,通过批准,当你写代码的时候,还要考虑时间,你要考虑到这个是不是按时完成,是不是足够早的完成?希望今天能够有足够的时间把这些都介绍一遍。我刚刚谈了我自己的房子,可能占了点时间,不能全部讲完。
    我们谈一下将范围扩展,在软件开发的时候,有时候要考虑到不仅仅是开发这块,有时候它只是一小部分内容。我刚才谈的这些可能没有趣味,没有意思。如何使软件更有趣味?我们可以把代码、软件扩展到其他的领域。首先我们看一下环境,比如说生产过程,在我开发软件这么多年过程中,实际上大家不能前后一致定义的很清楚,意思经常变。
    我们看一下环境,环境就是要确保测试环境完整。我们在测试的时候有五个环节,每一个环节都不一样,像集成测试,比如说某一部分要发挥作用,功能测试,我写的这些代码,它是否能完成它应该完成的工作。我们都很熟悉这种测试过程。可接受测试,如果这个软件代码能够完成它所做的工作的话,有时候人们可能会改变他的要求,有时候可能有新的想法。如果事情不能做的更好的话,那么就没有意义了,还有质量测试,就是看代码需要完成的工作,如果不能发挥作用的话,那么就不够好。最后是阶段测试。这个完成以后可以了解软件是否将来可以部署到应用的地方。阶段测试也是很重要的。
    我们在考虑到环境的时候,做环境的时候也要考虑到这些测试,不同的环境有不同的拥有者。拥有者,也就是说谁进行运维,从环境的角度上来说。因此,可以做一些分解。有一个环境,像一个砂箱一样,这里面不是一个很干净的地方,是一个很脏很乱的地方。从集成的角度上来讲,对于运维和开发者,他们可能有不同的责任,你们你越往上走,越有一些控制,那么第三方开发者就不能再进入这些环境了。当然要取决于你有多少个开发者,如果只有一个人,当然他可以对自己有非常好的保护。如果一个生产环境很大的话,那么你要非常小心,在这个环境的控制方面。你越靠近生产的时候,环境就更符合生产的要求,这是最佳实践的一个部分。
    在分段环境当中,你应该尽可能的封闭化,因为这里面会有一些操作系统,还有一些服务器在这个环境里面,不能让谁都碰。另外,我们刚才谈到五六种测试的类型,我们要考虑五六种测试的环境,也需要一个网站来提供支持,来做一做运维手册方面的说明。我强调有些人要退出,让有些人放手,通过一些程序的部署、工具的部署,使得一些开发者不能进入砂箱的环境当中去。
    下面再换一个话题,就是版本发放的管理。这在软件的开发当中是非常重要的,我们知道发布管理是非常重要的。我们从最基础的说起,软件实际上是几种应用的一个集合,把不同的应用集合在一起就形成了一个软件。作为一个组织,可能会有不同的几百个这样的应用,这些应用可能还会有一些不同的发布周期,发布主要是打一些补丁,有一些新的变化。但是每一个发布都是基于以前的发布之上的,然后还给他们一个版本号,在管理的时候,你要建立起这样一个很好的发布程序,编码号是大家都能很好理解的,比如说1.0、2.0、2.5。所谓Builds是一些尝试,来满足发布的需求。Builds会影响整个的生产,什么叫Pormtions?是把一个软件从一个环境转到另外一个环境当中去。这需要一些批准,需要测试。最终发生的事情是进行部署。有时候只是一个文档,有时候把一个应用从一个环境到另外一个环境的迁徙,或者是数据库的变化。这种部署,使每一个Builds里面都会有不同,因此,我们要有分层的意识,如果我们考虑到、崩溃,我们要知道我们在哪一个层面,我们不要把Pormtions跟Builds搞混了,因为它们属于不同的层次。所有这些层次都是非常重要的。
    我们说发布跟Builds是不同的,如果要谈Release的管理,大家要注意builds跟Release的不同,一个Release里面可能会有很多Builds,很多Builds在Release发布之后就丢掉了。这是变化最骨干的部分。谈到变化,我们也要谈一下对变化的影响因素都有哪些。最好的方法是维持一个电子表格,因为我们要对术语一致化,这个术语有时候人们不是很好理解。这里面Bus都是非常喜欢电子表格的,他们只是对表面上看着好的,对数字化的感兴趣,对其他的不感去。在这里我们要强调过程。
    谈最后一个话题。这个话题就是配置文件。每个语言都有一个配置文件,不管是Java,还是Scala,Java可能有几个配置文件。配置文件它是一个针对特定环境的一种文件。它含有的信息是让应用了解这个环境,但是还有其他的一些配置,像API这些配置。对配置文件进行定义的话,我们要看这个配置文件是不是两个环境都用同样的文件,如果是配置文件就不称之为配置文件,配置文件是针对某个特定环境的。另外要注意所谓伪的配置文件,什么叫伪的配置文件?有一些文件看上去像配置文件,但是含有的东西,是每个环境都有的,它并不是具有环境特殊性的。比如说在这个屏幕上看到的,它有一些指示,每个环境都要一致的。因此,它不是一个具有环境特定性的文件。
    因此,非常简单的一个原则,只要有所谓的KEY  VALUE,如果它之外还有别的东西,它就不是一个配置文件,因为它不具有环境特殊性。我们看到Java它已经把它的一些特质放在环境里面了,其他的一些配置文件需要考虑的点,有一些配置文件,比如说生产环境需要的保管方式跟其他的不同,需要建造一些过程,而且要围绕着配置文件做一些东西。
    最后几分钟我做一点总结。我们谈了三个不同的话题:环境、Release的管理,还有就是配置文件。这些都跟编码,跟软件,跟code好象没有什么关系,跟如何写更好的代码好象没有关系。但是在编写软件中,它们是很重要的方面,如果这个领域想做改进,就会使整个软件的质量大大提升,而且变化的影响比对编码变化带来的影响还要大。所以希望大家继续,就是说要超越代码的编写,我们需要持续的集成。谢谢。
    主持人:再次感谢Alex Papadimoulis的精彩分享,接下来是午饭时间。
    主持人:今天下午我是代替冯大辉来主持的,我对每一个人的演讲资料都看过了,但是可能看的不像冯大辉那么仔细,主持的不是非常专业,请大家谅解。接下来是今天网站案例架构分析第一场的分享,来自于4399架构部的负责人曹政,他分享的题目是分布式数据库设计与反范式设计。
    曹政:大家好,我是曹政。这是我个人的微博地址。为什么要做这个课题?其实我们并不是说特别强调这个概念,分布式设计怎么回事。我们实际上在开发过程中,在用数据库的过程中,特别是在做分布式数据库的时候,或者是做性能优化的时候,如果我们的数据库基于反范式结构来做,有一些问题不好解决,对整个性影响很大,我们主要是做去关联化和一个冗余的工作。这个跟互联网上提的反范式设计思路不谋而合。我们把工作中遇到的问题和解决思路整理起来,跟其他人对照一下。
    反范式设计分布式数据中的一些问题,它是一个衍生问题,并不是为了反范式而反范式。先做一个个人简介,其实我不是一个技术专家,在这个会场,在这个位置上我是比较逊的。但是不是技术专家,有一些地方也跟大家分享一下,首先做这个事情不会关注这个技术的深度怎么样,我以前也在很多公司待过,我发现有一些技术人员,有一些比较牛的技术人员,有点拽,非要挑战一下技术,非要把东西弄的很复杂,很庞大,其实很多情况下不需要。一个小公司,公司非常小,非要搞一个很复杂架构,何苦。技术工程师不要去炫耀,不要去写一些很奇怪的东西。
    冯大辉在博客上发了一个东西,分析了国外十多亿美元的技术架构,他介绍的都是第三方开源的产品,那个公司才13个人,为什么做出这么好的产品?不是因为他们每个人都是天才,而是因为他们站在天才的肩膀上。第三点,我这个人不是技术高手,但是我可能会做出很多事情是技术高手不如我的地方。
    信奉简单,这是我在公司经常说的。你要想复杂的话,你一定想错了。很多东西是有很多简单的处理方法。我很强调一点,技术是用来解决问题的,而不是制造问题的。这其实是对公司资源的一种浪费。这都是我的一些观点,跟大家分享,包括抓大放小。我们性能问题,比如说一个系统性能问题中的100条,是不是100条都要解决?我们每次只解决影响最大的两条,哪怕解决了前面10条,可能性能就变得的非常好。特别是我们一些公司都是轻公司、快公司,我们要抓效率,要跟竞争对手拼时间,那么我们一定要抓大放小。
    杂而不精是个人的特点。给大家一个忠告,这个忠告只写了一半,技术的价值取决于产品表现。比如说一个技术高手出去应聘一些简历的时候,面试官会问你之前做过什么产品?你说我做过百度搜索,做过QQ的用户中心,人家一听你就是高手。技术的价值取决于产品表现,但是另外一句话没有敢写,产品的表现并不完全取决于你的技术。很多情况你产品的用户观、用户体验,它对你产品的表现有很大的影响。特别是一些小公司,或者是成长的公司,技术工程师不要只盯着技术,要多盯盯客户,双方不理解,多去理解别人的想法,多去理解这个产品它在表现中的一些东西,对你的成长、职业发展有很大的帮助,这是自己由衷的一个建议。不要认为技术就是做技术的,就是在那儿写程序,做数据库,一定要看看用户的需求。
    刚才说的是一些废话,但是希望对大家职业发展有帮助。下面说一下分布式数据库。说到一个前提,我发现一些小公司的人会跟我讲,现在机器不值钱,是不是只要有流量负载就完了?其实基本工作还是要做好的。所以优化还是要做的,你首先性能要调的比较优,包括前面应用缓存也要做,不能把所有的压力放到数据库上来。我们做的也不是特别好。我们的负载、流量确实达到一个很高程度的时候,我们再考虑分布式的事情。有一些技术人员觉得学了分布式,是不是就不考虑单机优化了?这个还是要考虑的。
    简单的一个数据概念,经常就一些朋友问我,我现在数据容量非常大,一个数据100万台是不是要分点了?我说100万点台分什么点,还早。我的观点,在几千万条以内没有必要分点,一个数据点能够跑的非常好。你单机优化,如果做的很好,它可以支撑一部分。包括查询请求,我们服务器也不是那么好,如果说就是普通的一些查询,基于一个索引,你至少在每台服务器上能够支撑到1500台以上,你再去想说负载确实很高了,需要分点了。如果说每小时支撑十几次、100次的搜索就撑不住了,你就想去做分布了,那么你肯定有一些地方有问题,你先去把它有话好。
    协助请求也是,你一秒钟至少要写几百次以上,写几千次也很容易。如果写几十次数据库就撑腰不住了,那么还是要在本地做优化。对于大众公司来说,一定要有这个概念,每天有几十万人的访问,就开始想分布式了,其实单机的性能真的可以做到很高。
    这是一个前提,首先要把这些事情做好,但是有一些内容,像索引怎么优化,运维怎么优化,其实这个内容今天就不展开了。我最后会分享一个稳当,也是我们自己的一个文档。
    我们做分布式数据库肯定要考虑设计目标。很多工程师跟我讲,省钱。省钱对吗?不能说它不对,但是有一个问题。老板想的不光是省钱,还有赚钱。为了赚钱,必要的投入是值得的,省钱不是唯一的目标。在这种情况下关注成本的可控性。成本投入跟业务增长的关系是能够控制的,线性增长,它的底线,就是成本加几倍所获得的流量支撑能力提高几倍。最好能够收缩,比如说曲线能够往下收缩。如果这样的话,前期有一些额外的开销,它后期可以收缩。如果是指数曲线,业务增加一倍,成本增加两倍,这个生意就没法做了,因为它不可控,到一定程度成本超过收益,这是不可控的。这个东西设计的时候,它的计算量跟业务量要有一个可控的指标。
    还有就是扩展性。有一个很典型的例子,刘向东在微博上公开喊话,给你3倍服务器,把3倍流量给撑下来。但是它其实就是一个业务的目标。希望投资资源之后能够快速地扩充能力,你的目标,能不能做到3倍的服务器插进来能够支撑3倍的流量,这个就是我们要做这个系统时候的一个设计。
    还有一个就是可维护性。其中比较重要的一点,单点故障的隐患,其实有很多种方案,但是我们在做分布式数据库的时候要想一下,如果有一个节点,这个节点瘫痪了,导致整个事情不可用,那么这个叫单点故障。我们希望这个机器瘫痪以后,有机器能够替换它,而且是自动的。这块也非常重要。备份与数据安全。从热备转化到热备,这都是一些数据安全的一些东西。当然还有其他的。
    实际上我们做分布式数据库面临的挑战主要是数据量不断增加,几十亿条了,单点的结构化比较难操作。还有就是业务请求,一个是读取请求,一个是写入请求。这个是我们要面临的挑战。实际上不同的场景面临的挑战不一样。在不同的挑战情况下,所采取的措施也不一样,在这个情况下没有一个标准,就是找一个平衡,现在大家都明白,有的时候用CPU换IO,有的时候用内存换IO,如果读取压力非常大,用IO换CPU。这个情况也有。通过一些写冗余可以把这个进行优化的。
    很多小公司很喜欢用主从结构,它优点部署非常简单,但是问题在哪儿?第一,IO的压力不能分布,在这块有一个非常大的问题。可能从的写还不如主的效率高,这当时淘宝他们在微博上发的,他们做的真的是从的写入效率不如主。两台服务器性能效率还不如一台服务器,多台服务器提升的效率有限。在这种情况下,它的性价比并不高,你增加成本是不合算的。第二个是同步延时,这是躲不开的问题。写完了,从没有同步过去,然后导致一些七七八八的问题。实时性要求比较高的,这个地方是非常头大的事情。第三,主数据库,它是一种多从的情况下,用从替换它,如果一台服务器,你替换它没有问题,但是从替换了主,那些从跟谁同步?这个是没有办法自动替换的,因为它整个文献,这个东西非常头疼。主数据库典型的单点隐患,如果和很多个从在一起的时候,这个点就没法做了。这是三个比较大的局限性。但是它也可以做一些什么?比如说在线热备,一台对一台没有问题,它挂了,我直接替换它,这个没有问题。
    上次也是在QCon,我听于峰(音)讲,他说淘宝的数据库是16个主,16个从,一对一的结构,其实我觉得可能也是这个思路。当时我受他这个启发比较大,他们公司在一主多从的情况下也不是特别有把握。后来我私下问过他,主挂了怎么办?他说用从替换它,一台就能够扛住。
    另外一种方法,把数据库分开,这样就比较好了,负载分担比较好,这个数据表比较大,或者数据库有1000个表,500个表,你可以分成几个表去做。这个也不存在延时,然后拆分方法也很灵活。我推荐的是用分布分表做支撑方案比较好一点。用主从结构做故障转移方案,我们做一些小调整,调整也不多。amoeba的特点,你的拆库方案,你只要把方案告诉它,你前端的应用程序,你连接到omoeba,它根据定义的拆表、拆库的规则,把你的请求解析到不同的数据库中去。它如果说要做连表查询,它会有些障碍。所以在这个时候要去关联化的处理。
    分布原则有三个大原则:基于业务拆分、基于负载拆分。第三种,基于安全性的拆分。如果基于安全性拆分,我要保证安全性,在这种情况下,是基于效率优先的写入性能,差90%到99%。在这种情况下,很多公司说性能优先行不行?有一些业务人员说我的数据绝对不能丢,比如说用户的支付信息是绝对不能丢的。你看看这种绝对不能丢的数据有多少?只有很少,大部分数据,如果设置为2,它会在服务器断电丢失最后一秒钟的数据。所以可以做一个拆分,把安全性比较高的数据,把支付数据拿出来,用安全性优先的参数来配置这个数据库服务器。这样有限的情况下能够实现性能与安全性比较好的兼顾。如果不是这样的话,可能要么考虑性能,要么考虑安全性,这个成本还是蛮高的。
    我们说的方法是混合策略,刚才说业务拆分、负载拆分,我先说拆库。数据库中有很多数据表,我基于安全性把一些安全数据表拆出来,肯定安全性优先,我把剩余的业务再进行拆分,最后发现论坛的负载比较高,然后再分成第一、第二、第三。ABC负载不高,拆出来之后放在服务器上,开三个端口,B负载非常高,我要重新利用硬件资源。这样的话,你拆库的方案非常灵活。
    说一下拆表,拆表包括纵向跟横向。大家比较常见的是基于记录去拆,比如说用户信息表。我们发现一个U字型,它字段非常多,有一些用户个人信息介绍,用户的职业背景等等,你发现都是字库串类型的,但是修改的频率并不是很高。还有一些信息,用户的最后登录时间、用户的主业访问次数、用户的相片数,你发现这些数据都是整形的,而且经常更新。这种情况下有一种拆表方案,一种不经常更新的,但是又都是字库串类的拆成一个表,这是纵向拆表。
    在这种情况下,一些极端情况,我们发现纵向拆表也不够,用户会经常加很多莫名其妙的好友。在这种情况下,我们甚至把这个字段单独拆出来,从数据库中拆出来,专门去存这些频繁更新,又是基于主件产生的字段。等分拆表,拆分的条件是什么?这个拆分的条件要跟你常见的查询是绑定的,如果说拆分是基于A去拆分,那么基于B查询是没有办法查的。但是基于A+B查询没有问题的,B+C查询就没有办法查了,这个就是反范式设计中需要注意的一点。这个地方,在拆分的时候,不一定基于主件,有可能是基于经常查询的索引来拆分的。
    递增拆表,比如说用户表增加2000万开一个新表,这个就比较灵活,比如说二次拆分,用户表拆了16个表,后来发现每个字表都很大,都突破5000万,怎么办?是不是再拆?很头疼。递增拆表不需要考虑这个问题,这个情况可以做维护,但是有缺点。
    还有冷热拆表。比如说论坛很常见,对这种复杂查询,我特别要强调一下。什么叫复杂查询?比如说电商和交友经常遇到。你的查询条件是用户可以选择的,比如说可以选择三到四个条件,我可以选择年龄分布,地区在哪里,什么七七八八各种各样的条件。用户自己选择,他不一定都去选,他就是选三到四个组合,然后组合完进行搜索。这种搜索非常难优化,每个都建索引没有意义,最后只有一个索引。它的索引扫描行数非常大,比如说数据库有2000万套记录,这种符合查询是用户组合信息,索引扫描查询效率非常低,这种情况下怎么办?如果说做冷热拆表的话,大部分用的查询信息在热能表上就能够完成了。比如说交友,最近一个月有登陆的用户,我要优先满足他的查询结果。这种情况下,我把一个月内的登录用户当成热表,其他的当成冷表,这样索引会成倍降低,降低的很大,这是成本比较低的,数据量没有那么夸张的情况下做复杂查询的优化。这是非常好的事。但是如果像淘宝这样的,或者是51他们的情况,数量非常大,信息非常多的时候,你要考虑到第三方的全文搜索引擎,靠数据库是撑不住的。
    针对一种中等的,我们知道下面有很多中等电商,或者是中等的系统,这种方案非常省时,而且非常有效果。这是简单的分布式数据库总结,利用拆分解决数据容量问题和负载问题,利用主从解决数据安全问题和单点隐患问题。拆分是必要的,但是不是充分的,这个是后面说的事情。你会发现拆分会带来很多新的问题,包括去关联化这个非常重要的问题,一致性也是一个问题,你查询很多库的时候,我拆了很多很多数据表之后,发现这个数据的分解不是在完全一致的水平上。这是都是说拆分过程中会带来的一些连带问题,还包括拆分过程中的一些查询不好实现,一些统计也不好实现,可能也会带来一些连带的问题。拆分完之后还是有一些后续手段。
    关联产品的拆解也分两种,一种比较好拆,在一个表中查询,在一个表中去印,这是比较好做的。但是不能这么做的话,可能在业务逻辑上要处理一下,如果在技术上是很高的门槛的话,可以考虑在产品逻辑是调整一下。我经常看淘宝的操作界面,包括操作界面中的一些细节。其实说真的,它的一些操作细节暴露了它的操作方案,尤其是大半夜,淘宝也好,新浪也好,它翻页的方案,你能够看得出来它是怎么做。在给用户操作选择上可以做一些手脚,在不影响用户体验的情况下解决大的问题。
    数据一致性的问题,你要把数据表拆了,拆的七七八八,数据库没法跑,这样会带来很多很多隐患,而不是说在应用层,在程序端要想到这些。
    反范式设计,主要是两块,一个是去关联化,就是数据连表查询不能再用了。强调索引的概念,比如说数据表建索引,以前提的外件,在数据库它就是方便查询的。适度冗余,在以前的范式结构强调精确性。在反范式结构中,我们做一些冗余字段,甚至做冗余结构就能够解决看上去很复杂的问题,而且开销很小。
    分为四种:一个是基于展现的冗余,基于查询的冗余,基于统计的冗余,还有基于写入的冗余。并不是说所有的一致性问题都不能容忍。特别是在论坛中遇到过这样的例子,回帖的是某某人发了一个什么信息,然后点头像进去,点头像进去是白银长老,他原来在回帖表中把这个冗余字段带进去了。技术人员一看就知道这个实现的方式了,这个对用户伤害大吗?不大。它并不是一个真正的问题,是一个可容忍的问题。
    比较典型的一个例子,消息表。我经常看谁给我发消息了,这是一个列表。从范式结构讲,完全可以表现这个表的结构,但是列的时候,我一定会列用户名。我要列的时候,我希望把用户名跟用户性别列出来,第一个写完之后,我用硬操作写一下,但是用户表拆成64个、32个,这个事情就很头疼了。我又不能连表,我要到很多用户表去查,在发消息的时候把这两侧带进去就完了。内容非常简单,而且更改度不高,用户名一般不让更改,用户的性别一般不让更改。这样的话,我加两个冗余字段,用户表拆成多少跟我没有关系。社区消息表也是,在游戏中看战报也一样,还有列表也是,动态也是,本来只需要一个UID,但是可以把这些东西带进来。回帖表把用户级别带进去了,这个存在一个一致性的问题。
    基于查询的冗余复杂一点。我们以前的查询条件,查询条件涉及多个表的字段,拆到不同的数据库里面,这个查询怎么做?比如说电商,我要搜索一个产品的信息,可能搜索条件中包含这个产品本身的属性,也包含这个产品分类的属性,产品又非常多,分了很多个表。这种情况下,这个怎么查?比如说产品就一个表,产品分类一个表,现在两个表要去关联化。如果比较简单,我把产品属性的信息作为冗余字段,写入到产品信息表里面去。那么我就可以在一个表中进行查询了。这种情况是什么情况?是比较简单的情况,就是产品表只有一个表,但是如果把这个问题再复杂一遍,这个分成很多表,一般产品不会有问题,除非像淘宝这样的结构。
    如果这么查的话,查询条件还是要跨很多表,很头疼。然后这个产品条件又是两个属性值,我不能说在所有的表中查,这个很头疼。怎么办?如果我的查询条件是比较固定化的,我可以把这个固定化的字段单独建成一个冗余表,就是说每加一条产品信息的时候,往冗余表里加一个信息,这个冗余表就记这个产品属性跟分类属性。这个适合于什么?这个适合条件比较有限制,查询条件是相对固定的,这两个选项是固定的,但选项值是用户自己调的。我利用写入,增加了写入,减少了读取的请求次数,让它在一个结构中去查询,然后减少这种读取的结构。这是基于多个表查询的冗余结构方式。
    我们做一个用户表,分出来之后,通常以UID为主要的分表依据,为什么?因为可能用户跟其他所有的关联表都是UID关联的,所以UID为主要的关联条件,分成十几个表,在用户登录的时候会出现问题,他只知道用户名是什么,我不能跑到所有的子表去查这个用户名。那么这个时候要做一个冗余结构。用户明天都要登录,只有注册的时候才会写入,这个时候做一个冗余结构,它有一个对应关系。用户登录的时候,知道他的用户名就知道到哪个表去查了,通过UID查询密码。这个解决了登录的问题。有一些网站它不仅仅允许用户名登录,它允许多种方式来登录,我可以通过手机号码登录,也可以通过邮件地址登录。这个也可以做,在刚才的基础上改一点点。一个用户可以有多个K,我仍然可以基于K做分表,这种情况下,可能有两亿用户,但是两亿用户有八亿条记录,这个没有关系,做个表就可以了。然后查询的时候,用户登录的时候,他输入一个手机号,你就可以在这个表里面很容易把它定位到。所以有几亿条记录,十几条记录没有关系,分布式数据库,多项登录马上就解决了。如果只做主表分布,不考虑冗余的话,那么就很难了。这是通过写入冗余减少查询,提高查询效率,减少查询的请求次数。
    还有一种,我们提交积分的游戏很多,用户也很多,一天几百万条,这个数据表膨胀的速度非常快。也要拆表,遇到一个问题,拆表好拆,但是怎么查询?有两个主要的查询要求。第一,看每个游戏的时候,它肯定有游戏排行榜,基于Gameid去查询,还要看用户信息,比如说看一个玩家的头像,看这个玩家玩过哪些游戏,他得了多少分,这个也是一个常见的操作。怎么做冗余?这个冗余跟刚才那个不太一样,这个冗余是一个全冗余,两个表的结构完全一样,索引的目标一样。一个是基于Gameid去分表,用户要写两条技术,然后再往UID去写一个。这个面可能存在数据不一致的情况,但是基本上这个也是一个容忍度的问题。这是非常典型的一个例子。当我们在多个字表查询过程中,可能会遇到这个问题。
    基于统计的冗余。比如说我们很多论坛游count跟sum的操作。在这种情况下,它的索引扫描行数也非常大。比如说论坛今日发帖数,板块的发帖数,今日细分会员数,它都是加出来,这个就是冗余字段。但是加1加1有一个问题,跟你实际数据不一致。通常冗余字段就够了,游戏积分排名,这里面还有一个条件,我们把这个游戏的积分分成段,每个段有一个计数器,做了一个独立的统计表,每个分数段的计数器。当你提交成绩的时候,我先看你属于哪个分数段,这个时候索引扫描行数会小很多。然后在分数段找出排名之后,再把计数器相加,这个就非常小了。然后就得到排名了。这个只是分了一级的段。后来觉得这个效果还可以,后来发现了Redis不错,它是一个数据结构,每个节点上都有一个小计数器,加总得到排名,这个结构在我理解它就是一个统一的冗余结构,而且也是分段的,但是只是分成多级的段,效率非常好。
    大家牺牲的是写入效率,在这种结构下,它写入效率并不高。牺牲了写入效率,提高了排名的查询效率。我对这个结构中有一个基本了解情况下,它为什么会这样?就是它存在的原理是什么。这种冗余结构,第三方其实也用到了。这种比较少见,但是也遇到过,就是基于写入压力的优化。比如说一次请求涉及到多次写的情况。比如说做游戏,我带五个武将去打怪,我发现这五个武将的经验血、等级都要发生改变,我打完一个怪,在页面上就是一下,然后打怪成功之后,有人说这个可以缓存回写,当然这是一个很好的方法。如果说这个武将信息要求持续化保存,其实还有一个变通的方法,我以用户ID做一个临时的结构,这个结构专门存这种信息,把五条信息变成一条。我平时读取怎么读?变成两次读,增加了读,然后减少的写,有的时候增加写减少读,把武将信息根据临时结构读出来,然后再把数据合并起来,变成真正的武将信息,这是读的过程。写的时候把五次写变成一次写,但是五次写还会写回去,我放在后面。因为隔一段时间去写,可能用户发生了多次操作,其实你只写一次就可以了。通过中间结构减少写入请求。还有实时统计,一分钟更新一次,更新频率非常快,但是一分钟更新一次以后,像什么PV、IP比较好更新,有一些数据比较碎,比如说这个网站的来路,还有网站的受访页面,案例是一个UL,但是你发现一分钟1000个网站汇总过来,这个量还是蛮大的。你会发现经常重复,它没有效,到提前结束的时候,你发现很多东西都是复杂的。这种情况下怎么做?其实也一样,可以在一分钟的时候,我写到一个临时的字段,我把这个网站的这些信息作为一个字符串,我读的时候,拼出来当前的信息,用户看上去也是实时的。写的时候,开始每分钟只往那个临时字段去写,从临时字段读出来,然后再写回到UL表格中去。通过这种方式,我既做了持久化的保存,同时又能够把写入合并起来,让它写入频率没有那么高。
    做一个简单的总结,适度冗余可以减少查询请求,可以解决一些索引查询的问题。刚才说展现的方式,还有通过一些冗余结构来分点解决查询问题,还有就是对IO请求频率做一些优化。但是这些都不绝对,其实每个东西都锁定了场景。场景非常重要,有的时候如果说IO压力很大,你不能用IO换查询了,如果说查询压力很大,你看哪个资源比较紧,然后哪个资源压力比较大,你的方案是针对这个资源压力比较大想办法的,通过其他的资源来换它。
    反范式设计,第一条就是减少数据表中的关联性,空间冗余解决衍生的问题,反范式设计只是说遇到问题的时候才会考虑这个概念。在这个情况下会出现相当多的一致性,就是数据不一致,这个需要业务层面有很多的处理能力,要做一些一致性的校验,还包括在一些展现层面可以做一些容忍度,就是有一些东西其实用户也不是那么关心的,哪些是用户关心的不能出错误,用户不太关心的,其实也可以容忍的。寻求平衡,这些问题,很多很多问题并不是说每个方案一定是好的,对的,你要去找一个平衡的方案,让资源能够利用起来。
    非常感谢大家,这个是我们4399的实景图,大家有时间到厦门的话,一定要去参观交流。有加盟的话,可以跟我私下谈。谢谢。
    主持人:看看大家有没有给曹政提问的。
    提问:刚才听分布式设计,讲到分布或者是分表,包括纵向拆分或者是垂直拆分,刚才提到一个递增拆表,是不是就是这个概念?
    曹政:递增是自动扩展的方式,每天凌晨创建一个新表,如果说像刚才说的,2000万增加一个新表也很好处理,看到1500万了,我新创建一个表在那儿等着它,直接根据UID写上哪个表就可以了。
    提问:这样的自动扩展,你之前假设是垂直分布。
    曹政:要么就是垂直,要么就是自动化的。你想把两个方案混合起来是吧?
    提问:对。
    曹政:我们没有考虑这个。
    提问:你们在分布式过程中,有没有遇到事物的问题?
    曹政:这个参数跟是跟事物有关系的,一秒钟提交一次。我们自己并没有刻意处理系统,但是我们在参数的选择上是考虑的。
    提问:那个主要是从保证事物的持久性,但是有分布分表的话,如果业务中需要处理用户虚拟帐户的金额,必须用事物来保持数据的一致性,不知道有没有这个方面的意见?
    曹政:我们做的并不是非常到位。我们这块还是以程序来保证的。实际上这个东西比较好,你可以留多个数据,用户提交一个数据,他可能在多个地方留档,这种问题可以通过多个数据源去回溯的。当然也会遇到投诉,为什么数据没有。如果回溯到另外一个信息,证明它已经有重档了,我们可以人工的去做。但是这个并不是很严谨的。
    主持人:再次用热烈的掌声感谢曹政。
    
     主持人:像刚才演讲的资料,在11点半的时候准备了一个最新的版本,刚才又拷了一个最新的版本,他们针对这个演讲进行了精心的准备,我们用热烈掌声欢迎岳旭强和金潇。
    岳旭强:我们两个人的概念,就是团队总比个人力量来的强大一点。今天跟大家分享的一个议题是说在创业型的团队,在初期或者中期的时候我们的架构应该是怎么样的,我们是怎么样的。这是我们今天分享的一个话题。因为整场叫知名网站的架构设计,到现在为止,是不是一个知名的网站我心里没底。知道蘑菇街的人请举手。我们从两个方面介绍一年多的演变过程,前面部分由技术专家金潇跟大家分享一下蘑菇街在一年零两个月上线以来在技术方面做的变化,我在后面会打打酱油。后面有请金潇来跟我们大家分享一下技术方面的东西。
    金潇:谢谢岳旭强。我简单介绍一下蘑菇街这边技术方面应对的一些问题。UV注册用户,每天130万,这都是我们之前的一些东西,我就不提了。现在每天蘑菇街这边有2000万次的搜索引擎请求,还有近8亿次的Redis请求。这个过程,还是爱一些借鉴意义的,今天跟大家分享一下我们刚刚起步和后面的一些东西。
    这张图是10年10月份蘑菇街的一个初版,叫吕布跟貂蝉。
    岳旭强:当时为什么叫吕布?
    金潇:吕布,天下无敌嘛,寓意很明显。
    岳旭强:为什么数据库叫貂蝉?
    金潇:有句话叫男女搭配,干活不累。我记得当时是两台吕布跟貂蝉,二手的IBM,价格大概在1600左右。算一个比较传统的架构,当时为什么选择它?第一点,很重要。我们熟悉PHP,我们当时有三个开发,都是从PHP那边的老手。这个架构搭建很简单,一个人一天时间搭建完,然后继续做业务开发,非常快。
    第二点,相对于其他语言来说,PHP的入门相对比较简单。顺带说一下,我们现在团队大概有70%左右的是Java背景的。之所以造成这个原因……
    岳旭强:当时我们预见到开头,没有预见结尾。PHP确实新手入门非常快,但是对PHP非常熟悉的技术人员,相对Java人员来说小一些,对我们招聘来说是一个挑战。但是还好,开头不错。我们有70%的Java背景,基本上一周以内就可以上手工作了,现在来看非常符合我们要求的体系。
    金潇:后来在10年12月末的时候,我们做了一件事情,这件事情还算是比较成功的一个东西。我们当时把机房从杭州迁到了嘉兴。虽然说之后的结果造成我们现在整个应用和整个的PV……
    岳旭强:我印象里,主要的原因是觉得1600块的服务器不靠谱,所以我们升级了两台3000多块钱的服务器,搬到了新的机房。
    金潇:3000块钱的服务器,总比1600要好。第一天晚上的时候,我们上线了,访问非常之快,会员也非常很高兴。但是到第二天早上发现,发现网站响应变慢了,我们当时是两台服务器的架构。开发也是当时我们几个人,我们就开始查为什么慢。按照经验去查负载,负载蛮低的,零点几。然后看看IO有没有问题?IO没有问题。之前我们根据经验,以前碰到过磁盘写满的情况,去查查磁盘,磁盘也正常。后来想了一下,没辙了,查了一下整个带宽的情况,带宽还是没有问题。仔细一想,我们从1600到3000的服务器,当时从5.1升级到5.5,测试出来不错,但是按照现在这个查法,找不到原因。我们当时想可以回滚,回滚完之后,还是不行。
    岳旭强:当时半天多的时间已经过去了,非常着急。
    金潇:后来无意之中发现一个问题,有一个同事他拼了一下,从一台服务器到另外一台服务器,发现拼很慢,但是拷贝没有问题。后来仔细一下,我们连的网线是从电脑城买过来的很普通的网线,当时我们打电话给机房负责运维的人。
    岳旭强:他给我们很严重的打击,说这条网线太烂了。
    金潇:这个事件,大家想一下,如果说我们碰到这样的问题,或者说以后碰到这样的问题,我花半天的时间查这一堆机器的负载,到整个的软件版本。是不是说我可以省掉这半天的时间?后来我们就整个搭建了一个很详细的一个监控平台。我把前面这六点,甚至说更多的点直接过滤掉,我可以直接查一些其他的东西,这样能够快速排查问题。
    监控这个东西,不管是你还是一个小网站,还是说在发展阶段,你必须重视,这是我们当时血一样的教训。前天我们统计了一下蘑菇街的监控点,大概是14383个人,包括系统监控跟业务的监控。接下来讲第二件事。
    岳旭强:这张图就是从监控系统里面截的图。
    金潇:这张图是我们的一个流量图。大家能够发现这边有两个很垂直的一个峰值,中午12点和晚上9点半的时候,几乎是很垂直的两条线,我们的流量翻了三倍不止。
    岳旭强:我们一直想还原到刚上线推广的时候,那个时候不止3倍,应该是30倍,那时候基数很小,推广增量很大。
    金潇:正常情况下,现在流量在70%到80%左右。当时碰到这样一个问题,很纠结,我该怎么办?按照简单的逻辑,我会想前面水平波,可以加机器,或者是并发限制。但是仔细一想,这个东西很麻烦,加机器或者是做并发限制,我总要耗费一定的时间。
    岳旭强:最重要是没有钱。
    金潇:我们想了一个很简单的方案,Killall—9,把PPP重新启动。
    岳旭强:我们真正研究下来,这个方式对用户的影响有,但是突然引进30倍冲高的时候,损失的人相比引进进来的人,占比很小,我们每次推广都有专门的人在做这个事情。
    岳旭强:当时确实是一个非常简陋的方式,非常有用。
    金潇:我们总不能这么一直苦逼下去,我们称之为系统保护。原理还是蛮简单的,当大拼发进来的时候,你会通过web这端访问外部服务器,这样的话,做一个简单的限制,把相同的请求限制在每台服务器可能50个,这样的话,后面的请求就直接被挂掉了,类似一个自动的降级,就能够保证推广在翻倍的时候服务还是很正常访问的。
    简单做一个总结。第一点,在网站的发展阶段,监控是很重要的。不管是说服务器出问题,应用出问题,还是说业务方面有问题,我必须把监控给做起来,如果现场出现了一些东西,那开放热点要第一时间能够处理。
    第二点,在现场出现问题的时候,当我们成为救火队员的时候,越直接的手段越有效。根据我们这边的经验,就是重启服务,回滚代码。
    岳旭强:补充一下,我们的原则很重要,我们并不是说出问题的时候立刻找到问题的根源,而是先让服务恢复起来,后面再找真正的原因,这对我们来讲是一个非常重要的原则。
    金潇:第三点,网络非常重要的我们从10年12月底从杭州迁到了嘉兴,网络确实变好了,那个时候没有任何原由的PV涨了30%。大家买网线一定要买好的网线。
    蘑菇街大概在11年情人节的时候正式上线了,这个整个UV的成长曲线图,我们的业务确实发展很快,我们需要去配合这些业务。技术这边我们会做一些事情。
    岳旭强:我们把业务作为我们第一目的,业务快速的上线是我们唯一的诉求。
    金潇:我们经过这么长时间发现一个问题,这个是二八现象,20%的产品开发完之后是不上线的,只有20%线上的功能发挥了作用。为了应对这种情况,开发这边要尽量快。按照蘑菇街的原则,单个需求过来,大概是一天到两天时间就能够直接上线。天下武功,唯快不破。
    岳旭强:我在蘑菇街有个名字叫独孤,他的名字叫小小。
    金潇:我们确实做了一些事情,第一就是DB。DB对于整个网站来说很重要。蘑菇街这边,我们是从1600的服务节过来的,我们第一个解决DB碰到的瓶颈,就是换一台更好的服务器,当时换了48机的,确实有提升。但是提升不明显。我们评估大概是只有50%的成本。后面一个很偶然的机会,虽然说升级了服务器,但是其实没有什么作用,后来我们偶然改了一个参数,不知道什么原因,参数设计的是64兆。
    岳旭强:现在我们也不知道谁设成的64兆,现在还没有找到元凶。
    金潇:改了参数之后,发现整个硬件性能没有挖到底,我们当时找了一些相对来说对DB蛮熟的人,我们优化了一下参数,又有50%的提升。但是随着业务发展会发现,简单一点,往里面加成本,但是写的东西没有被降低,写没有任何提升。假设主的DB水平扩展的时候,现在没有办法,如果我们继续做优化的话,按照我们蘑菇给团队的人员分配来说,确实成本有点高。当初我们采用的方案,用钱买了固态硬盘,固体硬盘的性能大概在普通硬盘的10倍左右。但是根据我们的应用来看,至少有500%的提升。所以能够用钱解决问题,或者说用钱解决问题的时候,成本不大,那么我们可以用钱解决问题。
    岳旭强:我补充一个点,我们可以看到在当时做参数优化的时候,优化之前我们加机器的成本跟收益是很不均衡的,我们投入一倍的成本,但是只带来50%的提升。所以一个很关键的点,如果说在我们的实力没有优化到对优的时候,加机器是没有用的。刚才提到了假设永远是不合理的,如果能够做到这一点的话,其实其他什么都不需要用,只需要加机器,但是现实成本很高,在这种情况下,用钱来解决,升级单台的性能也是一个不错的选择。
    金潇:经历了前面类似的优化之后,蘑菇街这边会出现好几个业务,当时确实碰到了瓶颈,随着粉丝数越来越大,它分发之后,写入量越来越高。当时我们发现一个很简单的原则,每个人的Timeline个数是规定的。
    岳旭强:蘑菇街的时间限值有20页,每页有50个消息。我们给每个人分配了4K多的一个空间,存储1000个消息ID。相对来说,我们花了一天的时间,从开始想到真正实现上线差不多就是一天的时间,上去以后我们数据库压力就降下来了,它本身的性能也是很不错的。在这个上线以后,专门发布了一个微博,我说个性化的存储时代要到来了。我当时觉得这种定制型的快速解决问题的方式真的是很靠谱的。但是非常悲剧的是,没有多久我们就做了一个新的业务,因为时间限制有很多噪音,比如说在蘑菇街有一个很重要的工作,我喜欢,点喜欢,假设我关注了小小,他点了一个喜欢,我们把比较频繁的操作分了一个组。这个业务变化相对于之前的存储结构已经不能满足了,我们另外一个同事,花了将近一周的时间把这个看起来并不复杂的一个功能搞上线。就在那个时候,我们把缓存系统升级到redis,它性能不差,很靠谱。从那个事件以后,突然发现之间定制化、个性化存储时代来临的这句话多么不靠谱。从这点来看,这是我们反面一个例子。到现在为止,我们还是要靠刚才说的那个同事来做这个产品,后面有计划会把它迁到redis。这是一个反面例子,后面是我们一个相对来说正面的例子。
    金潇:蘑菇街在11年3月份上线了一个项目,可以说非常之生动,每天会有很多美女会在图片墙上点喜欢,发评论。当我点完了喜欢,当我发完评论之后,这个图片会非常火,然后我们就在网上点,图片墙是通过搜索来做的。它的开发成本蛮高的,它的索引如果超过内存的话,那么优化会成为一个瓶颈。所以当时我们负责搜索这部分的同事,他开了一个项目,把我们整个搜索翻天覆地的改了一遍。我需要快速地调整它的排序,按照之前的方案很慢,我要重建整个索引,这边会有一个实时的排序模块来做。现在来看它是非常之成功的,但是当时上线经过一个多月的时间,整个搜索非常稳定。我们同事那一个半月,每天晚上蹲在那边看搜索有没有问题,非常之辛苦。
    岳旭强:当时我的一个判断,觉得自己做搜索太不靠谱了,花这么多时间和精力,做完以后还不稳定。刚好差不多同样的时期,现在看来整个搜索系统成为蘑菇街最核心的一个部分,我们整个排序的动态调整,我们实时的作业更新都是非常有用的。
    金潇:关于Jessica还是有一个段子的,我们当时在一个类似于车库的地方,突然有天中午。
    岳旭强:有个前提,我们那个时候技术人员很苦逼的,每天都在写代。有天下午的时候我们突然接到一个电话,一个听起来很有味道的一个女人的声音,她说她要叫jessica,要找蘑菇街的一个姓李的经理,当时在我们苦逼的技术人员的心里就掀起一阵波澜。当时我们同事正在做新的搜索,觉得jessica有很多神秘感,所以我们当时决定把新的搜索起名叫做jessica,现在演变到第二个版本,我们后面几天在杭州做关于jessica2的分享,它的重要变化就是它的实时性得到了本质的变化,几乎是一个完全实时的系统。如果杭州朋友有兴趣的话可以一起聊一下jessica2。
    金潇:经历了选型,也经历了之前的优化,我们会碰到这样一个纠结,是不是该做一些服务化的东西?举一个例子,以我们的图片为例,我们每天大概会有50万到10万张图片,包括缩略图。峰值的时候,整个带宽在7G左右,一张图没有上传的时候,可能经历几个部分,第一个是把图片做压缩,生成一些缩略图,然后分发到多台服务器上,做一个冗余,后面做一个分析,它属于哪个维度颜色,后面再加一些文字识别。我发现这个处理是很耗CPU的,我们有次推广的时候,处理图片的进程会占用CPU,它的处理能力也就慢慢下降了。我们当时想能不能把它独立出来。仔细分析之后,我们发现图片这个东西,相对于我们来说,它是一个很独立的业务,并且它是长期不变的一个东西。而且我要做颜色分析,我要做文字识别的时候,我会加入很多模块。现在所有的运维工作都是由我们自己来承担的。不同的机器会有略有一些小的区别,我用的运维成本非常之大,每次上一个功能都很麻烦。
    当时我们就直接把图片业务分拆为传图、读图两块东西,后面再加上一些图片集群的小运维。根据这点我们可以得出三个简单的原则,就是当业务相对独立,并且长期固定的时候,当运维成本非常大的,当整个业务对主线业务的性能影响大的时候,可以把它提取出来,成为一个服务。
    根据上面讲的东西,我们过渡到现在这个阶段,这个是去年10月份的时候我们的一张架构图。这边的存储是TFS的集群,一些服务独立出来了,一些简单的应有会有一些小的集群在里面。前面讲到我们服务器的命名,像刚开始时候的吕布与貂蝉,现在为了查起来方便,并且运维简单一点,是用了另外一个模式。
    岳旭强:创业期真的很辛苦,我们会找各种乐子来让自己开心一点,比如说jessica,心目中它的形象变得很好。我们最初有很多好玩的东西,我们最初服务器的名字都是用三国里面的名字来命名,比如说后面还有张飞、赵云这些。但是服务器数量随之增加,三国里面比较牛的人物名字没有那么多,后来我们同事提出来用自己的名字命名,然后把服务器的名字命名成员工的名字,我在蘑菇街的名字叫独孤,我们有一台服务器在做独孤。用员工的名字以后,我们突然发现一件很纠结的事,有一些人的人品有问题,用他们的名字作为服务器的那台服务器,经常出问题。我们有一个同事是现在移动的负责人,一个女孩子,她非得让自己的名字叫张飞,我们有一台服务器的名字叫张飞,上线没几天就挂了,再也起不来了。从那儿以后,我们觉得用员工名字命名也不行,对员工可能是一个打击。
    我们后来换了一个名字,卷流是我们的创始人之一,或者说创始狗之一。最开始团队只有几个人的时候养了一条小狗,它的人品非常好,它命名的服务器从来没有出过问题。所以接下来所有的服务器就用卷流带命名。
    金潇:我们这边业务快速发展,针对业务快速发展,我们有几个原则,快速上线,一个需求过来,立马一天、两天就会上线的。我们会挑选使用熟悉的并且是成熟简单的方案,来降低我们整个的人工成本。
    岳旭强:硬件的发展,往往一个提升就可以让很多很多人一年的辛苦可以省掉。如果我们自己来优化这些软件的东西,如果有5倍的提升,那简直是不可想象的。但是它硬件的提升立刻5倍、10倍就涨上来了。有时候用钱解决问题不是问题,但是真正的问题是钱总是问题。所以在创业期的时候,这个平衡比较难掌握。
    金潇:我们现在的团队是没有运维,没有测试的一个团队。并且整个工作年限蛮早的,一般都在一到两年之间,但是我们却拥有快速发展的也许,快速暴涨的数据。其实最重要的还是靠我们的团队,蘑菇街有一个最最默契的团队。接下来由技术负责人介绍一下我们的团队。
    岳旭强:现在蘑菇街的团队到前两天,我们好象刚满90人,技术团队差不多占30%到40%的样子。其实回到我们创业最初期的时候,我做个小调查,因为我们都是技术人员出身,有谁心里想着说以后我想创业的,不管你会不会创业,但是心里欧这个想法的。其实我一直有一个推断,每个男人的心里都有一个创业的想法。所以我们想调查一下有多少人以后想创业。
    其实很多人对创业有一种期望,有一种梦想,创业是一个很开心的事情,我自己可以控制自己,想怎么样就怎么样。确实,其实在创业的最初阶段,真的非常开心。我现在回想一下在创业最初阶段的时候,但是每天在一起工作,甚至一起生活,上面有一个链接,这是我们小组里面的一个主题,是我们另外一个合伙人,算我们的CEO,这是他发的创业初期的照片,很有意思。那个时候,我们还一起做饭,做红烧肉。
    其实在整个创业最初期的感觉非常好。所谓一起扛过枪,关系都是最铁的。在那个时候没有任何组织,我们就是一起在朝一个方向一起努力,我们也没有任何的纪律,大伙都是有一个共同的目标,不需要约束你怎么样,大家都是很拼命,都在朝那个目标走,如果有任何新的进展,我一嗓子大家都知道,其他人一嗓子,我们也知道。在那个时候,推荐大家去看一下这个主题,里面会有一些有趣的照片,可能会有一些体会。
    为什么说创业初期最高兴?因为随着慢慢步入正规,比如说我们的团队越来越大,我们的业务在往前快速发展,我们整个系统的负载越来越高,在那个时候,其实创业最初很高兴的感觉,慢慢会被很苦的感觉替代掉。在不知不觉间,我也不知道什么时候,蘑菇街团队变成了一个任务型的一个组织,这个组织在去年的下半年发挥了非常非常重要的作用,整个业务的高速发展,在这个阶段体现的非常明显。我们现在比以前发展的更快。可以认为那个时候其实是对极限的一个利用,每个人一天会有几个事情的安排,一个做完会有另外一个排在后面。我们当时还没有10个人的技术团队,最多的时候一周发布了90多个改进。
    我曾经统计过我们某一天从下午五点钟到六点钟,一个小时发布了10次。在那个团队里面产生了一小批很成功的人,他们是红砖,他们什么都能够搞,小小是一个典型。在这个阶段,我们业务快速的发展。到去年年底的时候,我们发现大家真的很苦,我们最初创业期好玩的东西,我们服务器用卷流命名,自己的名字也不会成为服务器的名字。好玩的东西变得慢慢少一些。在这个情况下我们一直在思考怎么样才能组织我们的团队变回到创业最初期的感觉,让大家很高兴,一心一意,然后一个目标,像亲人一样,真是一起扛过枪的感觉。我们一直在思考这个问题。
    抛开以前讲团队的东西不看,我一直很痛苦的一件事,沟通效率太差,而且很容易失真。我不知道有多少人看过三体,还是很多的。看来技术宅男都是这样的。如果说我们能够很精确的瞬间就可以去沟通的话,那么这个世界就太完美了。但是现实我们做不到这一点。尤其在创业的中期阶段,我们团队,包括整个蘑菇街,我们觉得最大的问题不是业务,不是钱,不是技术,什么的问题是我们每个人的成长,我们能不能跟的上业务的高速发展。我之前仔细回想在蘑菇街一年的一个心得,我觉得蘑菇街一年系统量的压力的增加,我们业务的增长,我们团队人数的扩张,其实比得上我在上一家公司三年的时间。所以每个人的成长变成最大的问题。
    一个人怎么来成长?现在看一下,可能不外乎四个点。首先如果对这件事情没有兴趣,短期内可能做的不错,但是时间长了,肯定是会相对来说比较疲一些,所以兴趣是第一个非常重要的点。另外一点,如果只有兴趣,但是不努力,你不具体实施,可能也不会有成长。刚好我有兴趣,我又很想努力去做,但是没有这个机会的话,比如说他想做一个传统的软件,但是我们是一个互联网企业,可能也没有施展他本领的机会,所以很难成长。很幸运,这三点都满足了,但是如果做完以后,做完的东西在线上运行的怎么样都不知道,其实你的成就感得不到体现。回想一下去年下半年任务型团队的最大问题,每个人排的很满,但是做完的东西在线上跑的怎么样,带来了多少用户,让我们的产品完善了多少,他心里并不是很清楚。这个是成为阻碍成就感很大的一个原因。
    只有满足这四个点,我们才有可能成长,让我们整个的业务撑得下去。基于这些点,蘑菇街过完年还是做一些调整,组织精简,或者是角色精简,这是我们一直在做的事情,我们没有运维,没有测试,我们前端、后端分的不是很清楚,我们这个时候更多需要全能型的选手,但是他在某个领域,基于自己的兴趣,还是有一些专业性的挖掘。其实后面这点非常重要,我们回想一下创业期为什么非常高兴,因为所有的结果我们都是直接知道的,而这个结果是最终的一个商业结果,比如说我们有1万个注册用户的时候,很高兴,我们有1万个注册用户了。但是现在如果做了一个产品上去,有多少成绩,可能他感受不是很深。所以我们需要商业结果导向型的这么一个团队。
    刚才说到全能型的选手,很多人理解我会运维,我会测试,我会开发,这个是全能型的选手。但是其实很重要的一点,我们需要他对商业的东西有一点敏感度。在前段时间开始实行一个,我们希望我们的组织是一个一个业务型的组织,大家是面向业务和商业的结果,提出这个想法以后,我们业务团队非常高兴。蘑菇街的男女比例非常协调,基本上业务线里面的一些同事都是女孩子,她们听说工程师要下乡了,然后她们会做一个下乡的欢迎牌。在这个牌子后面写了一些很肉麻的话。为什么我们的业务团队非常关心工程师下乡?因为他们之前挺痛苦的,即使业务型团队效率非常高的话,他有东西想做提交给产品经理,然后产品经理找到技术小组负责人,这个负责人告诉具体做的技术工程师,其实中间隔了三层沟通,效率非常低。他们有些时候跟产品经理说一遍,到后面还要跟技术说一遍,还要跟技术团队的组长说一遍,非常痛苦。所以听说工程师下乡,非常高兴。前段时间我们的几个工程师天天都有农家大园吃。
    工程师一开始有一些担心,因为他会觉得到业务团队以后,技术团队是不是变得没有一个整体感?这个也是我们现在担心的一个地方,所以小小后面的责任非常重大,因为他会对我们全局做一些把握和掌控。一段时间以后,我们的同事就很高兴了。
    如果我们业务型的组织还再继续的话,希望以后有机会跟大家分享更多我们在整个创业期经历的一些东西。我们从来不做招聘广告,可以联系我。谢谢大家。
    主持人:感谢岳旭强和金潇两个人的精彩分享。接下来是答疑时间。
    提问:听你们刚才的介绍,蘑菇街产品发布速度非常快,你们是如何解决你们快速的测试,你们有没有过这样的先例?如何看待这种问题的?
    岳旭强:我的理解,在快速开发过程中,比如说有一个小的10次的发布,有几次发布会对现在的东西产生影响。我现在真正想想,这种情况好象比较难杜绝。因为现在我们也会出现发布一个新的功能,然后线上有问题。我觉得对根本的问题,就是每个人的能力和他的责任心,如果他做的好的话,出错的概率比较低。我们可以在技术方面提供更多的手段,比如说我们线上有两个机器,一台是以卷流命名的,还有一台是周瑜,我们要求每个功能改进或者是产品上线之前要在这两个环境中测过。我们有测试人,我们基本上一半的测试是由工程师直接测的,还有另外一半是由业务方、产品经理一起参与测试的,现在看来质量还不错。
    提问:两位好,我有一个问题,我看你们刚才说有13000多个监控点,你们能不能介绍一下这个监控系统的设计大概是怎样的?
    岳旭强:如果真的说起来,可能话很长了。我们监控的初衷,首先有一点,要实时。即使业务的东西不要求实时,因为整个系统做下来就是实时。我们现在有几代服务器在专门收集所有服务器的日志数据、性能数据等等,收集起来以后,我们有一个固定的文件格式存这些结构数据,然后生成报表。细节的东西线下交流吧。
    提问:我问一个技术性的问题,刚才说到系统的设计,分成传图和读图两块,单独运维。我想知道具体的一些实现的方式,能跟我们分享一下吗?
    金潇:其实只是从结构上把它分开了,你可以理解成为我有几台服务器,然后做一个小集群,这个集群只是做一个传统的东西,然后提供一个接口。我们之前一直用PHP。补充一下,我们后端存图这边采用了淘宝的TFS。
    提问:我也是技术人员,我也尝试创业过,但是我感觉最困难的就是在创业过程中,从技术导向去创业,走到最后,感到穷途末路了。我现在还没有想明白这个问题,到底该怎么去做?能不能分享一下你们从技术导向创业的过程。
    岳旭强:我一直在想我们应该不算技术导向,我们从创业最初期来讲,我们第一个目标就是自己能够活下去,为了达到这个上线,我们月最土的技术也没有关系,但是最终结果是这个东西上线了。我可以用看起来很炫的技术做,但是有可能做两个月。但是我们用最成熟、最简单的东西来做,我们只需要一个月,这个是我们的一个原则目标。可能到一定阶段,我们需要很多技术导向型的产品,现在蘑菇街内部已经有一些技术导向型的产品,包括刚才提到的搜索引擎的排序和一些实时的东西,是偏技术导向型的,但是整个公司就是一个商业导向型、业务导向型的。
    提问:刚才您提到在推广业务型弱组织,在这个环节中,产品经理的地位是什么?沟通的成本有多少提升?具体的流程是怎样的?
    岳旭强:这是一个非常好的问题。今天我们凌晨3点钟才到酒店,我很有兴趣聊一下刚才这位同学说的问题。我们在做工程师下乡以后,其实很担心的一个问题,很多时候可能我们的业务方面跟我们的工程师直接交流沟通的,最后担心的一个问题就是产生产品的失控。做了很多东西在线上,其实做了什么也不知道。对于产品经理来讲,它的要求更高。以前是所有需求从产品经理这边过一遍,但是现在可能会出现他不知道的东西。所以对产品经理的要求,他整个的把控和沟通能力要求更多。我们现在的做法,小的东西没有关系,业务方跟工程师沟通好上线就可以了。涉及到一些相对大一点的东西,还是需要把我们的产品经理拉进来一起决定做不做这个事情。
    我心目中一直认为如果一个产品经理做到极致的话,他应该是整个业务的负责人,他下面有技术,有运营,有推广。现在我们的阶段,可能整个团队的能力还没有到那个水平,我们需要几个团队互相配合才能做好。显然直接卡业务目标的是业务团队更合适一些,所以是业务团队、产品、工程师三个角色没有什么约束关系的,但是他们要一起合作才能把事情做高。
    提问:刚才看到团队很有激情,大家之间的关系也非常好,你们在创始人或者是创始团队是如何分配股权,来达到这样的激励机制的?这是一个很敏感的问题。
    岳旭强:这个并不敏感。因为创业型团队大部分有期权方面的激励措施。具体细节不好说,只能说蘑菇街现在期权的池子比较大。
    主持人:再次感谢蘑菇街两位带来精彩的分享。谢谢。
    
    
    冯大辉:大家好,欢迎回到架构专场。我是这个专场的主持人冯大辉。上午因为有时间没有赶到,向前面演讲的嘉宾表示歉意。接下来是由58同城的刘晓飞先生为我们分享互联网弹性架构设计方面的经验。提起58同城,可能大家比较熟悉了,可能大家会想到杨幂那句撕心裂肺的广告语。其实58同城这么多年来技术上积累的也很可观,非常难得我们请到58同城技术团队来为我们揭示一下58同城这么多年积累下来的技术经验。接下来把话筒交给刘晓飞。
    刘晓飞:我想说58同城不管有杨幂,还有技术。我叫刘晓飞,目前在58同城架构部任总监职位。主要是这次带来的课题是一个高弹性的架构。何谓高弹性?其实这个定义空间很大,高弹性可以想象成一个自动的高伸缩,说到高弹性,大家可能会想到弹簧,系统定义是这样的。我们希望系统在高并发的时候能够表现出色,在低并发的时候能够节省资源。对于这样一个系统来说怎么做到?接下来我把58同城技术的一些做法跟大家简单分享一下。
    首先跟大家分享一个高弹性的架构,这是一个目录。首先做一个背景的介绍,为什么需要高弹性的架构,普通的架构为什么不行?接下来由这个背景引出一些新问题。简单把这个问题描述一下,普通的架构有什么样的问题。针对这些问题做几个架构的设计。设计上可能每一个方案都有优缺点,我给大家逐一分析一下。
    接下来分享一个58的高弹性架构,叫DRM系统。DRM系统,我会花一半时间介绍一下它内部的主要实现的一些方式和一些架构的原理。最后简单介绍两个应用的场景,完成今天的演讲。
    首先背景,58同城他们很熟悉,对于一些数据来讲,可能大家不是特别了解。目前日访问量接近3亿,日发帖量每天200万。单纯的信息系统访问,每秒钟达到2万。不管是访问量还是信息存储量都已经非常庞大了,它有多个集群,每个系统都有一个集群,都有各种各样的系统。一旦集群,系统多了以后,这样带来的管理成本会持续增加,因为要管理很多集群,管理很多机器,需要很多业内人员去管理,开发人员,他要知道自己的系统在哪个机器上,这些都带来一些成本,关键是机器要增加。有的时候机器增加并不是说加一台机器就可以解决问题的,有的时候加机器只是一时的问题。
    怎么解决这些背景所产生的问题?根据这个背景分析一个典型的问题。这是一个很典型的普通的静态架构图。前段是一个客户端,可以是用户,也可以是咱们的客户端,比如说如果看作这是一个中间层,这个就是前端应用的一个后端。可以是局域网,也可以是因特网,这个架构可以考虑。目前是一个web的话,前端这两台是代理的,后面的是app。这三台适合日常的,一般情况下是三台,只是比高峰期多一点点,正好适应就可以了,这样达到成本最节省的方案。但是这样一个问题的出现,比如说突发流量,你要搞一个活动,或者是被人刷了,怎么办?可能三台机器满足不了,这个时候会出现拒绝服务的一些情况。
    对于这些情况,这是静态架构所产生的问题,一个是无法应付突发流量,资源利用率还低。为什么资源利用率低?每一台服务器,按照高峰来做,你不可能按照低峰来做,一般情况都是按照高峰来做的。但是高峰一天当中占的时间点非常有限,可能就那么一个小时,甚至几十分钟。剩余的时间,三台服务器就需要两台,甚至到晚上12点,没有流量了,只需要一台。从时间交叉上造成了一种资源的浪费,怎么解决这个问题?这是一个资源的问题。
    维护工作,那么多集群,那么多机器,现在只是划了三台,维护工作非常繁琐,包括下游系统的部署工作也非常麻烦。这些都是咱们带来的一系列的问题。既然有了问题了,那么就要解决问题的目标。咱们的目标是什么?没有蛀牙,这是高露洁的目标。咱们的目标是解决问题,首先要把目标明确了,把目标都实现了就可以解决问题了。
    首先,我们需要实现一个根据用户请求动态创建销毁实例的功能。到高峰的时候,我可以把我的服务创建到足以应付这些高峰的流量。当高峰过去以后,要把这些流量回收掉,但是这些不是靠人工实现的,如果靠人工会非常累,这需要一天24小时守,靠人工完全做不到。怎么做到?必须有一个系统来代替。计算机当中所有有规律的东西都可以用程序去实现。一天24小时趴在这儿是非常有规律的事情,这个完全可以用计算机语言来描述。这些工作完全可以用一个系统来实现。
    第二个目标,实现资源的分时共享。什么叫分时共享?刚才已经提到了,高峰的时候给了,因为有的时候,系统高峰不是说所有系统都是那一刻高峰。举一个简单的例子,比如说网站,对外用户访问,比如说高峰在早上10点,下午2点,这是高峰期。但是有的并不是这个高峰期,比如说12点是高峰。统计的机器,在白天没有统计,这个机器做统计,这完全是浪费。白天的时候可以拿过来给web的机器用。到了晚上,web成低估了,然后把web机器拿来给统计用。统计系统需要五台机器,web需要五台机器,按照分时资源共享,可能六七台就搞定,web剩一两台保证不挂就可以了。
    还有就是实现服务的自动部署。集群很大,一个集群有上百台机器,自动部署不太现实,但是这个可靠性并不是那么好。什么样的部署好?不同步,布一段就可以了,一份就可以了。但是这一份怎么实现?其实有一个文件共享就可以了。大家可能对这个文件共享有一些疑问,下面会讲到这些问题。实现服务的集中化管理,服务很多,不可能说是每个人在每个服务器上看这些服务,希望能够到一两台服务器就能够看到所有服务的情况,甚至可以管理它,做到服务的集中管理,这对管理是非常有好处的。
    目标有了,然后看设计。怎么去设计这个东西?分析上面的目标,其实不外乎需要三个东西。刚才说了,咱们是通过增加服务的实例,既然要实例,肯定要服务的调度。说到服务,包括web站点和中间服务层。既然是多实例,肯定需要调度,不能说只访问一个,那没有意义。所以要均衡的访问10个,10个不行访问20个,这个是中间的负载调度。不仅要有实例,而且这个实例要能够调度,这才能起到向外扩展的作用。另外什么时候起?你需要机器来模拟,人知道达到一定程度之后知道该起,机器怎么做?机器也得有一个负载检测,感觉这个机器负载系统很高了,三个实例撑不住了,我需要创建一个实例,或者是创建更多的实例共同来承担。所以要有一个负载检测。负载检测可以有很多方法,一种方法是通过间接的,可以根据它的链接的流量,就是访问的流量来评估,这是一个评估,并不是真正的检测,我感觉这个服务现在有50个跟它有效链接了,如果就是一个链接,那么有点小,可以通过这些现象来评估它的负载。
    还有一个直接检测,直接检测就是获取基本信息,看看CPU消耗多少等等。通过这个评估来掌握服务实例。这是负载检测,一旦检测到服务压力已经达到了,需要去创建了,通过什么去创建?它不能创建,它只是一个检测,通过下面这个,叫实例服务,服务实例管理。服务有可能是web的,有可能是中间层的服务,检测到以后就通知它。它怎么去创建?这个模块会调appserver的一个代理,通过它来实现,起一个服务实例,并且把相关的链接和端口添加进来,这个时候就充分达到了向外扩的一个目的。这是三个模块的一个简单介绍。
    根据目标制定了几个方案。首先看方案1,方案1比较简单,通过一个代理,这是一个应用代理,走的是应用协议,它是一个反向代理,它在技术访问后端,再把请求转回去,为什么必须是应用?一会儿讲。上面是一个决策服务器,这个决策服务器承担什么角色?它承担两个责任,一个是负载检测,另外一个是实例管理。中间代理承担一个责任,就是刚才说的调度。它会把这个调度的信息传递给决策服务器。然后决策服务器根据短时间内调度的信息来评估,把调度信息发给它了。比如说最近1分钟全调度它,它就知道这个已经很忙了,可以完全评估出来,达到什么程度了,间接可以评估出哪个服务负载是不是已经达到极限了,是一个间接评估。
    评估出来之后,其实这个机器上,资源服务器,后端叫应用服务器池,可以理解成资源机,因为上面都是资源。这是一个过程。有一个好处,非常非常大的好处,比其他都好的一个好处,这个地方是基于应用协议的。前端用户如果访问它,它反向代理失败了怎么办?因为它是基于应用协议的,它完全知道这个应用错了,是应用出错,并不是网络出错,这个时候处理的一个办法就是可以做重试的,在做重试过程中,可以重试到这台机器,可以大大降低用户前端访问出错的一个概率,只有在基于应用协议的时候才可以这么办。如果基于三层、四层协议做不到,如果机器没有宕,就是应用出错了,那么没有办法做到的。这是应用协议一个非常大的好处。
    这个方案还有一个坏处,也是一个非常非常大的坏处,这是个瓶颈,如果后端有很多台服务的话,因为它是代理,所有的流量都要经过它,这明显就成一个瓶颈了,可能集群不会超过20台,超过20台就受不了了。这个方案不适合大型的集群,尤其是请求量小、返回量大的数据。类似于web的请求,这种都不太适合,它会成为瓶颈。这个肯定不是单点,我画的是一个单点,毕竟它是一个代理,所以这是一个瓶颈。
    怎么解决这个瓶颈?下一个方案,效率低,代理服务器是瓶颈。优点是结构简单,调度灵活,可用性非常高,可以做重试,有的时候用户访问有问题,可能重试一次就没有问题了。
    方案2,它不是应用了,它是基于nat和dr模式。NAT在网络传输过程中,它修改目标地址或者原地址,或者是目标端口、原端口,以达到代理的模式,它不是一种代理,它通过把数据包在这个层次上修改,修改完了之后会发给,让对方以为是他发布的。回去的时候也有修改。还有DR,它通过一种IP切片,上面这个模式,从客户端到这儿,这个模式称之为NAT。这个模式通过客户端,到这儿,然后直接返回,这种模式称之为DR模式。它是一个IP切片,客户端访问它的时候,它通过修改路由,或者是修改链路层的地址重新发布出去,发到这儿以后,因为它跟它是一个IP,所以它往回发的时候,其实客户端不知道是它发的,以为是它发的,这样最大的一个好处是什么?服务器这端回流的数据就没有了,它只有请求数据,没有回去的数据,压力会非常非常小。并且互联网有一个特点,就是请求的包一定要远远小于回应的包。回去的数据如果不经过它,这个节点就可以大大降低了,所以说它只是起了一个调度的作用。这是它的优点。
    缺点跟优点一样,非常非常突出。它回去的时候不经过它,这端出错的时候,它根本坚持不到,没有办法再做重试,即使是NAT经过它,你也没有办法,因为现在NAT工作在四层,你没有办法得到应用层协议的错误。怎么处理这些问题?没法处理。所以有缺点,也有优点。
    决策服务器跟上面的原理一样,它要调度的信息,传过去,这个调度和前面有所不一样。刚才讲调度范围大了一点,那个调度可以调度长链接,因为它是基于应用协议的。如果说前端只是一个web的程序,后面是中间的服务,我可以给它建长链接,通过自己制定的应用协议可以不停地访问。因为我基于应用协议,哪怕是长链接,我也照调度不误。但是下面这个方案就不行了,这个方案达不到应用协议,它工作在四层。怎么处理这块?它的调度怎么调度?只能按照链接的建立调度。当前端发起建立请求的时候,发现C的标记以后,它认为是第一次握手,然后立马选择一台服务器跟它建立,然后在这个地方要插一个链接跟踪表,链接跟踪表什么样?再来一个包,如果不是C,它会找链接跟踪表,然后拿到目标机就可以了。它是创建的连接,这个有一个很大的问题,一旦连接建立完毕之后,它就再也没法调度了。尤其对长连接的中间层服务,连接一旦建立了,这个时候访问它的机器,访问它去了,它都没有访问了,所以造成应用层面协议上的访问不均衡,它会负载很高,因为你是长连接,你建立一次就完了,有的甚至是连接池。这是一个很大的问题。
    服务器刚才说了原理是一样的,它会选择调度,它照样会有一个intemet。这是第二个方案。缺点是无法检测应用级错误,基于连接的调度,然后结构复杂。
    方案三只是一个概念,没有实现过,前两个方案都实现过,这个方案没有实现过,优缺点就不列了,我可以简单说一下,没有实践,我也没有发言权,我只是简单把这个思路说一下,可以作为抛砖引玉,大家有兴趣的话可以实践一下。
    这个比较简单有效,我前面没有写代理,它就是一个负载,什么都可以。自己写都可以,最好是自己写,为什么自己写?因为它有一个功能,一会儿会讲到。正常的模式,来的请求,你调度就可以了。然后附加了一个Monitor,这个监测上面的服务进程。所有的进程,这个上面起的几个服务实例,它都知道,在他这儿备案了,过一段时间,它就去通过Intemet告诉它这个进程怎么样,比如说占CPU多少,连接多少,过一段时间会去问,当然汇报也可以。当发现这些进程,比如说一个服务实例,一个站点起了两个进程,发现这两个进程占用的资源非常高,再不起实例就有问题了,这个时候通过判断两个服务器的资源情况,选择一个服务器,通过intemet发布一个指令,现在就两个实例,创建完了以后,成功之后,把这个实例发给它,它要加进去。加进去就能够知道密码,不需要重启了。我也不知道这个对不对,Linux好象做不到,加进去还得重启一下。本身它功能比较简单,自己写一下也没有多少困难,并且还能够实现功能。Linux要实现的话,可能还要写一个插件,非常麻烦,还不如自己写快。好坏不做评价,因为这个没有实践过。这是咱们的方案3,monitor模式。
    接下来给大家介绍系统架构。因为是代理,它可以做到很好的应用层的判断。DRM模式在三四层做的,是基于Linux内核的一个项目,这个项目有一定的复杂性,我讲的时候会简化一下。
    项目立项的时候大概的一个目标,是基于Netfilter,它是Linux内核的一个网络框架,它是集负载均衡、自动部署、资源的动态分配等于一体的高可用、高效率、高弹性的平台。后端是资源池,或者是叫服务池都可以。但是咱们的理解它就是一台一台的资源,每台机器上有CPU资源、内存资源等等,我们可以合起来就是一个大池子,我们不区分体系,应用的时候可以细化一下,我们不是按照机器来的,我们是按照进程来的。它是以协议为基础,以服务为对象,服务不是说的中间服务,服务包括web站点,只要是别别人访问的都叫服务,DRM系统可以应用在站点上,也可以应用在服务,基本上网络访问都可以用的。
    简单说一下Netfilter。Netfilter是Linux内核的一个网络框架,提供了五个HOOK点,拦截到以后可以做你想做的事情。iptobles都是基于Netfilter的一个实现,它是内核的一个框架。目前还是很爽的,想干什么就可以干什么,爱怎么玩就怎么玩。
    这是Netfilter一个简单的架构图,这是我从网上下载在一个图。五个方块就是刚才提到的五个HOOK点。在这个上面是在调度机里面插了一个模块,主要用于数据包的二次调度,把包发过来再调度在资源机上。这个主要用在资源机上。因为你起的时候,比如说访问8081的一个服务,前端调度机是8081,但是后端不见得就是8081,那是随机的,一定要修改回来,这个主要是用来修改原端口的。有兴趣的可以查一下这个方面的资料,并不是特别复杂。这个是DRM的模块划分,左边是调度机上的模块右边是资源机上的模块。调度机分为内核和用户态,用户态主要是管理,比如说管理的一个界面,可以管理这些集群,因为内核不会让你直接管理,所以通过用户态的应用来管理内核的东西。
    集群管理后面会讲到,现在忽略。服务实例管理,它会对资源机上的实例,它会根据复杂的情况进行实例子的回收、实例的创建等等一系列的工作,全部由它来实现,就是前面提到的三大模块之一。调度管理,这个调度管理并没有新的意义,大家都很成熟。这个不是核心的东西。数据路由,尤其是DR里面的,数据包到的以后,要发给哪个,尤其是地址怎么修改,这个功能在路由里面。还有配置管理,配置管理是针对服务的,服务的物理文件存在哪儿,它的启动路径是什么,尤其是它最需要什么样的资源,比如说有的服务可能需要高CPU,有的服务不需要CPU,但是它需要内存。所以这些东西都是配置的。这些东西在调度的时候是一种参考价值。你需要高CPU,我们会找一台最空闲的CPU给你,如果你需要内存,我不考虑CPU,只要有大内存就可以给你起实例,它是根据配置来选择的,配置是影响实例将来起到哪个资源机的一个很重要的因素,这个首先是人工配置的,你要清楚你的服务需要什么,你别瞎配,结果配完了之后,搞的机器都晕头转向。一定要实事求是,有这个应用,就需要高内存,你分配的时候,优先给我分内存大的机器,需要高CPU的,你就给我分高CPU的。
    组播通讯,一对多、多对多的通讯非常多,前面有两个调度机,所有的资源机要定期做汇报,比如说三个周期收不到心跳,就认为你死了。这个时候前端有两个调度机,一主,一备,它需要一对多、多对多的通讯。中方式当中,组播是最佳的选择,是最快的,一群人,喊一嗓子大家都知道了,没有必要知道每个人都说一遍,这样浪费资源。所以组播通讯是最佳的,我后面会讲到通讯模型。
    另外一个是用户态,这个不说了。
    资源机上,就是管理服务实例的,负载同步什么概念?我要定期把机器上真实的负载情况,比如说CPU多少,内存剩多少,要统统反馈给调度机,调度机作为一个参考,你本身就起了一个进程,没有什么连接,你这个机器出了什么毛病,CPU已经百分之百,你还要去调度,这个有问题。给一个调度机,定期的给,调度机会做一个调度的参考,如果说进程多少,服务器确实很空闲,那么就往上面调度,这没有任何问题。组播通讯也是一样的,在资源机上有一个内核态,这个是往回发的一个Pnet的一个模式。
    这是DRM的一个架构图,上面黄色的图,这块是用户态管理的两个模块,这是集群管理和集群检测。这是一个服务管理。这是集群管理、服务实例管理,蓝色是调度机上的模块,中间是互相通讯需要的东西,另外一个是服务请求,服务请求不能都组播了,这块是通过资源机上的模块,一个是代理模块,所有的进程都是他托管的,我要起一个进程,都是通过它来起,所有的进程都是它的子进程,把它杀死了,起的所有实例都没有了。服务集成管理,要起,要关的这些,负载同步刚才说过。NAT这个也说了,回去的时候要修改原端口。DRM的根据,一个是流量的评估,就是间接的评估。还有一个是资源状态,这个是直接的,这个是通过机器上真实的CPU、内存反馈过去的,根据这两项综合起来做一个调度,这两个都是它的参考值。根据对资源的要求策略,查找合适的服务器。通过通讯模块发给资源机,通过进程模块把这个信息添加到调度机上,从而达到一个调度目的。
    这个图是可以展示这个过程的,上面有一个RS Table,它里面会有真实的机器目前的情况,它的负载情况,还有一个Conn Table,根据这两个的综合来产生一个调度方案,在哪个机器上部署一个服务。下一步通过组播通讯模块,把组播的信息,把创建服务实例的模块的这个命令发给对方。这边的组播通讯模块收到之后,创建之后有一个结果,它把这个东西添加到调度机上就可以了,这个过程就完成了。这是整个服务管理的一个过程,流程很简单,其实里面的细节还是蛮复杂的。
    这是资源机的代理模型,上面有控制模块,是控制进程的,还有通讯这些东西,还有SNAT。机器内部通讯模型,就是刚才说的组播,全部都是组播。应用协议,通讯的协议有几种,一个是创建实例,创建实例有一个协议模型,怎么创建,前面是什么,后面是什么,这个是创建实例的。还有销毁实例的一个协议,它不是一个协议。同步实例,因为它现在要保证一致,比如说隔5分钟要把服务实例同步给调度机,做一次校验,看一不一样,这样即使调度丢掉一个也没有关系,它一会儿就加上了。
    状态检测消息,说白了就是看看下面的资源机是不是活着,解决一个心跳。三个周期,每六秒钟做一次。如果三个周期收不到,就认为它死了。负载检测也一样。集群的管理,集群管理是通过用户态来管理的,用户态通过socket。服务文件的部署,有的公司几百台服务器,然后一点按纽就通过了。当然这到目前为止是很好的做法,但是我认为不是最好的做法,最好的做法是共享。我们通过Mount方式实现一个共享的文件夹。
    在现在的情况下,mount做了两层文件夹,我们有两台文件服务器,第一台宕掉了,它会找第二台。但是这不是我们的理想状态,我们的理想是做一个可挂载的分布式文件系统。我们现在刚开始,可行性还没有通过,成不成还不知道。
    应用场景,web站点,中间服务层。有一个问题需要强调一下,http的端口问题。DMR解决不了这个问题,怎么办?一个服务器上只能布一个服务,这是web的一个问题。目前DRM的问题还没有解决。我们正在想办法解决。
    还有就是中间服务层,SCF是58同城的中间服务件。这是我们完全自主开发的一个很高的规模,还有其他的,只要基于UDP完全都可以实现。
    最后一个模块,大集群的应用场景。其实刚才看见了,第一种设计方案和第二种设计方案如果结合起来的话,能够做到一个非常非常大的集群,并且可用性非常高。怎么做?我们做三层。这一层是代码,到它是通过第一个方案,基于代理的模式实现。而上面这一层是通过DRM来实现的,中间服务层可以无限扩展,在中间代理可以扩展,这样解决掉了代理层的瓶颈了。瓶颈受限制,再起一个代理就完了,但是资源机是不够用的。你要部署系统,就往共享文件上一步就可以了,一配置你就不用管了。什么突发流量都不用管了,突发流量可以自己部署。对于前端开发人员来讲,他永远不知道服务跑在哪几台服务器上。谁也不知道,就这个机器知道,所以你不用关心你的机器服务跑到哪儿了,如果有特殊处理,可以创建一些命令来实现。
    今天讲的PPT就到这儿。
    提问:58的系统里面,我刚才听你说的,它是机基于natDR模式来实现的,它和说的三层架构是一样的吗?听前面介绍里面没有涉及到代理模式,没有解决应用层的错误。
    刘晓飞:nat模式,它把第一种方案和第一种方案结合起来的,目前58并没有结合。结合起来以后,这一层可以解决高可靠的问题,而这一层可以解决流量的问题,这两个方案结合起来比较完美,但是这个方案要有很大的集群,因为三层需要很多机器才可以的。机器少的话,没有必要的情况下,如果方案都用对了,没有必要这样做。
    提问:刚才介绍58也有基于代理模式的那种。
    刘晓飞:有。
    提问:那种集群,它用于不同的业务场景是吧?
    刘晓飞:对,它是用于刚才讲到的SCF,一个是长连接,长连接的服务,其实基于自己的应用协议,所以它用代理模式最合适,如果用DR模式,基于应用是非常均衡的。
    提问:听了你这个演讲很精彩,我能不能简单理解为58同城是通过系统负载自测,然后来动态调整。
    刘晓飞:可以这么理解。
    提问:前端是四层加七层为基础,在三四层上加了负载。
    刘晓飞:对。
    提问:你刚才提到采用工作共享部署的方法,DRM包括很多内核模块和应用模块。如果内核模块,采用共享文件的方式部署的话,会不会碰到什么问题?
    刘晓飞:共享目录跟内核没有任何关系,共享放的是应用,放的站点的物理文件,启动的时候,那个是用户态的,不是内核态的,调一个物理文件,所以跟内核没有任何关系。
    提问:如果开发人员修改了组播协议什么的,可能会牵扯到内核或者是其他内核态的模块,需要一台机器做部署吗?
    刘晓飞:内核模块不能通过共享文件夹部署的,共享文件夹部署的是应用的物理文件,内核是加这个资源机是提前植入进去的,是一个标配。
    提问:如果有更改的话,线上的机器还要重新部署一次。
    刘晓飞:对,要把内核重新改一遍,一般情况下内核不会变的。
    提问:首先是刚刚提到的心跳检测和调动模块的问题。
    刘晓飞:强调一点,内核的东西一定是越小越好,用户态做的工作部署到内核就很危险了。
    提问:Linux大家知道,版本非常多,不同的版本接口也不一样,你们是统一业务同一个系统操作版本?
    刘晓飞:我们现在没有开源,用的版本非常统一,我们目前为止没有遇到这个问题,我们会下去研究一下Linux有没有这个问题。
    提问:后面所有的应用服务器的用户数据怎么做到状态同步的?比如说某个用户请求过来,它可能会定向到某个定向appsevre,它接下来的请求会转到其他的appsevre,这两个怎么做同步?
    刘晓飞:咱们是基于一个连接的,所有后续的数据都会基于这个连接,如果是Web的话,我请求一次web页面,所有的数据会到达一个服务器。
    提问:某个用户所有的连接都会固定在某个appsevre去做?
    刘晓飞:连接所有数据包会到一个服务器,不会分开。
    提问:两个不同连接之间的数据……
    刘晓飞:如果是web服务器,我们基本上不用的,如果是随机调度也会出现问题,我们一般建议用hook,或者是其他的方式。
    提问:刚才提到的整个架构,主要是对于用户请求web的一个用户请求,但是对于系统内部的一些请求,对于内部的请求,这个调度系统能够调度吗?
    刘晓飞:可以。我刚才说到了,因为下面标的是internet的模式,局域网和互联网都可以,对于局域网它前端就是一个web,后端是一个中间服务。
    提问:总的内存缓存很大,你请求一个缓存的数据的时候,可能是在某台特定的机器上,你去某一台web应用服务其访问一个缓存,是直接交给调度吗?
    刘晓飞:咱们这个调度是对应用完全透明的,它访问起来就是一台机器,一个IP,你调度的时候,你调度这个IP,如果有客户端就直接一个IP就可以了,因为它是长连接,长连接建立完毕以后,它就永远可以接受请求。但是如果分配算法和连接的调度有关系的话,这样会产生一些数据不存在的。其实这个问题可以通过其他方式来解决的。
    冯大辉:感谢刘晓飞带来的精彩分享。