Skip to the content.

最开始的架构

技术组成

LAMP(Linux + Apache + MySQL + PHP)架构

原因

原因:要快速开发出来,技术开源、免费

技术改进

对数据库进行了修改,从一个数据库的读写操作,拆分为一个主库,两个从库,读写分离。

读写分离

发送 sql 请求,主库不执行读操作,从库执行读操作。读写分离使得读写效率得以提升(写比读更加消耗资源,分开后互不干扰)

主库写,从库读,需要解决主从直接的数据同步。主从的同步一般由数据库来实现。

网站升级

升级内容

数据库替换原因

MySQL 撑不住当时的业务量了,Oracle 容量大、稳定、安全、性能高,而且阿里巴巴有很强的 DBA 团队

采用连接池技术,避免申请连接,关闭连接的开销(Oracle 的连接是长连接,进程级别的很消耗资源)。

支付创新的原因

买卖双方存在不诚信的交易,货到了不给钱。逐步想到了“担保交易”这种散发托管资金的方式。便开发出来一个安全交易功能,供卖家选择。

坑:银行虽支持在线支付,但是网关五花八门,杂乱。所以公司人员跑断腿,各种申请在线支付接口,统一化支付方式。

淘宝旺旺

对比 eBay,淘宝允许买卖双方交流。【符合当时人们的兴趣??】

企业级Java网站

Java 的特点

Java 是当时最成熟的网站开发语言,有良好的企业开发框架,网站开发的主流语言,且具备 Java 开发经验的人才多,后续维护成本低。

更换语言

问题:

解决:

思考:

性能、容量和成本的进化

Oracle 的处理能力有上限,要想办法减轻它的压力

创新技术

为何创新?

市面上的技术无法解决自身的问题时,只能创新技术了。

淘宝文件系统 TFS

淘宝的数据量太大了。尤其是图片,2010 年保存着 286 亿个图片文件。图片的访问流量占到了 90%,且图片的平均大小为 17.45KB,小于 8K 的图片占比为 60%。

大规模小文件的存储和读取需要磁头频繁的寻道和换道(比如要查找 ABC 三张图,找到 A 了,接下来找 B 需要寻道,找到 B 了,要找 C 需要寻道。由于文件本身很小,读取时间短,这就放大了寻道时间在 IO 中占的比例了)

在研发 TFS 的时候,Google 公布了 GFS 的设计论文,为 TFS 带来了很多借鉴的思路【CS、SE 是理论与实践相结合的,不仅需要实践,也需要理论作为支撑】

由于文件大小比较统一,可以采用专有文件系统由于并发量高,读写随机性强,需要更少的 I/O 操作;考虑到成本和备份,需要用廉价的存储设备;考虑到容灾,需要能平滑扩容。

淘宝缓存系统Tair

在使用新技术/改变使用方式时要考虑好用户习惯,否在会适得其反。

分布式电子商务操作系统

架构师要考虑系统的扩展性、重用性。

服务化

最开始商品的分类是按树状一级一级来分的,商品数量不断增加,节点越来越深,越来越复杂。用属性替换商品的分类,品牌、样式、材质、男装女装都是属性。建立属性这样的数据结构,把其独立为一个服务。【那一个商品岂不是有很多的属性字段?这种表如何设计?】

个人感觉:当一类操作十分复杂时,可以对其进行优化拆分,拆分为一个服务,供其他系统调用。不仅解耦,也更容易拓展。

中间件

服务拆分后如何获得需要的服务?

在显示屏上把能提供的服务显示出来,有需要时先看显示屏,寻找服务所在的区域,然后去这个区域。

分布式的消息中间件系统,支持消息的订阅、发送和消费。

注册消息服务,消息的客户端订阅消息服务。某个客户端发送一条消息, NotifyServer 把消息发送到所有订阅这个消息的客户端。

为了保证消息一定能发出,且对方也一定能收到,消息数据本身就需要记录下来,这些信息存放在数据库中(可以是各种数据库)。由于消息具有中间状态(已发送、未发送等),应用系统通过 Notify 可以实现分布式事务—— BASE(基本可用(Basically Available)、软状态(SoftState)、最终一致(Eventually Consistent))。NotifyServer 可以水平扩展,NotifyClient 也可以水平扩展,数据库也可以水平扩展,从理论上讲,这个消息系统的吞吐量是没有上限的,现在 Notify 系统每天承载了淘宝 10 亿次以上的消息通知。

数据库也得拆分!

淘宝很早就对数据进行过分库的处理,上层系统连接多个数据库,中间有一个叫做 DBRoute 的路由来对数据进行统一访问。DBRoute 对数据进行多库的操作、数据的整合,让上层系统像操作一个数据库一样操作多个库。但是随着数据量的增长,对于库表的分法有了更高的要求,例如,你的商品数据到了百亿级别的时候,任何一个库都无法存放了,于是分成 2 个、4 个、8 个、16 个、32 个……直到 1024 个、2048 个。好,分成这么多,数据能够存放了,那怎么查询它?这时候,数据查询的中间件就要能够承担这个重任了,它对上层来说,必须像查询一个数据库一样来查询数据,还要像查询一个数据库一样快(每条查询在几毫秒内完成),TDDL 就承担了这样一个工作。

一台服务器时,用 Session 解决用户识别很简单。集群的时候,用户的请求可能会被分配到不同的服务器上,如何保证这些请求中存取的 Session 值一致?

用户过多时,用户信息都存在 Session 中,检索效率就低了。

session 共享的解决:【成本高,性能差】

硬件负载,将用户请求分发到特定的服务器。【成本高】

Session 复制,就是将用户的 Session 复制到集群内所有的服务器。【性能差,浪费内存】

结尾

和做科研很像。先调研下大家怎么做的,然后判断下是不是适合用在自己的任务上,再根据实验结果针对性优化。