【计组】设计大型DMP系统--《深入浅出计算机组成原理》(十四)

news2024/12/24 9:04:21

目录

一、DMP:数据管理平台

二、MongoDB 真的万能吗

三、关系型数据库:不得不做的随机读写

(一)Cassandra:顺序写和随机读

1、Cassandra 的数据模型

2、Cassandra 的写操作

3、Cassandra 的读操作

(二)SSD:DBA 们的大救星


一、DMP:数据管理平台

DMP 系统的全称叫作数据管理平台(Data Management Platform),目前广泛应用在互联网的广告定向(Ad Targeting)、个性化推荐(Recommendation)这些领域。

DMP 系统会通过处理海量的互联网访问数据以及机器学习算法,给一个用户标注上各种各样的标签。然后,在做个性化推荐和广告投放的时候,再利用这些标签,去做实际的广告排序、推荐等工作。无论是 Google 的搜索广告、淘宝里千人千面的商品信息,还是抖音里面的信息流推荐,背后都会有一个 DMP 系统。

对于外部使用 DMP 的系统或者用户来说,可以简单地把 DMP 看成是一个键 - 值对(Key-Value)数据库。广告系统或者推荐系统,可以通过一个客户端输入用户的唯一标识(ID),然后拿到这个用户的各种信息。

这些信息中,有些是用户的人口属性信息(Demographic),比如性别、年龄;有些是非常具体的行为(Behavior),比如用户最近看过的商品是什么,用户的手机型号是什么;有一些是通过算法系统计算出来的兴趣(Interests),比如用户喜欢健身、听音乐;还有一些则是完全通过机器学习算法得出的用户向量,给后面的推荐算法或者广告算法作为数据输入。

基于此,对于这个 KV 数据库,我们的期望也很清楚,那就是:低响应时间(Low Response Time)、高可用性(High Availability)、高并发(High Concurrency)、海量数据(Big Data),付得起对应的成本(Affordable Cost)。如果用数字来衡量这些指标,那么我们的期望就会具体化成下面这样。

  • 低响应时间:一般的广告系统留给整个广告投放决策的时间也就是 10ms 左右,所以对于访问 DMP 获取用户数据,预期的响应时间都在 1ms 之内。
  • 高可用性:DMP 常常用在广告系统里面。DMP 系统出问题,往往就意味着整个的广告收入在不可用的时间就没了,所以对于可用性的追求可谓是没有上限的。Google 2018 年的广告收入是 1160 亿美元,折合到每一分钟的收入是 22 万美元。即使我们做到 99.99% 的可用性,也意味着每个月我们都会损失 100 万美元。
  • 高并发:还是以广告系统为例,如果每天我们需要响应 100 亿次的广告请求,那么我们每秒的并发请求数就在 100 亿 / (86400) ~= 12K 次左右,所以DMP 需要支持高并发。
  • 数据量:如果产品针对中国市场,那么需要有 10 亿个 Key,对应的假设每个用户有 500 个标签,标签有对应的分数。标签和分数都用一个 4 字节(Bytes)的整数来表示,那么一共需要 10 亿 x 500 x (4 + 4) Bytes = 4 TB 的数据。
  • 低成本:从广告系统的角度来考虑,广告系统的收入通常用 CPM(Cost Per Mille),也就是千次曝光来统计。如果千次曝光的利润是 0.10 美元,那么每天 100 亿次的曝光就是 100 万美元的利润。这个利润听起来非常高了。但是反过来算一下,DMP 每 1000 次的请求的成本不能超过 0.10 美元。最好只有 0.01 美元,甚至更低,才能尽可能多赚到一点广告利润。

为了能够生成这个 KV 数据库,我们需要有一个在客户端或者 Web 端的数据采集模块,不断采集用户的行为,向后端的服务器发送数据。服务器端接收到数据,就要把这份数据放到一个数据管道(Data Pipeline)里面。数据管道的下游,需要实际将数据落地到数据仓库(Data Warehouse),把所有的这些数据结构化地存储起来。后续,就可以通过程序去分析这部分日志,生成报表或者或者利用数据运行各种机器学习算法。

