Kyligence AI 服务 - 让大模型完成准确、可靠的数值计算和回答! 立即了解更多
AI 数智助理
Kyligence Zen Kyligence Zen
Kyligence Enterprise Kyligence Enterprise
Kyligence Turbo Kyligence Turbo
指标平台解决方案
OLAP 解决方案
行业解决方案
客户总览
金融
零售
制造
医药
其他
云平台
BI
寻求合作
资源
Kyligence Enterprise
Kyligence Zen
培训
Apache Kylin
Byzer
Gluten
博客
关于
市场活动
对 OLAP 场景的查询而言,单个查询往往需要在存储端扫描大量数据,再在内存中进行一些统计分析后,才能输出所需要的统计结果。因此,如果不能像以 Kylin 为代表的 MOLAP 引擎采用预计算的方式来避免数据的实时扫描,对于基于磁盘存储的数仓而言,存储端无疑会因为扫描大量数据造成磁盘吞吐的瓶颈。
既然如此,是否存在别的选择,可以少从存储端加载数据呢?列存数据库正是通过采取合适的数据组织结构,来减小查询加载的数据量,最终提高查询效率。
大数据圈的各位对列式存储一定不陌生,快速浮现你脑海里的想必是 ORCFile,Parquet 等,但其实这些只是数据格式,并不能直接和列存数据库划等号。
列存格式 = 列存数据库
列存数据库[1]更像是基于列存格式,设计的一套完整的数据库解决方案,而这套解决方案不仅需要考虑数据格式,更要考虑以下因素:
由此可见,为了追求极致的性能,底层存储的变化往往会引发存取方法、执行引擎、关系算子算法实现等多方面的一系列适配性的变化,真可谓环环相扣,好不紧张。下面,我们就依次从这几个方面介绍其所涉及内容。
可曾记得把列存的思想引入大数据的先驱者—— RCFile[3],它的基本思想是将数据水平切分成一个个行组,在每个行组内除了元数据和行组切分标识以外,数据部分按列来进行连续存储。
这样操作的原因在于 OLAP 的查询虽然一般都会扫描大量行,但只会涉及少量列,通过这样的列存布局方式,能够有效避免无关列的加载,从而达到减小磁盘吞吐的目的。
但似乎先驱者的下场往往不那么尽如人意,RCFile 也没有摆脱这个魔咒。相较传统数仓中的列存而言,RCFile 还是太过粗糙,要学就学全套呀!
Hive 的开发者们总结了 RCFile 的经验教训,指出其核心问题[4]在于:
站在前人的肩膀上,后续的 ORCFile,Parquet 都开启了进化之旅,一方面加入一些 Min、Max、Count 等轻量级统计索引来加速查询;另一方面,针对不同场景,采用 RLE,Bitcode,Dictionary Code 等编码方式进行存储优化,比如 RLE,针对的就是取值范围不大,重复度高的数据,假设有一列数据是 AAABBBB,RLE 就会直接采用 A3B4 来表达(其中“3”和“4”代表前一个值出现的次数)。
自此以后,列存格式的风吹遍了整个大数据生态圈,CarbonData 采用多维排序的方式优化数据的列式布局;Druid 在列存之上,通过对维度列进行 Dictionary 编码加 Bitmap 索引的方式加速了数据的筛选和聚合......
当然,存储格式并不是只需关心存储查询的效率问题,将其应用到实际中所需要考虑的问题同样重要。比如,2019 年 4 月,Databricks 公司重磅开源 Delta Lake,给数据添加了 ACID 特性,支持数据的并发读写,Hudi 和 Iceberg 也不甘落后,存储的故事又拉开了一张大幕,世界就是这样精彩!
数据存在磁盘上的数据布局叫做存储格式,而存取方式则包括:
等一系列过程。
这里我们以数据从磁盘加载到内存的过程为例,来探讨列式存储能够给存取过程带来哪些优势。由于数据最终输出时是以行为单位,所以在将列存数据读入内存时,直接定位到要扫描的列,然后按顺序重构一行行数据并交由执行引擎处理,就显得尤为自然,但我们不如想的更深入一步:
对于问题一,Presto、ClickHouse 等实践者通过在内存中使用列存布局,不仅优化了存储效率,也使得向量化计算加速分析查询变为可能;
对于延迟物化[5]的问题,核心就在于数据是否能等到真正需要它们的时候再加载,例如对于以下查询:
select b from R where a = X and d = Y
是直接如上图左侧所示,将查询涉及到的 a、b、d 列全部加载到内存里构成一行一行数据,然后进行过滤(Filter)和映射(Project);
还是如上图右侧所示,选择尽量延迟加载,先分别对 a、d 列进行单独加载过滤,决定要输出的行(图中的 01 向量),再把对应行的 b 列加载输出,最后再构建成行数据输出?
这两者的 Tradeoff 在于,虽然延迟加载能够减少数据的加载量,但需要维护原始数据的位置,这样才能找到对应行的其他列的值,然而如果筛选条件(R.a = X and R.d = Y )不能大量过滤数据,延迟加载反而低效。对于这种情况,就需要根据一些统计信息选择合适的加载算法,来最大限度的提高效率。
说完了存储端的故事,让我们转战计算端,唠一唠执行引擎和关系算子与列存之间又有怎样的故事。
首先,来了解一下执行引擎的在 SQL 查询过程中发挥了什么样的作用。
熟悉 SQL 查询引擎的同学应该都清楚,一条 SQL 会经过词法语法解析、语义校验、逻辑执行计划生成优化等一系列步骤,生成最后的物理执行计划,例如,对于如下 SQL:
select * from R where a = 1
其物理执行计划如下图所示:
执行引擎所做的事情就包括,定义 TableScan,Filter 等一系列关系算子(Operator)的实现框架,从而可以组合使用多个关系算子,构建它们之间的数据依赖关系(也就是执行计划),最终实现不同 SQL 的功能。
最经典的执行引擎实现非 Volcano[6] 莫属了。它把每一个算子抽象成数据的迭代器(Iterator),分别由 Open,Next,Close 构成。其中 Open 做一些初始化的工作,比如 TableScan 如何实现打开对应的表文件;Next 按照特定算子的功能逻辑处理数据,增量式得到输出;Close 清理资源。如下的伪代码就是 TableScan 的一个实现:
public class TableScan implement Iterator{ void open(){ tableFile.open(); } Row next(){ if ( (row = tableFile.nextRow()) != EOF){ return row; } return EOF; } void close(){ tableFile.close(); } }
Volcano 的优点在于处理逻辑清晰,每个算子只需关心自己的处理逻辑即可,耦合性低。不过它的缺点也很明显,过多虚函数的调用,导致大量 CPU cache miss,从而影响 CPU 执行效率。
在数据库诞生之初,数据库先贤们奋战在弥补磁盘和 CPU 速度巨大的鸿沟上,CPU 的浪费显得微不足道。然而,在数据库新时代,摩尔定律的失效使得单核性能提升日渐趋缓,OLAP 的发展导致将大量数据加载到内存进行计算,瓶颈慢慢从存储端向 CPU 端倾斜,榨干 CPU 每一滴性能的企图就变得越发强烈,于是 CodeGen,向量化执行[7]等方法应运而生,它们从不同的方向入手来优化 CPU 的利用率,能够极大的提高执行效率。向量化执行正是利用列式存储的优势,可以一次性对整列数据进行批量处理,减少 CPU 的消耗。
有了执行引擎奠定的框架,关系算子只需要一个萝卜一个坑,逐一实现即可,然而算法的世界是层出不穷,千变万化的,比如对于 Join 大家最熟悉的算法就有 BroadcastJoin,LookupJoin,SortJoin 等等, 而列存又会给 Join 算法带来什么样的优化空间呢?
对于 Join 而言,运算的核心在于两表中 Joinkey 的匹配上,而对于其他列数据匹配上了就复制,匹配不上就丢弃。那么结合延迟物化的思想,是否可以等到匹配完成后再加载其他列数据,从而减小不必要的数据加载。
举个例子,对于如下 SQL:
SELECT emp.age, dept.name FROM emp, dept WHERE emp.dept_id = dept.id
我们先抽出 emp 表的 dept_id 和 dept 表的 id 列数据,进行匹配,并输出匹配结果对应原表的位置信息,如下图所示:
其中等于号的左边为 dept_id 和 id 列的数据,等于号的右边为匹配结果对应原表的位置信息,比如第一行 1,2 代表 dept_id 列的第一个值 42 和 id 列的第 2 个值 42,Join 的结果。
然后根据输出的位置信息,就可以从原始数据中抽取 age,name 列的数据得到 Join 最后的结果。当然该算法能够产生明显优化效果的前提是 Join 的结果相较于原始数据比较小,这样才能够有效避免加载过多数据。另外由于上图输出结果的第二列是无序的,如果回表查必然造成大量随机 IO,为了解决这个问题,Jive Join[8]采用了对其进行排序之后再查询,即将随机 IO 转化为顺序 IO 的方法进行优化。
综上,我们从大数据存储格式的变迁;存取方式中 Early Materialization 和 Late Materialization 的权衡取舍;执行框架向优化 CPU 的方向迈进;关系算子结合存储进行优化等几个方面对列存数据库进行了讲解。
实际上,列存数据库不只是存储格式的问题,底层存储的变化往往牵一发而动全身,如何适应性的修改计算引擎、存取方式等来达到更高更快的性能,并适应不同的 workload 或者硬件发展的趋势,都是列存数据库要关心的问题。
参考文献:
[1] The Design and Implementation of Modern Column-oriented Database Systems.
[2] Design Tradeoffs of Data Access Methods.
[3] RCFile: A Fast and Space-efficient Data Placement Structure in MapReduce-based Warehouse Systems.
[4] Major Technical Advancements in Apache Hive.
[5] Materialization Strategies in a Column-oriented DBMS.
[6] Encapsulation of Parallelism in the Volcano Query Processing System.
[7] Vectorization vs. Compilation in Query Execution.
[8] Fast Joins Using Join Indices.
更多 Apache Kylin 最新动态,技术博客以及案例分享,请扫描二维码,关注 Apache Kylin 公众号。
01 现象 社区小伙伴最近在为 Kylin 4 开发 Soft Affinity + Local Cache
01 背景 随着顺丰末端物流(末端物流主要分为对小哥、柜机、区域等的资源的管理和分批;对路径、排班、改派等信息
Apache Kylin 的今天 目前,Apache Kylin 的最新发布版本是 4.0.1。Apache
Kylin 入选《上海市重点领域(金融类)“十四五”紧缺人才开发目录》 数字经济已成为全球增长新动
在 Kyligence 主办的 Data & Cloud Summit 2021 行业峰会的「数字化转
近日由 Kyligence 主办的 Data & Cloud Summit 2021 行业峰会在上海成
近五年来,Kyligence 服务了金融、制造、零售、互联网等各个行业的龙头企业,我们在服务这些企业的过程中,
2021年1月14日,Kyligence 产品经理陈思捷开启了我们在 2021 年的首场线上分享,为大家介绍了
400 8658 757
工作日:10:00 - 18:00
已有账号? 点此登陆
预约演示,您将获得
完整的产品体验
从数据导入、建模到分析的全流程操作演示。
行业专家解惑
与资深行业专家的交流机会,解答您的个性化问题。
请填写真实信息,我们会在 1-2 个工作日内电话与您联系。
全行业落地场景演示
涵盖金融、零售、餐饮、医药、制造等多个行业,最贴合您的业务需求与场景。
Data + AI 应用落地咨询
与资深技术专家深入交流,助您的企业快速落地 AI 场景应用。
立即预约,您将获得
精准数据计算能力:
接入高精度数值计算大模型服务,为您的企业级AI应用提供强大支持。
个性化业务场景解决方案:
量身定制的计算模型和数据分析服务,切实贴合您的业务需求和应用场景。
Data + AI 落地应用咨询:
与资深专家深入探讨数据和 AI 如何帮助您的企业加速实现应用落地,构建更智能的数据驱动未来。
申请体验,您将获得
体验数据处理性能 2x 加速
同等规模资源、同等量级数据、同一套数据处理逻辑,处理耗时下降一半
专家支持
试用部署、生成数据、性能对比各操作环节在线支持