CarbonData是一个支持索引和物化视图的ACID数据湖,在5月初正式发布了2.0 RC2,这个版本在索引、物化视图、数据湖能力、ACID等方面均有增强。
我们可以先快速浏览一下这个版本。
**索引和物化视图能力**:
* 详单查询:二级索引、时序索引、空间索引、Segment级别MINMAX索引,实现PB级别详单查询秒级响应。
* 复杂查询:物化视图、分桶索引,实现复杂查询秒级响应
* 数据湖索引管理:分布式索引缓存——IndexServer、并支持索引内存预加载
**数据湖能力**:
* 历史数据无缝迁移:支持对Parquet、ORC、CarbonData数据进行统一元数据管理,PB级别Parquet数据秒级导入CarbonData
* 历史数据加速:为Parquet、ORC、CarbonData构建统一物化视图
* 异构计算融合:对接Flink、Hive、Presto、PyTorch、TensorFlow
**ACID**:
* Insert、Update和Delete性能增强,支持Merge语法
下面我们首先介绍CarbonData的愿景,其次通过示例介绍CarbonData的索引、物化视图、数据湖能力和ACID能力。
## 前言
如下表所示,业界在EB级别存储的数据库可选方案主要包含Nosql数据、Hadoop生态数据仓库等,但都有其明显的不足。
可选方案 | 优势 | 不足
-|-|-
HBase、ES、Kudu、MPP等 | 快 | 贵
Spark、Hive等 | 成本低 | 慢
首先,以HBase服务、MongoDB服务或者ElasticSearch服务为代表的Nosql数据库,虽然也可以支持快速的复杂SQL查询,但是这些服务均不支持存储与计算分离,为了满足PB/EB级别存储的需求,往往我们需要启动更多的计算节点,消耗更多的CPU和存储成本,同时还要付出更多的运维成本,计算和存储的紧密耦合也意味着更低的计算和存储利用率。例如HBase服务,单台RegionServer可维护不超过10TB的数据,面对10PB的数据存储时,需要1000台计算节点部署RegionServer,其所面对的金钱成本和运维成本都十分高昂。
其次,以Spark on Parquet、Hive on ORC为代表的Hadoop生态数据仓库解决方案,支持将数据放在对象存储服务上,但是没有对数据构建高效的索引,使得明细数据查询或者复杂查询都很慢。假设如下几种场景:1)查询过去一年某用户的行为轨迹,当没有针对用户构建索引时,只能暴力扫描过去一整年的数据,测试中需要7天才能完成,2)Join类的复杂查询同样如此,无索引情况下,只能对数据暴力扫描,极大限制了查询速度。
由上可见,Nosql数据库虽然具有较好的数据索引机制,但是“太贵”,传统的Hadoop生态数据仓库将数据放在对象存储上,但是“太慢”,这两者各自的局限性,使得我们进行EB级别数据仓库选型时,面临着这一个鱼与熊掌不可兼得的选择题。
> 为了能够像关系型数据库一样,可以高效执行复杂SQL查询,又可以像NoSQL数据库一样,构建高效索引,最后,又可以和Spark/Hive一样,享受高度可扩展性的数据并行处理,又能利用近乎无限的低成本的对象存储资源,满足这种“又方便又快又便宜”的任性就是CarbonData的使命。
>
接下来的内容,我们将重点介绍如何体验CarbonData 2.0 RC2中的索引、物化视图、ACID能力。
## 一、快速安装CarbonData
* 准备1台Linux弹性云服务器
* 下载快速安装脚本
```shell
curl -k -O http://carbondata-publish.obs.myhuaweicloud.com/quick_start_carbondata.sh
```
* 启动sparksql和carbondata
```shell
source quick_start_carbondata.sh
```
## 二、CarbonData索引和物化视图
CarbonData 2.0 提供了丰富的索引能力,笔者总结了CarbonData提供的不同索引能力和适用场景。如下表所示。
索引类型 | 适用场景 | 效果
-|-|-
排序索引 | 带有排序键过滤的查询 | 秒级主键精确查询
二级索引 | 带有二级索引键过滤的查询 | 秒级非主键精确查询
物化视图 | Join、GroupBy、OrderBy等复杂查询 | 复杂查询秒级响应
时序索引 | 时序聚合 | 秒级时序聚合
空间索引 | 空间检索 | 秒级空间精确过滤
BloomFilter索引 | 带有高基数列过滤的查询 | 高基数列快速过滤
Lucene索引 | 多维检索 | 秒级多维索引
下面我们给出在CarbonData中构建索引的语法示例。
* 构建排序键索引,语法举例如下:
```sql
CREATE TABLE person(id STRING, age INT, country STRING, timestamp timestamp, address STRING, skill STRING)
STORED AS carbondata
TBLPROPERTIES('sort_scope'='GLOBAL_SORT','sort_columns'='id, age');
```
* 构建二级索引,语法举例如下:
```sql
CREATE index person_si_country_age on table person(country, age) AS 'carbondata';
```
* 构建物化视图,基于复杂查询构建物化视图的语法举例如下:
```sql
CREATE MATERIALIZED VIEW person_countid_gb_country
AS SELECT country,count(id) FROM person GROUP BY country;
```
* 时序索引,基于时间键的复杂查询构建时序索引的语法举例如下:
```sql
CREATE MATERIALIZED VIEW person_countid_gb_timeseries AS
SELECT timeseries(timestamp, 'minute'),count(id)
FROM person
GROUP BY timeseries(timestamp, 'minute');
```
* BloomFilter索引,语法举例如下:
```sql
CREATE INDEX person_bf_address
ON TABLE person (address)
AS 'bloomfilter'
PROPERTIES ('BLOOM_SIZE'='640000', 'BLOOM_FPP'='0.00001');
```
* Lucene索引,语法举例如下:
```sql
CREATE INDEX person_luc_skill
ON TABLE person (skill)
AS 'lucene';
```
* 加载数据
```sql
INSERT INTO person VALUES
('c001', '23', 'china', '2016-02-23 09:01:30','china sz','computer design'),
('c003', '23', 'japan', '2016-02-23 08:01:30','japan to','sport speech'),
('c002', '23', 'india', '2016-02-23 07:01:30','india mm','draw write');
```
* 查询数据
利用排序索引查询
```sql
SELECT * FROM person WHERE id = 'c001';
```
利用二级索引查询
```sql
SELECT * FROM person WHERE country = 'china' and age = 23;
```
利用物化视图进行查询
```sql
SELECT country,count(id) FROM person GROUP BY country;
```
利用时序索引进行查询
```sql
SELECT timeseries(timestamp, 'minute'),count(id)
FROM person
GROUP BY timeseries(timestamp, 'minute');
```
利用BloomFilter索引进行查询
```sql
SELECT * FROM person WHERE address = 'china sz';
```
利用Lucene索引进行查询
```sql
SELECT * FROM person WHERE TEXT_MATCH('skill:*computer*')
```
## 三、数据湖
CarbonData在体现性能优势的下一步,就需要回答如何将历史数据搬迁到CarbonData的问题,CarbonData 2.0交出了如下的答卷:
> 1)历史Parquet、ORC数据如何导入CarbonData;
>
> **支持通过"add segment"的方式,实现CarbonData对Parquet、ORC数据进行统一纳管。实现PB级别历史数据秒级迁移。**
>
> 2)如何对历史Parquet、ORC数据构建索引;
>
> **支持对CarbonData、Parquet、ORC构建统一物化视图。实现PB级别数据复杂查询秒级响应。**
下面主要通过示例演示以上两个功能:1.Parquet文件如何无缝导入CarbonData; 2.如何对Parquet数据构建物化视图。
* Parquet文件导入CarbonData
首先构建一张Parquet表,并写入数据。
```sql
CREATE TABLE parquet_table(id STRING, age INT, country STRING, timestamp timestamp, address STRING, skill STRING)
STORED AS parquet;
INSERT INTO parquet_table VALUES
('c004', '23', 'kor', '2016-02-22 09:01:30','kor ab','design'),
('c005', '23', 'russia', '2016-02-21 08:01:30','russia mo','game'),
('c006', '23', 'india', '2016-02-23 07:01:30','india sc','travel');
```
将Parquet文件元数据导入CarbonData,语法示例如下。这里path需要替换为真实parquet表路径,路径信息可以通过describe formatted parquet_table查询得到
```sql
ALTER TABLE person ADD SEGMENT options('path'='{$parquet_table_location}','format'='parquet');
```
查询CarbonData表。最终可以发现CarbonData表中已经可以查询到Parquet表的数据。
```sql
SELECT * FROM person;
```
* 为Parquet表构建物化视图、时序索引
```sql
CREATE MATERIALIZED VIEW parquet_table_countid_gb_country
AS SELECT country,count(id) FROM parquet_table GROUP BY country;
```
利用物化视图进行查询
```sql
SELECT country,count(id) FROM parquet_table GROUP BY country;
```
## 三、ACID
CarbonData 2.0中深度优化了UPDATE、DELETE性能,并支持了Merge语法。
数据更新,语法示例如下:
```sql
UPDATE Person SET age = '24' WHERE id = c001;
```
数据删除,语法示例如下:
```sql
DELETE FROM Person WHERE id = c002;
```
数据Merge,支持批量查询、更新、删除。语法可参考:
```sql
https://github.com/apache/carbondata/blob/master/examples/spark/src/main/scala/org/apache/carbondata/examples/CDCExample.scala
```
## 结语
CarbonData提供了一种新的融合数据存储方案,以一份数据同时支持多种应用场景,EB级别数据规模,查询性能秒级响应。可以看出CarbonData目前的架构和想法都十分先进,在体验了CarbonData 2.0 RC2的强大功能后,笔者也更加期待5月中CarbonData 2.0的正式版本发布了,大家一起拭目以待。
网友评论