作者:子柳

书中主要围绕网站的业务和系统架构之间的关系展开论述。

第0章 引言:光棍节的狂欢

2011年11月11日这一天,淘宝商城与淘宝网交易额之和突破52亿元人民币,这个数字是“购物天堂”香港一天零售总额8.5亿元的6倍。 网民感受到的是疯抢的喜悦,而网站的技术人员感受到的却是“压力山大”。就如同你家办酒席,宴请左邻右舍,这个办起来容易,倘若宴请十里八乡所有的人,吃饭的人固然开心,但却不是一般人家能够办得起来的。

用户进行搜索时常常有如下几类意图。 ● 浏览型:没有明确的购物对象和意图,边看边买,用户比较随意和感性。Query1例如:“2010年10大香水排行”、“2010年流行毛衣”、“zippo有多少种类?”; ● 查询型:有一定的购物意图,体现在对属性的要求上。Query例如:“适合老人用的手机”、“500元手表”; ● 对比型:已经缩小了购物意图,具体到某几个产品。Query例如:“诺基亚E71 E63”、“akg k450 px200”; ● 确定型:已经做了基本决定,重点考察某个对象。Query例 如:“诺基亚N97”、“IBM T60”。 通过对你的购物意图的分析,主搜索会呈现出完全不同的结果。

另外,如果你在网上购买过火车票,更能体会到网站能支持多大的流量有多重要。但这不是一朝一夕就能做出来的,也不是有钱就能办到的。

任何网站的发展都不是一蹴而就的,通常是在什么阶段采用什么技术。在发展的过程中,网站会遇到各种各样的问题,正是这些原因才推动着技术的进步和发展,而技术的发展反过来又会促进业务的更大提升。二者互为因果,相互促进。

第1章 个人网站

他们去了一个神秘的据点——湖畔花园小区的一套未装修的房子里,房子的主人是马云。这伙人刚进去的时候,马云给他们布置了一个任务,就是在最短的时间内做出一个个人对个人(C2C)的商品交易的网站。这里出一个问题考考大家,看你适不适合做淘宝的创业团队:亲,要是让你来做,你怎么做? 在说出这个答案之前,我们先介绍一下这个创业团队的成员:三个开发工程师(虚竹、三丰、多隆)、一个UED工程师(二当家)、三个运营工程师(小宝、阿珂、破天)、一个经理(财神),以及马云和他的秘书。

LAMP架构的网站

了解淘宝历史的人都知道淘宝是在2003年5月10日上线的,2003年4月7日到5月10日,这之间只有一个月时间。要是你在这个团队里,你怎么做?不是“抄一个来”,我们的答案是——“买一个来”。

这个直到现在还是一个很常用的网站架构模型,其优点是:无须编译,发布快速,PHP语言功能强大,能做从页面渲染到数据访问所有的事情,而且用到的技术都是开源、免费的。

这个直到现在还是一个很常用的网站架构模型,其优点是:无须编译,发布快速,PHP语言功能强大,能做从页面渲染到数据访问所有的事情,而且用到的技术都是开源、免费的。

<aside> 💡 php是最好的语言 不是没有道理的哈哈哈

</aside>

这么做的好处有几点:存储容量增加了,有了备份,使得安全性增加了,读写分离使得读写效率得以提升(写要比读更加消耗资源,分开后互不干扰)。这样整个系统的架构就如下图所示。

第2章 个人网站的升级

eBay买断了新浪、搜狐、网易的电子商务类型的广告,签署了排他性协议,切断了淘宝在这上面做广告的路子。大路不通,我们就独辟蹊径,上网比较早的人应该还记得那些在右下角的弹窗和网站腰封上一闪一闪的广告,“淘宝网”几个字总是如影随形地出现在任何中小型网站上。市场部那位到处花钱买广告的家伙太能花钱了,一出手就是几百万元,他被我们称为“大少爷”。

数据库从mySQL到Oracle

于是工程师们不得不24小时开着手机,一旦收到“SQL Relay进程挂起”的短信,就从春梦中醒来,打开电脑,连上机房的网络,重启服务,后来干脆每天睡觉之前先重启一下。做这事最多的据说是三丰,他现在是淘宝网的总裁。现在我们知道,任何牛B的人物,都有一段苦B的经历。

脱胎换骨的升级——更换开发语言