除了数据仓库之外,还会有一个实时数据处理模块(Realtime Data Processing),也放在数据管道的下游。它同样会读取数据管道里面的数据,去进行各种实时计算,然后把需要的结果写入到 DMP 的 KV 数据库里面去。

二、MongoDB 真的万能吗

MongoDB 的设计听起来特别厉害,不需要预先数据 Schema,访问速度很快,还能够无限水平扩展。作为 KV 数据库,可以把 MongoDB 当作 DMP 里面的 KV 数据库;除此之外,MongoDB 还能水平扩展、跑 MQL,可以把它当作数据仓库来用。至于数据管道,只要我们能够不断往 MongoDB 里面,插入新的数据就好了。从运维的角度来说,只需要维护一种数据库,技术栈也变得简单了。看起来,MongoDB 这个选择真是相当完美!

然而,所有的软件系统,都有它的适用场景,想通过一种解决方案适用三个差异非常大的应用场景,显然既不合理,又不现实。接下来,我们就来仔细看一下,这个“不合理”“不现实”在什么地方。

对于数据管道来说,我们需要的是高吞吐量,它的并发量虽然和 KV 数据库差不多,但是在响应时间上,要求就没有那么严格了,1-2 秒甚至再多几秒的延时都是可以接受的。而且,和 KV 数据库不太一样,数据管道的数据读写都是顺序读写,没有大量的随机读写的需求

数据仓库就更不一样了,数据仓库的数据读取量要比管道大得多。管道的数据读取就是当时写入的数据,一天有 10TB 日志数据,管道只会写入 10TB。下游的数据仓库存放数据和实时数据模块读取的数据,再加上个 2 倍的 10TB,也就是 20TB 也就够了。但是,数据仓库的数据分析任务要读取的数据量就大多了。一方面,我们可能要分析一周、一个月乃至一个季度的数据。这一次分析要读取的数据可不是 10TB,而是 100TB 乃至 1PB。我们一天在数据仓库上跑的分析任务也不是 1 个,而是成千上万个,所以数据的读取量是巨大的。另一方面,我们存储在数据仓库里面的数据,也不像数据管道一样,存放几个小时、最多一天的数据,而是往往要存上 3 个月甚至是 1 年的数据。所以,我们需要的是 1PB 乃至 5PB 这样的存储空间。

在 KV 数据库的场景下,需要支持高并发。那么 MongoDB 需要把更多的数据放在内存里面,但是这样存储成本就会特别高了。

在数据管道的场景下,需要大量的顺序读写,而 MongoDB 则是一个文档数据库系统,并没有为顺序写入和吞吐量做过优化,看起来也不太适用。

数据仓库的场景下,主要的数据读取时顺序读取,并且需要海量的存储。MongoDB 这样的文档式数据库也没有为海量的顺序读做过优化,仍然不是一个最佳的解决方案。而且文档数据库里总是会有很多冗余的字段的元数据,还会浪费更多的存储空间。

那我们该选择什么样的解决方案呢?其实并不难找。

对于 KV 数据库,最佳的选择方案自然是使用 SSD 硬盘,选择 AeroSpike 这样的 KV 数据库。高并发的随机访问并不适合 HDD 的机械硬盘,而 400TB 的数据,如果用内存的话,成本又会显得太高。

对于数据管道,最佳选择自然是 Kafka。因为我们追求的是吞吐率,采用了 Zero-Copy 和 DMA 机制的 Kafka 最大化了作为数据管道的吞吐率。而且,数据管道的读写都是顺序读写,所以也不需要对随机读写提供支持,用上 HDD 硬盘就好了。

