《淘宝技术这十年》读后总结
阅读背景
最近一段时间在学习架构设计,查阅资料时意外发现了淘宝“子柳”的博客,然后就看到这本博客集锦《淘宝技术这十年》。作为一个在小微企业摸爬滚打 5 年的后端开发者,通篇读完,感触颇丰,就想通过这篇文章总结深化下理解,也分享下自己的思考。
挑战与解决方案
总观淘宝技术发展,“挑战”一词不断在我脑海出现。和每家从 0 开始的公司一样,随着公司业务发展、规模扩张,技术上面对的挑战总是不断涌现和变化。个人以为,淘宝技术的发展就是不断面对解决挑战的过程。
总览
1.0 版(2003 年 5 月—2004 年 1 月)
1.0 版的 PHP 系统运行了将近一年的时间,服务器由一台发展到多台;
1.1 版(2004 年 1 月—2004 年 5 月)
后来数据库撑不住了,将 MySQL 换成了 Oracle,引入了搜索引擎;
2.0 版(2004 年 2 月—2005 年 3 月)
不到半年的时间又把开发语言换成了 Java;
数据服务逐步采用了 IOE;
2.1 版(2004 年 10 月—2007 年 1 月)
随着数据量和访问量的增长,我们进行数据分库、加入缓存、使用 CDN;
挑战 1:从 0 开始--天下武功唯快不破
一步到位:买一个 LAMP
二次开发:把它拆分成一个主库、两个从库,并且读写分离
挑战 2:用户量增加--单机承载瓶颈
机器扩容:服务器由最初的一台变成了三台,一台负责发送 Email、一台负责运行数据库、一台负责运行 WebApp。
搜索独立:like 搜索 => 阿里巴巴中文站的搜索引擎 iSearch
挑战 3:04 年,用户量 23 万--数据库瓶颈
数据库替换:MySQL(MyISAM)=>Oracle,MySQL(MyISAM)数据库主从同步存在表锁、主键冲突问题(先天不足),阿里巴巴 Oracle DBA 已经很强大。
连接池处理:优化 php 连接处理
硬件演进:负载均衡 Oracle RAC、存储设备 NetApp NAS(NFS)=>Dell 和 EMC 合作的 SAN
PS:当时 MySQL 5.0(2003 年 12 月)还没有发布,InnoDB 引擎从 5.0 版本才引入 MySQL
挑战 4:SQL Relay 连接池--漏洞百出
开发语言:php=>java,分模块,边跑边换
框架:MVC 框架是阿里的 WebX,控制层用了 EJB,持久层是 ibatis
硬件升级:RAC 撑不住,Oracle 就运行在了小型机上,存储方面,从 EMC 低端 CX 存储到 Sun oem hds 高端存储,再到 EMC dmx 高端存储,一级一级地往上跳
挑战 5:05 年,商品 1663 万,PV8931 万,会员 1390 万
优化 IOE:
分库分表
DBRouter
Spring 替换掉了 EJB
缓存和 CDN
基于 Berkeley DB 的缓存系统
LVS 的创始人章文嵩博士带人搭建了淘宝自己的 CDN 网络
挑战 6:06 年,淘宝网日均 PV1.5 亿,商品 5 千多万,用户 3 千多万,成交额 169 亿
问题描述
在 2010 年,淘宝网的后端系统上保存着 286 亿个图片文件
图片的访问流量要占到 90%以上
解决方案
有了 TFS、Tair 的系统架构图
缓存策略:大部分图片都尽量在缓存中命中,如果缓存中无法命中,则会在本地服务器上查找是否存有原图,并根据原图生成缩略图,如果都没有命中,则会考虑去后台 TFS 集群文件存储系统上调取。
缩略图都是实时生成的
2007 年 6 月,TFS 1.0 版本上线
2009 年 6 月,TFS 1.3 版本上线
缓冲
ESI
TBstore(memcached 还没崭露头角)
TDBM
Tair
挑战 7:07 年,淘宝网日均 PV2.5 亿,商品 1 亿个,会员 5 千多万,成交额 433 亿元
问题描述
系统越来越臃肿,业务的耦合性越来越高,开发的效率越来越低
引用“你写一段代码,编译一下能通过,半个小时就过去了;编译一下没通过,半天就过去了。”
解决方案:
回归测试--“火车模型”
去 IOE
底层的基础服务继续拆分,从底层开始扩容,上层才能扩展,模块的逐步拆分和服务化改造
HSF
Notify
TDDL
如何实现分布式 Join(连接)
如何实现高速多维度查询
如何实现分布式事务
Rtools/JADE 作为数据库运维平台的组件被提了出来
Tbsession 框架
书中警句
能办得起来如此盛宴者,需要强大的财力和物力、组织能力、技术实力(例如做这么多菜,你的炒锅一定要是“分布式的”、“可复制的”、“可扩展的”,洗菜和切菜要有“工作流引擎”,跑堂的要计算一下最优路径,甚至连厨房的下水道都要重新设计)。
你需要知道的是,你每天使用的互联网产品看似简单易用,背后却凝聚着难以想象的智慧与劳动。
在发展的过程中,网站会遇到各种各样的问题,正是这些原因才推动着技术的进步和发展,而技术的发展反过来又会促进业务的更大提升。二者互为因果,相互促进。
买一个网站显然比做一个网站要省事,但是他们的梦想可不是做一个小网站而已,要做大,就不是随便买一个就行的,要有比较低的维护成本,要能够方便地扩展和二次开发。那么接下来就是第二个问题:买一个什么样的网站?答案是:轻量一点的,简单一点的。于是买了这样一个架构的网站:LAMP(Linux+Apache+MySQL+PHP),这个直到现在还是一个很常用的网站架构模型,其优点是:无须编译,发布快速,PHP 语言功能强大,能做从页面渲染到数据访问所有的事情,而且用到的技术都是开源、免费的。
现在我们知道,任何牛 B 的人物,都有一段苦 B 的经历。
微博上有人说“好的架构是进化来的,不是设计来的”。的确如此,其实还可以再加上一句“好的功能也是进化来的,不是设计来的”。我的师父黄裳曾经说过“好的架构图充满美感”。一个架构好不好,从审美的角度就能看出来。
其实在任何时候,开发语言本身都不是系统的瓶颈,业务带来的压力更多的存在于数据和存储方面。
到现在为止,整个商品详情的页面都在缓存里面了,眼尖的读者可能会发现现在的商品详情不全是“只读”的信息了,这个页面上有个信息叫“浏览量”(这个信息是 2006 年加上去的),这个数字每刷新一次,页面就要“写入”存储一次,这种高频度实时更新的数据能用缓存吗?通常来说,这种是必须放进数据库的,但是悲剧的是,我们在 2006 年开发这个功能的时候,把浏览量写入数据库,发布上线 1 个小时后,数据库就挂掉了,每天几亿次的写入,数据库承受不了。那怎么办?亲,……先不回答你,后面讲到缓存 Tair 的时候再说。
对于大多数系统来说,最头疼的就是大规模的小文件存储与读取,因为磁头需要频繁寻道和换道,因此,在读取上容易带来较长的延时。在大量高并发访问量的情况下,简直就是系统的噩梦。
个人感受
业务推动技术,技术促进业务
回头看看这几年,成长最快时往往都是业务发展比较快的时候。从几个人的内部 ERP 到几十人的订单管理,再到 SAAS 版的订单管理。随着使用人数的增加、单量的增加,前端页面、负载均衡、业务服务器、数据库都会出现各种未预料(但在情理之中)的情况。比如用户等待超时无响应、重复点击按钮、JVM 崩溃、内存泄露、数据库堵死等等。每一个情况的出现,往往都是需要架构重构,不断优化技术以支持当前业务。可以说淘宝的业务培养了淘宝的团队,同时淘宝的团队创造了淘宝的业务。
淘宝不是一天练成的
浏览量写表,导致数据库挂掉。原以为只有小微企业才会出现的情况,想不到淘宝也曾出过,而且不止一次。系统挂掉的原因也是层出不穷,各个阶段各有特点,好像到了 07 年之后才算稳定的“坚如磐石”。想想这个和我们公司当下的产品情况何其相似,突然也对自己公司的产品多了几分宽容。
十年技术事一代技术人
2010 年我刚刚迈入大学,淘宝技术体系刚刚成型;到现在十年已经过去,分布式、微服务各种大数据高并发概念和技术都已日臻成熟,回过头来看看淘宝当年的探索和创造。不禁让人感叹,这十年技术的进步确实飞快,曾经先辈们面对的未知和创造,轮到我们就已经是理论框架都较为成熟了。这些探索和创造不知经过了多少苦 B 的日子,提心吊胆的夜晚,致敬致敬。
附录
子柳博客
http://blog.sina.com.cn/s/blog_633219970100vz44.html
HSF 举例(引自《淘宝技术这是十年》)
互联网系统的发展看似非常专业,其实在生活中也存在类似的“系统”,正如一位哲学家说“太阳底下无新事”。我们可以从生活中的一个小例子来看网站系统的发展,这个例子是 HSF 的作者毕玄写的。
一家小超市,一个收银员,同时还兼着干点其他的事情,例如,打扫卫生、摆货。来买东西的人多起来了,排队很长,顾客受不了,于是增加了一个收银台,雇了一个收银员。
忙的时候收银员根本没时间去打扫卫生,超市内有点脏,于是雇了一个专门打扫卫生的。随着顾客不断增加,超市也经过好几次装修,由以前的一层变成了两层,这个时候所做的事情就是不断增加收银台、收银员和打扫卫生的人。
在超市运转的过程中,老板发现一个现象,有些收银台排很长的队,有些收银台排的人不多,了解后知道是因为收银台太多了,顾客根本看不到现在各个收银台的状况。对于这个现象,一种简单的方法就是继续加收银台。但一方面,超市没地方可加收银台了,另一方面,作为老板,当然不需要雇太多的人,于是开始研究怎样让顾客了解到收银台的状况,简单地加了一个摄像头和一个大屏幕,在大屏幕上显示目前收银台的状况,这样基本解决了这个问题。
排队长度差不多后,又出现了一个现象,就是有些收银台速度明显比其他的慢,原因是排在这些收银台的顾客买的东西特别多,于是又想了一招,就是设立专门的 10 件以下的通道,这样买东西比较少的顾客就不用排太长的队了,这一招施展后,顾客的满意度明显提升,销售额也好了不少,后来就继续用这招应对团购状况、VIP 状况。
在解决了上面的一些烦心事后,老板关注到了一个存在已久的现象,就是白天收银台很闲,晚上则很忙,于是从节省成本上考虑,决定实行部分员工只在晚上上班的机制,白天则关闭一些收银台,顾客仍然可以通过大屏幕看到哪些收银台是关闭的,避免走到没人的收银台去,实行这招后,成本大大降
低了。
这个生活中的例子及其解决的方法,其实和互联网网站发展过程中的一些技术是非常类似的,只是在技术层面用其他名词来表达了而已,例如,有集群、分工、负载均衡、根据 QoS 分配资源等。
集群:所有的收银员提供的都是收银功能,无论顾客到哪一个收银员面前,都可完成付款,可以认为所有的收银员就构成了一个集群,都希望能做到顾客增加的时候只需增加收银员就行。在现实生活中有场地的限制,而在互联网应用中,能否集群化还受限于应用在水平伸缩上的支撑程度,而集群的规模通常会受限于调度、数据库、机房等。
分工:收银员和打扫卫生的人分开,这种分工容易解决,而这种分工在互联网中是一项重要而复杂的技术,没有现实生活中这么简单,涉及的主要有按功能和数据库的不同拆分系统等,如何拆分以及拆分后如何交互是需要面临的两个挑战。因此,会有高性能通信框架、SOA 平台、消息中间件、分布式数据层等基础产品的诞生。
负载均衡:让每个收银台排队差不多长,设立小件通道、团购通道、VIP 通道等,这些可以认为都是集群带来的负载均衡的问题,从技术层面上说,实现起来自然比生活中复杂很多。
根据 QoS 分配资源:部分员工仅在晚上上班的机制要在现实生活中做到不难,而对互联网应用而言,就是一件复杂而且极具挑战的事。
版权声明: 本文为 InfoQ 作者【彬】的原创文章。
原文链接:【http://xie.infoq.cn/article/da767a4cbfd0953c527116043】。
本文遵守【CC-BY 4.0】协议,转载请保留原文出处及本版权声明。
评论