把一个庞大的网站的开发语言换掉,无异于脱胎换骨,在换的过程中还不能拖慢业务的发展,这无异于边换边跑,对时间和技术能力的要求都非常高。

其实在任何时候,开发语言本身都不是系统的瓶颈,业务带来的压力更多的存在于数据和存储方面。

坚若磐石——围绕性能、容量和成本的进化

我们的做法是把用户的信息按照ID来存放到两个数据库中(DB1和DB2),把商品的信息和卖家信息放在两个对应的数据库中,把商品类目等通用信息放在第三个库中(DBcommon)。

他写了一个数据库路由的框架DBRoute,统一处理了数据的合并、排序、分页等操作,让程序员像使用一个数据库一样操作多个数据库里的数据,这个框架在淘宝的Oracle时代一直在使用

在2005年和2006年的时候,Spring大放异彩,于是在控制层用Spring替换掉了EJB,给整个系统精简了很多代码。

到2006年,淘宝网已经有了1.5亿个的日均PV,商品数达5千多万个,注册用户3千多万个,全网成交额达169亿元。

第4章 创造技术

用钱能解决的问题都不是问题,我们花钱可以购买更好的机器和更好的服务。但当你变成业内最强之后,你的问题就会独特到没有人碰到过,这就意味着你必须自己动手解决问题。

淘宝文件系统——TFS 淘宝KV缓存系统——Tair

淘宝文件系统——TFS

在一次架构师大会上,章文嵩博士总结了几点商用存储系统的局限和不足。 第一,商用存储系统没有对小文件存储和读取的环境进行有针对性的优化;第二,文件数量大,网络存储设备无法支撑;第三,整个系统所连接的服务器越来越多,网络连接数已经达到网络存储设备的极限;第四,商用存储系统扩容成本高,10TB的存储容量需要几百万元,而且存在单点故障,容灾和安全性无法得到很好的保证。

由于大量的文件信息都隐藏在文件名中,整个系统完全抛弃了传统的目录树结构,因为目录树开销最大。拿掉后,整个集群的高可扩展性可极大地提高。实际上,这一设计理念和目前业界的“对象存储”较类似。

目前淘宝网的TFS已经开源(见code.taobao.org),业界的同仁可以一起使用和完善这个系统。

淘宝KV缓存系统——Tair

这个产品带给我们的是新技术(AJAX、prototype框架)的尝试,以及新技术对用户操作习惯的改变,一定要慎之又慎。

一般的缓存策略是不支持实时更新的,这时候多隆大神想了个办法,在Apache上面写了一个模块,这个数字根本不经过下层的WebApp容器(只经过Apache)就写入一个集中式的缓存区了,这个缓存区的数据再异步更新到数据库。这就是我前面提到的,整个商品详情的页面都在缓存中了,把缓存用到了极致。

TBstore的分布式算法实现:根据保存的Key(关键字),对key进行Hash算法,取得Hash值,再对Hash值与总Cache服务器数据取模。然后根据取模后的值,找到服务器列表中下标为此值的Cache服务器。由Java Client API封装实现,应用无须关心。

由于TDBM、TBstore的数据接口和用途都很相似,开发团队把二者合并,推出了淘宝自创的Key-Value缓存系统——Tair (TaoBao Pair的意思,Pair即Key-Value数据对)

第5章 分布式电子商务操作系统

服务化 中间件 Session框架 开放平台

服务化

上面说的都是比较小的复用模块,到2006年,我们做了一个商品类目属性的改造,在类目中引入了属性的概念。项目的代号叫做“泰山”,如同它的名字一样,这是一个举足轻重的项目,这个改变是一个划时代的创新。在这之前的三年时间内,商品的分类都是按照树状一级一级的节点来分的,随着商品数量的增长,类目也变得越来越深,且越来越复杂,这样,买家如果要查找一件商品,就要逐级打开类目,找商品之前要弄清商品的分类。而淘宝运营部门管理类目的小二也发现了一个很严重的问题,例如,男装里有T恤、T恤下面有耐克、耐克有纯棉的,女装里也有T恤、T恤下面还是有耐克、耐克下面依然有纯棉的,那是先分男女装,再分款式、品牌和材质呢,还是先分品牌,再分款式、材质和男女装呢?弄得很乱。这时候,一位大侠出来了——一灯,他说品牌、款式、材质等都可以叫做“属性”,属性是类似Tag(标签)的一个概念,与类目相比更加离散、灵活,这样也缩减了类目的深度。这个思想的提出一举解决了分类的难题!从系统的角度来看,我们建立了“属性”这样一个数据结构,由于除了类目的子节点有属性外,父节点也可能有属性,于是类目属性合起来也是一个结构化的数据对象。