对于数据仓库,存放的数据量更大了。2019年的应用场景下看,在硬件层面使用 HDD 硬盘成了一个必选项,否则,存储成本就会差上 10 倍。但是SSD和几年前比已经便宜了很多了,而且在PCI-E接口普及的情况下,顺序读写速度比起HDD也能拉开差距了,所以逐步我们也看到业界开始直接用SSD来部署Kafka也变得比较常见了。

这么大量的数据,在存储上我们需要定义清楚 Schema,使得每个字段都不需要额外存储元数据,能够通过 Avro/Thrift/ProtoBuffer 这样的二进制序列化的方存储下来,或者干脆直接使用 Hive 这样明确了字段定义的数据仓库产品。很明显,MongoDB 那样不限制 Schema 的数据结构,在这个情况下并不好用。

三、关系型数据库:不得不做的随机读写

DMP 的 KV 数据库主要的应用场景,是根据主键的随机查询。这个需求,实际的大型系统中,大家都会使用专门的分布式 KV 数据库来满足。

下面看一下Facebook 开源的 Cassandra 的数据存储和读写是怎么做的,这些设计是怎么解决高并发的随机读写问题的。

(一)Cassandra:顺序写和随机读

1、Cassandra 的数据模型

作为一个分布式的 KV 数据库,Cassandra 的键一般被称为 Row Key。其实就是一个 16 到 36 个字节的字符串。每一个 Row Key 对应的值其实是一个哈希表,里面可以用键值对,再存入很多需要的数据。

Cassandra 本身不像关系型数据库那样,有严格的 Schema,在数据库创建的一开始就定义好了有哪些列(Column)。但是,它设计了一个叫作列族(Column Family)的概念,我们需要把经常放在一起使用的字段,放在同一个列族里面。比如,DMP 里面的人口属性信息,我们可以把它当成是一个列族。用户的兴趣信息,可以是另外一个列族。这样,既保持了不需要严格的 Schema 这样的灵活性,也保留了可以把常常一起使用的数据存放在一起的空间局部性。

往 Cassandra 的里面读写数据,其实特别简单,就好像是在一个巨大的分布式的哈希表里面写数据。指定一个 Row Key,然后插入或者更新这个 Row Key 的数据就好了。

2、Cassandra 的写操作

Cassandra 解决随机写入数据的解决方案,简单来说,就叫作“不随机写,只顺序写”。对于 Cassandra 数据库的写操作,通常包含两个动作。第一个是往磁盘上写入一条提交日志(Commit Log)。另一个操作,则是直接在内存的数据结构上去更新数据。后面这个往内存的数据结构里面的数据更新,只有在提交日志写成功之后才会进行。每台机器上,都有一个可靠的硬盘可以让我们去写入提交日志。写入提交日志都是顺序写(Sequential Write),而不是随机写(Random Write),最大化了写入的吞吐量。

内存的空间比较有限,一旦内存里面的数据量或者条目超过一定的限额,Cassandra 就会把内存里面的数据结构 dump 到硬盘上。这个 Dump 的操作,也是顺序写而不是随机写,所以性能也不会是一个问题。除了 Dump 的数据结构文件,Cassandra 还会根据 row key 来生成一个索引文件,方便后续基于索引来进行快速查询。

随着硬盘上的 Dump 出来的文件越来越多,Cassandra 会在后台进行文件的对比合并。在很多别的 KV 数据库系统里面,也有类似这种的合并动作,比如 AeroSpike 或者 Google 的 BigTable。这些操作我们一般称之为 Compaction。合并动作同样是顺序读取多个文件,在内存里面合并完成,再 Dump 出来一个新的文件。整个操作过程中,在硬盘层面仍然是顺序读写。

3、Cassandra 的读操作

要从 Cassandra 读数据的时候,先从内存里面找,再从硬盘读,然后把两部分的数据合并成最终结果。这些硬盘上的文件,在内存里面会有对应的 Cache,只有在 Cache 里面找不到,才会去请求硬盘里面的数据。

