传统的大数据技术起源于 Google 三架马车 GFS、MapReduce、Bigtable,以及其衍生的开源分布式文件系统 HDFS,分布式计算引擎 MapReduce,以及分布式数据库 HBase。最初的大数据技术与需求往往集中在超大规模数据存储、数据处理、在线查询等。在这个阶段,很多公司会选择自建机房部署 Hadoop 的方式,大数据技术与需求集中在离线计算与大规模存储上,常见的体现方式有 T+1 报表,大规模数据在线查询等。
随着互联网技术的日渐发展、数据规模的扩大与复杂的需求场景的产生,传统的大数据架构无法承载。大数据架构在近些年的演进主要体现下以下几方面:
本篇文章将基于云原生大数据架构的场景,详细讨论实时计算中的维表和结果表的架构选型。
1 实时计算场景
大数据的高速发展已经超过 10 年,大数据也正在从计算规模化向更加实时化的趋势演进。实时计算场景主要有以下几种最常见的场景:
2 Flink SQL 实时计算
实时计算需要后台有一套极其强大的大数据计算能力,Apache Flink 作为一款开源大数据实时计算技术应运而生。由于传统的 Hadoop、Spark 等计算引擎,本质上是批计算引擎,通过对有限的数据集进行数据处理,其处理时效性是不能保证的。而 Apache Flink ,从设计之初就以定位为流式计算引擎,它可以实时订阅实时产生的流式数据,对数据进行实时分析处理并产生结果,让数据在第一时间发挥价值。
Flink 选择了 SQL 这种声明式语言作为顶层 API,方便用户使用,也符合云原生大数据架构的趋势:
上图是 Flink SQL 的一些基本操作。可以看到 SQL 的语法和标准 SQL 非常类似,示例中包括了基本的 SELECT、FILTER 操作,可以使用内置函数(如日期的格式化),也可以在注册函数后使用自定义函数。
Flink SQL 将实时计算拆分成源表,结果表和维表三种,将这三种表的 DDL 语句(比如 CREATE TABLE)注册各类输入、输出的数据源,通过 SQL 的 DML(比如 INSERT INTO)表示实时计算任务的拓扑关系,以达到通过 SQL 完成实时计算任务开发的效果。
下图是一个完整的实时计算示例,示例中的 Flink SQL 任务,这个任务的目标是计算每分钟不同商品分类的 GMV (Gross Merchandise Volume,即商品交易总额)。在这个任务中,Flink 实时消费用户订单数据的 Kafka 源表,通过 Redis 维表将商品 id 关联起来获取到商品分类,按照 1 分钟间隔的滚动窗口按商品分类将总计的交易金额计算出来,将最后的结果写入 RDS(Relational Database Service,如 MySQL) 结果表中。
# 源表 - 用户订单数据,代表某个用户(user_id)在 timestamp 时按 price 的价格购买了商品(item_id)
CREATE TEMPORARY TABLE user_action_source (
`timestamp` BIGINT,
`user_id` BIGINT,
`item_id` BIGINT,
`price` DOUBLE,SQs
) WITH (
'connector' = 'kafka',
'topic' = '',
'properties.bootstrap.servers' = 'your_kafka_server:9092',
'properties.group.id' = ''
'format' = 'json',
'scan.startup.mode' = 'latest-offset'
);
# 维表 - 物品详情
CREATE TEMPORARY TABLE item_detail_dim (
id STRING,
catagory STRING,
PRIMARY KEY (id) NOT ENFORCED
) WITH (
'connector' = 'redis',
'host' = '',
'port' = '',
'password' = '',
'dbNum' = ''
);
# 结果表 - 按时间(分钟)和分类的 GMV 输出
CREATE TEMPORARY TABLE gmv_output (
time_minute STRING,
catagory STRING,
gmv DOUBLE,
PRIMARY KEY (time_minute, catagory)
) WITH (
type='rds',
url='',
tableName='',
userName='',
password=''
);
# 处理过程
INSERT INTO gmv_output
SELECT
TUMBLE_START(s.timestamp, INTERVAL '1' MINUTES) as time_minute,
d.catagory,
SUM(d.price) as gmv
FROM
user_action_source s
JOIN item_detail_dim FOR SYSTEM_TIME AS OF PROCTIME() as d
ON s.item_id = d.id
GROUP BY TUMBLE(s.timestamp, INTERVAL '1' MINUTES), d.catagory;
这是一个很常见的实时计算的处理链路。后续章节中,我们将针对实时计算的维表和结果表的关键能力进行展开分析,并分别进行架构选型的讨论。
1 关键需求
在数据仓库的建设中,一般都会围绕着星型模型和雪花模型来设计表关系或者结构。实时计算也不例外,一种常见的需求就是为数据流补齐字段。因为数据采集端采集到的数据往往比较有限,在做数据分析之前,就要先将所需的维度信息补全。比如采集到的交易日志中只记录了商品 id,但是在做业务时需要根据店铺维度或者行业纬度进行聚合,这就需要先将交易日志与商品维表进行关联,补全所需的维度信息。这里所说的维表与数据仓库中的概念类似,是维度属性的集合,比如商品维度、用户度、地点维度等等。
作为保存用户维度信息的数据存储,需要应对实时计算场景下的海量低延时访问。根据这样的定位,我们总结下对结构化大数据存储的几个关键需求:
1. 高吞吐与低延时的读取能力
首当其冲,在不考虑开源引擎 Flink 自身维表的优化外,维表必须能承担实时计算场景下的海量(上万 QPS)的数据访问,也能在极低(毫秒级别)的延时下返回查询数据。
2. 与计算引擎的高整合能力
在维表自身的能力之外,出于性能、稳定性和成本的考虑,计算引擎自身往往也会有些流量卸载的能力,在一些情况下无需每次请求都需要去访问下游维表。例如,Flink 在维表场景下支持 Async IO 和缓存策略等优化特性。一个比较好的维表需要和开源计算引擎有着较高程度的对接,一方面可以提升计算层的性能,一方面也可以有效的卸载部分流量,保障维表不被过多访问击穿,并降低维表的计算成本。
3. 轻存储下的计算能力的弹性
维表通常是一张共享表,存储维度属性等元数据信息,访问规模往往较大,而存储规模往往不会特别大。对维表的访问规模极大地依赖实时数据流的数据量。比如,如果实时流的数据规模扩大了数十倍,此时对维表的访问次数会大大提升;又比如,如果新增了多个实时计算任务访问该维表,该维表的查询压力会激增。在这些场景下,存储规模往往不会显著增加。
所以,计算最好是按需的,是弹性的。无论是新增或者下线实时计算任务,或者增加访问流量,都不会影响访问性能。同时,计算和存储是应该分离的,不会单纯因为访问计算量的激增就增加存储成本。
2 架构选型
MySQL
大数据和实时计算技术起步之初,互联网早期大量流行 LAMP (Linux + Apache + MySQL + PHP)架构快速开发站点。因此,由于业务历史数据已经存在 MySQL 中,在最初的实时计算维表选型中大量使用 MySQL 作为维表。
随着大数据架构的更新,MySQL 云上架构也在不断改进,但在维表的应用场景下仍然存在以下问题:
以上这些限制使 MySQL 在大数据维表场景下存在性能瓶颈,成本也比较高。但总体来说,MySQL 是非常优秀的数据库产品,在数据规模不怎么大的场景下,MySQL 绝对是个不错的选择。
Redis
在云上应用架构中,由于 MySQL 难以承载不断增加的业务负载,往往会使用 Redis 作为 MySQL 的查询结果集缓存,帮助 MySQL 来抵御大部分的查询流量。
在这种架构中,MySQL 作为主存储服务器,Redis 作为辅助存储,MySQL 到 Redis 的同步可以通过 binlog 实时同步或者 MySQL UDF + 触发器的方式实现。在这种架构中,Redis 可以用来缓存提高查询性能,同时降低 MySQL 被击穿的风险。
由于在 Redis 中缓存了一份弱一致性的用户数据,Redis 也常常用来作为实时计算的维表。相比于 MySQL 作为维表,Redis 有着独特的优势:
Redis 有其突出的优点,但也有一个不可忽视的缺陷:虽然 Redis 有着不错的扩展方案,但由于高速缓存的数据存在内存中,成本较高,如果遇到业务数据的维度属性较大(比如用户维度、商品维度)时,使用 Redis 作为维表存储时成本极高。
Tablestore
Tablestore是阿里云自研的结构化大数据存储产品,具体产品介绍可以参考官网以及权威指南。在大数据维表的场景下,Tablestore 有着独特的优势:
方案对比
上面是前文提到的几个维表方案在各个维度的对比。接下来,将举几个具体的场景细致对比下成本:
1.高存储高计算:维表需要存 100 亿条订单维度的数据,总计存储量需要 1T,尽管业务在 Flink 任务端配置了缓存策略,但仍然有较高的 KV 查询下沉到维表,到维表的 QPS 峰值 10 万,均值 2.5 万。不同维表所需的配置要求和购买成本如下:
2.低存储低计算:维表需要存 100 万条地域维度的数据,总计存储量需要 10M,业务端在 Flink 任务中的维表配置了 LRU 缓存策略抵御了绝大部分的流量,到维表的 QPS 峰值 1000 均值 250。不同维表所需的配置要求和购买成本如下:
3.高存储低计算:维表需要存 100 亿条订单维度的数据,总计存储量需要 1T,业务端在 Flink 任务中的维表配置了 LRU 缓存策略抵御了绝大部分的流量,到维表的 QPS 峰值 1000 均值 250。不同维表所需的配置要求和购买成本如下:
4.低存储高计算:Redis 作为内存数据库,具有超高频的数据 KV 查询能力,仅 4 核 8G 内存的 Redis集群,即可支持 16 万 QPS的并发访问,成本预计 1600 元 / 月,在低存储高计算场景有着鲜明的成本优势。
从上面的成本对比报告中可见:
1)MySQL 由于缺乏存储和计算的弹性,以及关系型数据库固有的缺点,在不同程度的存储和计算规模下成本均较高。
2)Redis 作为内存数据库,在低存储(约 128G 以下)高计算场景有着鲜明的成本优势,但由于内存存储成本很高、缺乏弹性,随着数据规模的提升,成本呈指数增长。
3)Tablestore 基于云原生架构可以按量对存储和计算进行弹性,在数据存储和访问规模不大时成本较低。
4)Tablestore 作为 NoSQL 数据库存储成本很低,在高存储(128G 以上)场景下有着鲜明的成本优势。
1 需求分析
结果表作为实时计算完成后数据导入的存储系统,主要可分为关系数据库、搜索引擎、结构化大数据离线存储、结构化大数据在线存储几种分类,具体差异通过以下表格进行了归纳。
对于这几种数据产品,在各自场景下各有优势,起源的先后也各有不同。为了方便探究,我们将问题域缩小,仅仅考虑实时计算的场景下,一个更好的结果表存储需要承担什么样的角色。
上文提到了实时计算的主要几个场景中,实时数仓,实时推荐,实时监控三个场景需要考虑结果表的选型。我们一一分析。
2 关键能力
通过以上的需求分析,我们可以总结出几项实时大数据结果表的关键能力:
1.大规模数据存储
结果表存储的定位是集中式的大规模存储,作为在线数据库的汇总,或者是实时计算(或者是离线)的输入和输出,必须要能支撑 PB 级规模数据存储。
2.丰富的数据查询与聚合分析能力
结果表需要拥有丰富的数据查询与聚合分析能力,需要为支撑高效在线查询做优化。常见的查询优化包括高速缓存、高并发低延迟的随机查询、复杂的任意字段条件组合查询以及数据检索。这些查询优化的技术手段就是缓存和索引,其中索引的支持是多元化的,面向不同的查询场景提供不同类型的索引。例如面向固定组合查询的基于 B+tree 的二级索引,面向地理位置查询的基于 R-tree 或 BKD-tree 的空间索引或者是面向多条件组合查询和全文检索的倒排索引。
3.高吞吐写入能力
实时计算的数据表需要能承受大数据计算引擎的海量结果数据集导出。所以必须能支撑高吞吐的数据写入,通常会采用一个为写入而优化的存储引擎。
4.数据派生能力
一个完整的数据系统架构下,需要有多个存储组件并存。并且根据对查询和分析能力的不同要求,需要在数据派生体系下对存储进行动态扩展。所以对于大数据存储来说,也需要有能扩展存储的派生能力,来扩展数据处理能力。而判断一个存储组件是否具备更好的数据派生能力,就看是否具备成熟的 CDC 技术。
5.云原生架构:存储与计算成本分离
在云原生大数据架构中,每一层架构都在往服务化的趋势演进,存储服务化、计算服务化、元数据管理服务化等。每个组件都被要求拆分成不同的单元,作为结果表也不例外,需要具备独立扩展的能力,更开放、更灵活、更弹性。
单就从结果表来说,只有符合云原生架构的组件,即基于存储计算分离架构实现的产品,才能做到存储和计算成本的分离,以及独立扩展。存储和计算分离的优势,在大数据系统下会更加明显。举一个简单的例子,结构化大数据存储的存储量会随着数据的积累越来越大,但是数据写入量是相对平稳的。所以存储需要不断的扩大,但是为了支撑数据写入或临时的数据分析而所需的计算资源,则相对来说比较固定,是按需的。
3 架构选型
MySQL
和维表一样,大数据和实时计算技术起步之初,MySQL 是一个万能存储,几乎所有需求都可以通过 MySQL 来完成,因此应用规模非常广,结果表也不例外。随着数据规模的不断扩展和需求场景的日渐复杂,MySQL 有点难以承载,就结果表的场景下主要存在以下问题:
以上这些限制使 MySQL 在大数据结果表场景下存在性能瓶颈,成本也比较高,但作为关系型数据库,不是特别适合作为大数据的结果表使用。
HBase
由于关系型数据库的天然瓶颈,基于 BigTable 概念的分布式 NoSQL 结构化数据库应运而生。目前开源界比较知名的结构化大数据存储是 Cassandra 和 HBase,Cassandra 是 WideColumn 模型 NoSQL 类别下排名 Top-1 的产品,在国外应用比较广泛。这篇文章中,我们重点提下在国内应用更多的 HBase。 HBase 是基于 HDFS 的存储计算分离架构的 WideColumn 模型数据库,拥有非常好的扩展性,能支撑大规模数据存储,它的优点为:
HBase有其突出的优点,但也有几大不可忽视的缺陷:
国内的高级玩家大多会基于 HBase 做二次开发,基本都是在做各种方案来弥补 HBase 查询能力弱的问题,根据自身业务查询特色研发自己的索引方案,例如自研二级索引方案、对接 Solr 做全文索引或者是针对区分度小的数据集的 bitmap 索引方案等等。总的来说,HBase 是一个优秀的开源产品,有很多优秀的设计思路值得借鉴。
HBase + Elasticsearch
为了解决 HBase 查询能力弱的问题,国内很多公司通过 Elasticsearch 来加速数据检索,按照 HBase + Elasticsearch 的方案实现他们的架构。其中,HBase 用于做大数据存储和历史冷数据查询,Elasticsearch 用于数据检索,其中,由于 HBase 不具备 CDC 技术,所以需要业务方应用层双写 HBase 和 Elasticsearch,或者启动数据同步任务将 HBase 同步至 Elasticsearch。
这个方案能通过 Elasticsearch 极大地补足 HBase 查询能力弱的问题,但由于 HBase 和 Elasticsearch 本身的一些能力不足,会存在以下几个问题:
Tablestore
Tablestore 是阿里云自研的结构化大数据存储产品,具体产品介绍可以参考官网以及权威指南。Tablestore 的设计理念很大程度上顾及了数据系统内对结构化大数据存储的需求,并且基于派生数据体系这个设计理念专门设计和实现了一些特色的功能。简单概括下 Tablestore 的技术理念:
方案对比
举一个具体的场景,结果表需要存千亿级别的电商订单交易数据,总计存储量需要 1T,用户需要对于这类数据进行查询与灵活的分析。日常订单查询与数据检索频率为 1000 次/秒,数据分析约每分钟查询 10 次左右。
以下是不同架构达到要求所需的配置,以及在阿里云上的购买成本:
本篇文章谈了云原生大数据架构下的实时计算维表和结果表场景下的架构设计与选型。其中,阿里云 Tablestore 在这些场景下有一些特色功能,希望能通过本篇文章对我们有一个更深刻的了解。后续,我们会推出从零构建 Flink on Tablestore 系列文章,并针对维表和结果表场景推出最佳实践文章。
作者 | 志羽
原文链接
本文为阿里云原创内容,未经允许不得转载。