虽然个别架构师具备了“代码洁癖”,但淘宝前台系统的业务量和代码量还是呈爆炸式的增长。业务方总在后面催,开发人员不够就继续招人,招来的人根本看不懂原来的业务,只好摸索着在“合适的地方”加一些“合适的代码”,看看运行起来像那么回事后,就发布上线。在这样的恶性循环中,系统越来越臃肿,业务的耦合性越来越高,开发的效率越来越低。借用当时比较流行的一句话“你写一段代码,编译一下能通过,半个小时就过去了;编译一下没通过,半天就过去了。”在这种情况下,系统出错的概率也逐步增长,常常是你改了商品相关的某些代码,发现交易出问题了,甚至你改了论坛上的某些代码,旺旺出问题了。这让开发人员苦不堪言,而业务方还认为开发人员办事不力。

叫做“火车模型”,即任何一个乘客没有上车,都不许发车。这样做最直接的后果就是火车一直晚点,新功能上线更慢了,我们能明显感觉到业务方的不满,空闻的压力肯定非常大。

在当时,如果已经把会员、交易、商品、评价这些模块拆分出来,就不用什么都重做一遍了。

我们把交易的底层业务拆分出来,叫交易中心(Trade Center,TC),所谓底层业务,就如创建订单、减库存、修改订单状态等原子型的操作;交易的上层业务叫交易管理(Trade Manager,TM),例如,拍下一件普通商品要对订单、库存、物流进行操作,拍下虚拟商品不需要对物流进行操作,这些在TM中完成

到2008年年底就做了一个更大的项目,把淘宝所有的业务都模块化,这是继2004年从LAMP架构到Java架构之后的第二次脱胎换骨。我们对这个项目取了一个很霸气的名字——“五彩石”(女娲炼石补天用的石头)。这个系统重构的工作非常惊险,有人称为“给一架高速飞行的飞机换发动机”。

分拆之后,系统之间还是必须要打交道的,越往底层的系统,调用它的客户越多,这就要求底层的系统必须具有超大规模的容量和非常高的可用性。

中间件

HSF是一个分布式的标准Service方式的RPC(Remote Procedure Call Protocol,远程过程调用协议)框架,Service的定义基于OSGI的方式,通讯层采用TCP/IP协议。

然后鲁肃提出做一个系统框架上的解决方案,把要发出的通知存放到数据库中,如果实时发送失败,再用一个时间程序来周期性地发送这些通知,系统记录下消息的中间状态和时间戳,这样保证消息一定能发出,也一定能通知到,且通知带有时间顺序,这些通知甚至可以实现事务性的操作。

Notify是一个分布式的消息中间件系统,支持消息的订阅、发送和消费,其架构图如下所示。 

例如,你的商品数据到了百亿级别的时候,任何一个库都无法存放了,于是分成2个、4个、8个、16个、32个……直到1024个、2048个。好,分成这么多,数据能够存放了,那怎么查询它?这时候,数据查询的中间件就要能够承担这个重任了,它对上层来说,必须像查询一个数据库一样来查询数据,还要像查询一个数据库一样快(每条查询在几毫秒内完成),TDDL就承担了这样一个工作。

Taobao Distributed Data layer(TDDL,后来有人对它取了个外号 ∶“头都大了”⊙﹏⊙b)

分库分表和异构数据库的数据复制。

Session框架

网站服务器只有一台的时候,用Session来解决用户识别是很简单的,但是当网站是一个集群的时候,同一用户的两次请求可能被分配到两台不同的服务器上处理。怎样保证两次请求中存取的Session值一致呢?还有一个问题:网站规模扩大时,对于一个具有上亿个访问用户的系统来说,当大部分用户的Session信息都存储在服务端时,要在服务端检索出用户的信息效率就非常低了,Session管理器不管用什么数据结构和算法都要耗费大量内存和CPU时间。如何解决服务端Session信息的管理?

开放平台

从原来20ms的响应时间飙升到了1s以上,此时由于HTTP请求的同步性,导致前端服务路由网关的集群线程都释放得非常慢