如果不得不访问硬盘,按照时间从新的往旧的里面找,因为硬盘里面可能 Dump 了很多个不同时间点的内存数据的快照。

这也就带来另外一个问题——可能要查询很多个 Dump 文件,才能找到想要的数据。所以,Cassandra 在这一点上又做了一个优化。那就是,它会为每一个 Dump 的文件里面所有 Row Key 生成一个 BloomFilter,然后把这个 BloomFilter 放在内存里面。这样,如果想要查询的 Row Key 在数据文件里面不存在,那么 99% 以上的情况下,它会被 BloomFilter 过滤掉,而不需要访问硬盘。这样,只有当数据在内存里面没有,并且在硬盘的某个特定文件上的时候,才会触发一次对于硬盘的读请求。

(二)SSD:DBA 们的大救星

Cassandra 是 Facebook 在 2008 年开源的。那个时候,SSD 硬盘还没有那么普及。可以看到,它的读写设计充分考虑了硬件本身的特性。在写入数据进行持久化上,Cassandra 没有任何的随机写请求,无论是 Commit Log 还是 Dump,全部都是顺序写。

在数据读的请求上,最新写入的数据都会更新到内存。如果要读取这些数据,会优先从内存读到。这相当于是一个使用了 LRU 的缓存机制。只有在万般无奈的情况下,才会有对于硬盘的随机读请求。即使在这样的情况下,Cassandra 也在文件之前加了一层 BloomFilter,把本来因为 Dump 文件带来的需要多次读硬盘的问题,简化成多次内存读和一次硬盘读。

这些设计,使得 Cassandra 即使是在 HDD 硬盘上,也能有不错的访问性能。而对于数据的读,就有一些挑战了。如果数据读请求有很强的局部性,那内存就能搞定 DMP 需要的访问量。但是DMP 的数据访问分布,其实是缺少局部性的。

如果是 Facebook 那样的全球社交网络,那可能还有一定的时间局部性。毕竟不同国家的人的时区不一样。我们可以说,在印度人民的白天,把印度人民的数据加载到内存里面,美国人民的数据就放在硬盘上。到了印度人民的晚上,再把美国人民的数据换到内存里面来。如果主要业务是在国内,那这个时间局部性就没有了。大家的上网高峰时段,都是在早上上班路上、中午休息的时候以及晚上下班之后的时间,没有什么区分度。

因为缺少时间局部性,内存的缓存能够起到的作用就很小了,大部分请求最终还是要落到 HDD 硬盘的随机读上。但是,HDD 硬盘的随机读的性能太差了。如果全都放内存又太贵了。

幸运的是,从 2010 年开始,SSD 硬盘的大规模商用帮我们解决了这个问题。它的随机读的访问能力在 HDD 硬盘的百倍以上。同样的价格的 SSD 硬盘,容量则是内存的几十倍,也能够满足我们的需求,用较低的成本存下整个互联网用户信息。

不夸张地说,过去十年的“大数据”“高并发”“千人千面”,有一半的功劳应该归在让 SSD 容量不断上升、价格不断下降的硬盘产业上。

回到 Cassandra 的读写设计,你会发现,Cassandra 的写入机制完美匹配SSD 硬盘的优缺点。

在数据写入层面,Cassandra 的数据写入都是 Commit Log 的顺序写入,也就是不断地在硬盘上往后追加内容,而不是去修改现有的文件内容。一旦内存里面的数据超过一定的阈值,Cassandra 又会完整地 Dump 一个新文件到文件系统上。这同样是一个追加写入。

数据的对比和紧凑化(Compaction),同样是读取现有的多个文件,然后写一个新的文件出来。写入操作只追加不修改的特性,正好天然地符合 SSD 硬盘只能按块进行擦除写入的操作。在这样的写入模式下,Cassandra 用到的 SSD 硬盘,不需要频繁地进行后台的 Compaction,能够最大化 SSD 硬盘的使用寿命。因此,Cassandra 在 SSD 硬盘普及之后,获得了进一步快速发展。

