深入浅出计算机组成原理学习笔记:第五十二讲
一、原理篇总结回顾
如果你一讲一讲跟到现在,那首先要恭喜你,马上就看到胜利的曙光了。过去的50多讲里,我把计算机组成原理中的各个知识点,一点一点和你拆解了。对于其中的很多知识点,
我也给了相应的代码示例和实际的应用案例。
不过呢,相信你和我一样,觉得只了解这样一个个零散的知识点和案例还不过瘾。那么从今天开始,我们就进如应用篇。我会通过两个应用系统的案例,串联起计算机组成原理的两大块知识点,一个是我们的整个存储器系统,另一个自然是我们的CPU和指令系统了。
我们今天就先从搭建一个大型的DMP系统开始,利⽤组成原理⾥⾯学到的存储器知识,来做选型判断,从⽽更深⼊地理解计算机组成原理。
二、DMP:数据管理平台
我们先来看一下什么是DMP系统。DMP系统的全称叫作数据管理平台(Data?Management?Platform),目前广泛应用在互联网的广告定向(Ad?Targeting)、个性化推荐(Recommendation)这些领域。
通常来说,DMP系统会通过处理海量的互联网访问数据以及机器学习算法,给一个用户标注上各种各样的标签。然后,在我们做个性化推荐和广告投放的时候,再利用这些这些标签,去做实际的广告排序、推荐等
工作。无论是Google的搜索广告、淘宝里千人千面的商品信息,还是抖音里的信息流推荐,背后都会有一个DMP系统。
一个DMP系统应该怎么搭建呢?
那么,一个DMP系统应该怎么搭建呢?对于外部使用DMP的系统或者用户来说,可以简单地把DMP看成是一个键-值对(Key-Value)数据库。我们的广告系统或者推荐系统,可以通过一个客户端输如用户的唯一标识(ID),然后拿到这个用户的各种信息。
这些信息中,有些是用户的人口属性信息(Demographic),比如性别、年龄;有些是非常具体的行为(Behavior),比如用户最近看过的商品是什么,用户的手机型号是什么;有一些是我们通过算法系统计
算出来的兴趣(Interests),比如用户喜欢健身、听音乐;还有一些则是完全通过机器学习算法得出的用户向量,给后面的推荐算法或者广告算法作为数据输入。
基于此,对于这个KV数据库,我们的期望也很清楚,那就是: 低响应时间(Low Response?Time)、 高可用性(High Availability)、 高并发(High Concurrency)、 海量数据(Big Data),同时我们需要付得起对应的成本(AffordableCost)。如果用数字来衡量这些指标,那么我们的期望就会具体化成下面这样。
对于这个KV数据库,我们的期望如下
1.低响应时间:一般的广告系统留给整个⼴告投放决策的时间也就是10ms左右,所以对于访问DMP获取用户数据,预期的响应时间都在1ms之内。
2.高可用性:DMP常常用在广告系统里面。DMP系统出问题,往往就意味着我们整个的广告收入在不可用的时间就没了,所以我们对于可用性的追求可谓是没有上限的。Google?2018年的⼴告收⼊是1160亿美
元,折合到每一分钟的收入是22万美元。即使我们做到99.99%的可用性,也意味着每个月我们都会损失100万美元。
3.高并发:还是以广告系统为例,如果每天我们需要响应100亿次的广告请求,那么我们每秒的并发请求数就在100亿/(86400)~=12K次左右,所以我们的DMP需要支持高并发。
4.数据量:如果我们的产品针对中国市场,那么我们需要有10亿个Key,对应的假设每个用户有500个标签,标签有对应的分数。标签和分数都用一个4字节(Bytes)的整数来表示,
那么一共我们需要10亿x500x(4+4)Bytes=400TB的数据了。
5.低成本:我们还是从广告系统的角度来考虑。广告系统的收入通常用CPM(Cost Per Mille),也就是千次曝光来统计。如果千次曝光的利润是$0.10,那么每天100亿次的曝光就是100万美元的利润。这个利
润听起来非常高了。但是反过来算一下,你会发现,DMP每1000次的请求的成本不能超过$0.10。最好只有$0.01,甚至更低,我们才能尽可能多赚到一点广告利润。
这五个因素一结合,听起来是不是就不那么简单了?不过,更复杂的还在后面呢。虽然从外部看起来,DMP特别简单,就是一个KV数据库,但是⽣成这个数据库需要做的事情更多。
我们下面一起来看一看。
为了能够生成这个KV数据库,我们需要有一个在客户端或者Web端的数据采集模块,不断采集用的行为,向后端的服务器发送数据。服务器端接收到数据,就要把这份数据放到一个 数据管道(DataPipeline)里面。数据管道的下游,需要实际将数据落地到 数据仓库(Data Warehouse),把所有的这些数据结构化地存储起来。后续,我们就可以通过程序去分析这部分日志,生成报表或者或者利用数据运算各种机器学习算法。
除了这个数据仓库之外,我们还会有一个实时数据处理模块(Realtime Data Processing),也放在数据管道的下游。它同样会读取数据管道里面的数据,去进行各种实时计算,然后把需要的结果写入到DMP的KV
数据库里面去。
三、MongoDB真的万能吗?
面对这里的KV数据库、数据管道以及数据仓库,这三个不同的数据存储的需求,最合理的技术方案是什么呢?你可以先自己思考一下,我这里先卖个关子。
我共事过的不少不错的Web程序员,面对这个问题的时候,常常会说:“这有什么难的,用MongoDB就好了呀!”如果你也选择了MongoDB,那最终的结果一定是一场灾难。我为什么这么说呢?
MongoDB的设计听起来特别厉害,不需要预先数据Schema,访问速度很快,还能够无限水平扩展。作为KV数据库,我们可以把MongoDB当作DMP里面的KV数据库;除此之外,MongoDB还能水平扩展、跑
MQL,我们可以把它当作数据仓库来用。至于数据管道,只要我们能够不断往MongoDB里面,插入新的数据就好了。从运维的角度来说,我们只需要维护一种数据库,技术栈也变得简单了。看起来,MongoDB这
个选择真是相当完美!
但是,作为一个老程序员,第一次听到MongoDB这样“万能”的解决方案,我的第一反应是,“天底下哪有这样的好事”。所有的软件系统,都有它的适用场景,想通过一种解决方案适应三个差异非常大的应用场
景,显然既不合理,也不现实。接下来,我们就来仔细看一下,这个“不合理”“不现实”在什么地方。
1、数据管道和 数据仓库的性能取舍
上面我们已经讲过DMP的KV数据库期望的应用场景和性能要求了,这里我们就来看一下 数据管道和 数据仓库的性能取舍。
对于数据管道来说,我们需要的是高吞吐量,它的并发量虽然和KV数据库差不多,但是在响应时间上,要求就没有那么严格了,1-2秒甚至再多几秒的延时都是可以接受的。而且,和KV数据库不太一样
,数据管道的数据读写都是顺序读写,没有大量的随机读写的需求。
数据仓库就更不一样了,数据仓库的数据读取的量要比管道大得多。管道的数据读取就是我们当时写如的数据,一天有10TB日志数据,管道只会写如10TB。下游的数据仓库存放数据和实时数据模块读取的数据,
再加上个2倍的10TB,也就是20TB也就够了。
但是,数据仓库的数据分析任务要读取的数据量就大多了。一方面,我们可能要分析一周、一个月乃至一个季度的数据。这一次分析要读取的数据可不是10TB,而是100TB乃⾄1PB。
我们一天在数据仓库上跑的分析任务也不是1个,而是成千上万个,所以数据的读取量是巨大的。另一方面,我们存储在数据仓库里面的数据,也不像数据管道一样,存放几个小时、最多一天的数据,
而是往往要存上3个月甚至是1年的数据。所以,我们需要的是1PB乃至5PB这样的存储空间。
2、为什么MongoDB在这三个应用场景都不合适?
我把KV数据库、数据管道和数据仓库的应用场景,总结成了一个表格,放在这里。你可以对照着看一下,想想为什么MongoDB在这三个应用场景都不合适。
在KV数场据库的景下,需要支持高并发。那么MongoDB需要把更多的数据放在内存里面,但是这样我们的存储成本就会特别高了。
在数据管道的场景下,我们需要的是大量的顺序读写,而MongoDB则是一个文档数据库系统,并没有为顺序写入和吞吐量做过优化,看起来也不太适合。
而在数据仓库的场景下,主要的数据读取时顺序读取,并且需要海量的存储。MongoDB这样的文档式数据库也没有为海量的顺序读做过优化,仍然不是一个最佳的解决方案。而且文档数据库是总是会有很多冗余的字段的元数据,还会浪费更多的存储空间。
3、那我们该选择什么样的解决方案呢?
拿着我们的应用场景去找方案,其实并不难找。对于KV数据库,最佳的选择方案自然是使用SSD硬盘,选择AeroSpike这样的KV数据库。高并发的随机访问并不适合HDD的机械硬盘,而400TB的数据,
如果用内存的话,成本又会显得太高。
对于数据管道,最佳选择自然是Kafka。因为我们追求的是吞吐率,采用了Zero-Copy和DMA机制的Kafka最大化了作为数据管道的吞吐率。而且,数据管道的读写都是顺序读写,
所以我们也不需要对随机读写提供支持,用上HDD硬盘就好了。
到了数据仓库,存放的数据量更大了。在硬件层面使用HDD硬盘成了一个必选项。否则,我们的存储成本就会差上10倍。这么大量的数据,在存储上我们需要定义清楚Schema,使得每个字段都不
需要额外存储元数据,能够通过Avro/Thrift/ProtoBuffer这样的二进制序列化的方存储下来,或者干脆直接使用Hive这样明确了字段定义的数据仓库产品。很明显,MongoDB那样不限制
Schema的数据结构,在这个情况下并不好用。
2012年前后做光告系统的时候,我们也曾经尝试使用MongoDB,尽管只是用作DMP中的数据报表部分。事实证明,即使是已经做了数据层面的汇总的报表,
MongoDB都无法很好地支撑我们需要的复杂需求。最终,我们也不得不选择在整个DMP技术栈里面彻底废弃MongoDB,而只在Web应用里面用MongoDB。
事实证明,我最初的直觉是正确的,并没有什么万能的解决方案。
四、延伸总结
好了,相信到这里,你应该对怎么从最基本的原理出发,来选择技术债有些感觉了,你应该更多地从底层的存储系统的特性和原理去考虑问题。一旦能够从这个角度去考虑问题,那么你对各类新的技术项目和产品的公关稿,自然会有一定的免疫力了,而不会轻易根据商业公司的宣传来做技术选型了
因为低延时、高并发、写少读多的DMP的KV数据库,最适合用SSD硬盘,并且采用专门的KV数据库是最合适的,我们可以选择之前文章里提过的AeroSpike ,也可以用开源的Cassandra来提供服务
对于数据仓库、我们通常是一次写入、多次读取。并且,由于存储的数据量很大,我们还要考虑成本的问题于是、一方面,我们会用HDD硬盘而不是SSD硬盘;另一方面,我们往往会预先给数据规定好Schema,使得单条数据的序列化,不需要像存JSON或者MongoDB的BSON那样,存储冗余的字段名称这样的元数据。
所以,最常见的解决方案是,而Hadoop这样的集群,采用Hive这样的数据仓库系统,或者采用Avro/Thrift/ProtoBuffer这样的⼆进制序列化方案。
在大型的DMP系统设计当中,我们需要根据各个应用场景面临的实际情况,选择不同的硬件和软件的组合,来作为整个系统中的不同组件。