青训营 实操课-简易列式存储
概述
2022の夏天,半壶水响叮当的我决定充实一下自我
前置克隆项目地址: github.com/theMYang/da… ,开课前1天完成项目运行,有问题可以记录一下,直播课跟着讲师节奏走,或者积极在弹幕区提问哈。
背景知识
行存 VS 列存
| 行存 | 列存 |
|---|---|
| 按行写入数据,读取数据时需要读取不必要的列 | 可以只读取请求的列 |
| 适用于OLTP系统 | 适用于OLAP系统 |
| 适用于按记录读取数据 | 适用于按列读取数据 |
| 不利于大数据集聚合统计操作 | 利于大数据集聚合统计操作 |
| 不利于数据压缩 | 利于数据压缩 |
Parquet 数据布局
项目目标
- 理解列存数据排布
- 代码设计 - 了解主要实现类的行为和功能
- 代码实现 - 以列存格式写入数据并正确读出
- 优化现有代码
项目设计
写入过程
示例表结构
| a_field (int) | b_field (long) |
|---|---|
| a1 | b1 |
| a2 | b2 |
| ... | ... |
| a100 | b100 |
写入流程
- 将一行行数据的字段拆分,分别存储在各字段对应的ChunkWriter中
-
当写入的数据达到一个块的长度,或是数据已经写完,此时会持久化数据,以及生成块的元数据
- 持久化数据至输出流中
- 生成元数据,包括每个字段的元信息以及该块已写数据量
- 当整个文件写完,将文件元信息写至输出流,并在文件最后记录元数据占用字节数。
最终文件组织示例
文件
读取流程
- 读取元数据
- 根据元数据,获取每个block中各个列信息
- 根据请求列,读取对应列数据
- 将读取到的数据拼成Record返回
代码流程图
写入流程
读取流程
项目仓库
代码结果
代码仓库: github.com/theMYang/da… 利用cloc工具进行代码统计:
编译
mvn clean install -DskipTests
复制代码
代码优化
- 支持复杂类型读写
- 增加列基本统计值,增加filter过滤不需要读取的数据
- 支持数据压缩、编码
- 预读取优化
- 拆列优化
- 对接Spark或Hive等计算引擎
晚安玛卡巴卡
快乐暑假