【推荐阅读】Cassandra - A Decentralized Structured Storage System。读完这篇论文,一方面你会对分布式 KV 数据库的设计原则有所了解,了解怎么去做好数据分片、故障转移、数据复制这些机制;另一方面,你可以看到基于内存和硬盘的不同存储设备的特性,Cassandra 是怎么有针对性地设计数据读写和持久化的方式的。

课程链接:深入浅出计算机组成原理_组成原理_计算机基础-极客时间 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/340497.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Mysql 增删改查(一) —— 查询(条件查询where、分页limits、排序order by、分组 group by)

查询 select 可以认为是四个基本操作中使用最为频繁的操作,然而数据量比较大的时候,我们不可能查询所有内容,我们一般会搭配其他语句进行查询: 假如要查询某一个字段的内容,可以使用 where假如要查询前几条记录&#…

线上服务质量的问题该如何去处理?你有什么思路?

线上服务质量的问题该如何去处理?你有什么思路? 目录:导读 发现线上故障 处理线上故障 修复线上故障 运营线上质量 就是前几天有个同学问了我一个问题:目前业内高可用部署主要采用方案? 看到这个问题&#xff0c…

5G网络架构与组网部署

文章目录5G网络架构与组网部署一、5G网络架构的演进趋势5G移动通信系统4G移动通信系统二、核心网架构的演进三、无线接入网的演进趋势5G网络架构与组网部署 一、5G网络架构的演进趋势 5G移动通信系统 5G移动通信系统包括5GC(5G Corn Network,5G核心网)和NG-RAN(Next Generat…

Zookeeper下载安装与集群搭建

Zookeeper下载安装与集群搭建1.下载安装1.1 下载安装1.2 配置启动2.集群搭建2.1 搭建要求2.2 准备工作2.3 配置集群2.4 启动集群2.5 模拟集群异常1.下载安装 1.1 下载安装 1、环境准备 ZooKeeper服务器是用Java创建的,它运行在JVM之上。需要安装JDK 7或更高版本。…

跟我一起写Makefile--个人总结

此篇笔记是根据陈皓大佬《跟我一起写Makefile》学习所得 文章目录换行符clean变量make的自动推导另类风格的Makefile清空目标文件的规则cleanMakefile总述显示规则隐晦规则变量的定义注释引用其它的Makefile环境变量MAKEFILESmake的工作方式书写规则规则举例规则的语法在规则中…

Flutter Windows端打包并生成可安装文件流程

Windows打包 1.首先安装visual Studio 下载地址:https://visualstudio.microsoft.com/zh-hans/ 下载成功后按照下图勾选桌面应用和移动应用下的使用C的桌面开发,勾选右侧安装详细信息中的windows 11/10 sdk 中的任意一个完成安装即可 2.打包Windows …

IC封装常见形式

参考:https://blog.csdn.net/dhs888888/article/details/127673300?utm_mediumdistribute.pc_relevant.none-task-blog-2defaultbaidujs_baidulandingword~default-0-127673300-blog-115610343.pc_relevant_multi_platform_whitelistv4&spm1001.2101.3001.4242…

truffle 创建测试合约并部署到测试网络

1、npm 安装truffle npm install -g truffle2、创建truffle项目 mkdir imooc-on-blockchain-truffle && cd imooc-on-blockchain-truffle3、初始化truffle目录,会生成如下几个目录 contracts 存放.sol合约文件migrations 部署脚本目录test 测试文件目录t…

20230210组会论文总结

目录 【Ultra-High-Definition Low-Light Image Enhancement: A Benchmark and Transformer-Based Method】 【ShuffleMixer: An Efficient ConvNet for Image Super-Resolution】 【A Close Look at Spatial Modeling: From Attention to Convolution 】 【DEA-Net: Single i…

自动机,即有限状态机

文章目录一、问题来源二、题目描述三、题解中的自动机四、自动机学习五、有限状态机的使用场景一、问题来源 今天做力克题目的时候看到了字符串转换整数的一道算法题,其中又看到了题解中有自动机的概念,所以在这里对自动机做个笔记。题目链接 二、题目描…

详解Python正则表达式中group与groups的用法

在Python中,正则表达式的group和groups方法是非常有用的函数,用于处理匹配结果的分组信息。 group方法是re.MatchObject类中的一个函数,用于返回匹配对象的整个匹配结果或特定的分组匹配结果。而groups方法同样是re.MatchObject类中的函数&am…

MySQL主从同步-(一)搭建主机服务器

准备工作:搭建mysql 数据库 主从复同步系统 centos 7.5 运行环境 docker mysql版本 8.0.3 准备主机服务器第一步:停止虚拟机中其他 docker ,关闭防火墙,关闭系统的mysql(防止端口冲突)docker stop $(docker…

C++11实现计算机网络中的TCP/IP连接(Windows端)

目录引言1、TCP2、IP2.1 IP路由器3、TCP/IP4、TCP/IP协议C11实现参考文献引言 TCP/IP 指传输控制协议/网际协议(Transmission Control Protocol / Internet Protocol)。[1] 在TCP/IP协议簇中主要包含以下内容: TCP (传输控制协议) - 应用程序…

Bing引擎引入ChatGPT申请候补名单方式

Bing引入ChatGPT申请候补名单方式ChatGPT一、ChatGPT简介二、OpenAI和Google的"军备军赛"三、ChatGPT版本⭐Bing引擎引入ChatGPT申请候补名单方式1.下载chrome拓展程序2.配置拓展程序3.Bing 申请候补名单3.1旧版本Bing3.2新版本Bing4.等待获取结尾ChatGPT 一、ChatG…

Linux ALSA 之十:ALSA ASOC Machine Driver

ALSA ASOC Machine Driver一、Machine 简介二、ASoC Machine Driver2.1 Machine Driver 的 Platform Driver & Platform Device 驱动模型2.2 在 Probe() 中注册声卡三、snd_soc_register_card 函数3.1 bind DAIs3.2 New a sound card3.3 Create card new widgets3.4 Probe …

JointBERT代码复现详解【上】

BERT for Joint Intent Classification and Slot Filling代码复现【上】 源码链接:JointBERT源码复现(含注释) 一、准备工作 源码架构 data:存放两个基准数据集;model:JointBert模型的实现&#xff1b…

修改本地host文件加入可用ip使谷歌浏览器翻译插件重新生效

修改本地host文件加入可用ip使谷歌浏览器翻译插件重新生效 第一步:找到host文件: 可以使用这个工具进行对Hosts文件进行一个查找 鼠标放到对应路径上面 点击鼠标右键,选择打开路径就到对应 路径了 也可以复制到这个路径下面去找hosts文件 …

【Node.js实战】一文带你开发博客项目之Koa2重构(实现session、开发路由、联调、日志)

个人简介 👀个人主页: 前端杂货铺 🙋‍♂️学习方向: 主攻前端方向,也会涉及到服务端 📃个人状态: 在校大学生一枚,已拿多个前端 offer(秋招) 🚀未…

Redis集群搭建(主从、哨兵、分片)

1.单机安装Redis 首先需要安装Redis所需要的依赖: yum install -y gcc tcl然后将课前资料提供的Redis安装包上传到虚拟机的任意目录: 例如,我放到了/tmp目录: 解压缩: tar -xzf redis-6.2.4.tar.gz解压后&#xff1…

C# Lambda表达式含义及各种写法

Lambda表达式在各个语言中的表达方式都不太相同,本文重点介绍C#的Lambda表达式。 首先,Lambda表达式就是一个匿名的方法/函数。 以下面的一个完整版作为例子,前面是参数,后面是返回值: 由于 Lambda表达式和委托常常一起…