当时又想到了软负载切割Haproxy和LVS,一个是七层的网络软负载切割,一个是四层的负载切割,由于涉及业务,于是考虑用七层的软负载切割,尝试一台Haproxy挂7台虚拟机,然后运行期可动态调整,配置在出现问题的时候可人工干预切割流量。

充分利用多核能力用计算换内存;磁盘换内存,用并行设计来保证整体业务时间消耗不变甚至减少;Slave Shuffle来减少Mater的合并压力;数据压缩减少数据传输消耗和内存占用。

前5年是技术变革带动开放平台发展,而接下去的5年将会是业务变革和理解带动开放平台的阶段,对业务的理解直接决定了开放平台的价值所在

第6章 我在淘宝这八年

“支付宝认证”是淘宝的一个创新,淘宝在成立之初就要求卖家实名认证,最早的认证方式是让用户上传身份证照片,我们去连接公安系统的网站来核对信息,核对一个要交5元钱,成本相当高。后来浅雪@浅的雪过来做PD,提出了一个新的认证方式:我们认为银行一定有用户的身份信息,而支付宝又与银行有合作,那就可以通过银行的用户信息来验证身份。所以支付宝认证的原理就是:用户提交身份信息和银行账户,我们往这个账户里存钱,存进去之后,用户填写收到了多少钱(我们号称存过去的是1元钱以内的金额,实际上只有几分钱),如果用户填写的与我们向里面存的是一致的,那么这个人的身份就是对的。这不仅降低了认证的成本,也使认证的效率由原来的一周左右变成一天以内。由于我对支付宝比较熟,又做过PM,就理所当然地做起了这个项目的PM。据说,这个项目后来申请了专利,这的确是一个很大的创新。

在这个项目中有一个技术细节值得说说,“淘宝商品详情页面”每天的流量在10亿次以上,其中的内容都是放在缓存里的,做“招财进宝”的时候,我们要给卖家显示他的商品被浏览的次数,这个数字必须实时更新,而用缓存一般都是异步更新的。于是商品表中增加了这样一个字段,每增加一个PV,这个字段就要更新一次,发布上去一个小时后,数据库就挂掉了,撑不住这么高的更新。数据库撑不住怎么办?一般的缓存策略是不支持实时更新的,这时候多隆大神想了个办法,在Apache上面写了一个模块,这个数字根本不经过下层的Web容器(只经过Apache)就写入一个集中式的缓存区了,这个缓存区的数据再异步更新到数据库。好像什么问题到了多隆手里,总能迎刃而解。

有读者担心,写到后面会不会变太监了。其实,越往后面越难写,一方面是那些人就在你旁边,你要顾及他们的感受;而那些事,也才刚刚过去或者正在进行中,身在其中,很难有个客观的描述。不过既然都写了这么多,那就继续写下去吧,后面的事情比较近,也不太有名,估计感兴趣的人不多了。

接口测试的思路很简单,就是用测试代码来验证系统代码的逻辑是否正确。但做起来很难,最大的困难就是被测代码太“拥抱变化”了,三天两头地变,测试代码经常会失效;另一个问题就是要验证一个业务逻辑,也许要用10倍的测试代码才能覆盖,所以,这事儿也是一个体力活。我们发现系统越往下层,变动越小,逻辑越简单,于是我们就从底层的IC、TC、UIC开始测试。测试代码写完之后,放入持续集成的环境中,一旦被测代码提交SVN,测试代码就回归一遍,把错误信息发布出来。2009年是这个团队异常艰难的一年,我们把底层的代码都做了接口测试,有些还有性能的测试。我记得做UIC接口测试的时候,模拟了10亿次以上的请求量,结果发现了JDK中的Bug,并提交给了Sun公司。做这些事情的过程中,我们也对常用的测试方法做了一个抽象处理,弄了一个测试的框架,写了一本《接口测试白皮书》。

在得到老板们的支持之后,我们开始花重金在内部悬赏这样的课程,把某项技术讲透,需要8个小时以上的时间,需要有良好的课程设计和授课技能

培训的本质到底是什么呢?经过老板提点,我们认为培训的本质是:“通过知识的流转,促进员工的成长,进而推动公司业绩的提升。”那又有老板会问:“你们怎么证明自己的工作提高了公司的业绩?”这是一个好问题,呵呵……有一天我听到农夫山泉的一个广告,说“我们不生产水,我们是大自然的搬运工”,我灵光一闪、再闪……“我们不生产知识,我们是知识的搬运工”。我们搬得越多,别人接收得越多,我们的价值就越大。我不知道我这瓶水是拯救了饥渴的生命,还是呛到了谁的肺,但我知道它一定有价值。 随着理论的补充和姑娘们的努力(@奇怪的伟大别介意,我们把你当姑娘了),在年中特殊晋升的机会中,我升了一级,变成了M2。

在线文档的难度不在于产生内容,而在于内容的吸引力,PPT很难承载有实质内容的东西,PDF太长的话又没有人看

这些新的学习方式的探索是一个长期的过程,搭建一个平台很容易,上传很多内容也不难,最重要的是坚持维护其中的内容和及时更新有效信息,我相信只要保持这种热情和精力的投入,在线学习的平台未来能够发挥出比线下培训更大的作用。

我认为互联网行业的知识不是要去管理的,而是要让隐性的知识显性化,在它的生命周期里迅速传播出去。我们不需要等它沉淀,只需要让足够多的知识流动起来,就能创造巨大的价值。

于是在老板来了三个月后,我们启动了一个“小三通”和一个“大三通”项目,“小三通”就是培训资源的打通,包括课程、讲师、解决方案的互通有无;“大三通”是培训平台的打通,培训的资源放进同一个平台里。我任“小三通”项目的PM、苏苏(就是《人人都是产品经理》的作者苏杰)任“大三通”项目的PM。

正明——集团核心系统高级研究员

子柳:你对刚入行的技术人员有什么建议? 正明:找到自己感兴趣的,花时间投进去,通过实践后的知识积累比只看书本有用得多。我看过一本操作系统方面的英文书,其中引用了一段中国人的格言:“I hear and I forget.I see and I remember. I do and I understand”,这句话给我留下非常深刻的印象。是荀子说的“不闻不若闻之,闻之不若见之,见之不若知之,知之不若行之。”

正祥——淘宝高级研究员,OceanBase项目负责人

最近,很多企业开始做NoSQL的系统,其实这个NoSQL可以说“No SQL”或者“Not Only SQL”,我更倾向于叫后者,咱不能否定SQL。

关系数据库的数据规模受限的根本原因是目前的关系数据库尽管有各种方式的扩展,但本质上是单机系统。

OceanBase最好的地方就是具备事务,数据一致性很好。HBase在数据容量上会有优势,几千万亿字节都有可能,但它没有解决事务的问题

子柳:从你的经历来看,你对现在的技术人员的成长有什么建议? 正祥:很多人会说年轻人比较浮躁,其实我的身边有很多非常优秀的年轻人,他们聪明、刻苦、有闯劲、愿意接受新事物。年轻的同事想赚钱,想提升自己的职称,这些都是十分正常的。在这点上,我特别喜欢马总的理念——做公司要赚钱,但阿里从不把赚钱作为第一目标,我们服务好了客户,客户赚了钱,我们一定会得到自己应得的一份。在个人成长问题上也是类似的道理,这就是,一个人如果把做事、做成事作为主要目标,该他得到的东西,一定会顺理成章的、水到渠成地得到,但是,如果把上升作为主要目标,做同样的事,结果就会完全不一样。一句话,你的心态会最终决定你的成就。

阳振坤博士(淘宝花名正祥),中国计算机学会YOCSEF荣誉委员。1984年进入北京大学,大学只用了三年,硕士只用了一年多,24岁成为王选的博士生。1997年破格晋升为教授,1999年成为北京大学首批“长江学者奖励计划”特聘教授之一,先后获得北京市科学技术进步奖一等奖、国家科学技术进步奖一等奖(排名第四)、第六届中国青年科技奖、北京市五四青年奖等。曾先后担任方正研究院副院长、北大计算机研究所副所长、联想研究院首席研究员、微软亚洲研究院主任研究员、百度高级科学家等。现担任淘宝高级研究员。

就我在职期间的感受——联想要求研发人员要了解市场,跟着一个产品从市场需求到开发,再到小批量生产、真正量产等整个环节。

我觉得百度其实不如淘宝重视技术,KPI导向的文化很重,各部门之间的协作和配合比较难(这一点淘宝要好不少),不同部门、不同项目的开发人员做了不少有差别但其实比较类似的东西,看起来个体效率高,但整体效率未必高,这可能是百度加班很严重的原因之一。