写点什么

为什么 OLAP 需要列式存储

  • 2021-03-21
  • 本文字数:2532 字

    阅读完需:约 8 分钟

为什么 OLAP 需要列式存储

为什么这么设计(Why’s THE Design)是一系列关于计算机领域中程序设计决策的文章,我们在这个系列的每一篇文章中都会提出一个具体的问题并从不同的角度讨论这种设计的优缺点、对具体实现造成的影响。如果你有想要了解的问题,可以在文章下面留言。


ClickHouse 是最近比较热门的用于在线分析处理的(OLAP)1数据存储,与我们常见的 MySQL、PostgreSQL 等传统的关系型数据库相比,ClickHouse、Hive 和 HBase 等用于在线分析处理(OLAP)场景的数据存储往往都会使用列式存储。



图 1 - OLAP 和 OLTP

对数据库稍有了解的读者都知道,在线事务处理(Online Transaction Processing、OLTP)2和在线分析处理(Online Analytical Processing、OLAP)是数据库最常见的两种场景,这两种场景不是唯二的两种,从中衍生出来的还有混合事务分析处理(Hybrid Transactional/Analytical Processing、HTAP)3等概念。


在线事务处理是最常见的场景,在线服务需要为用户实时提供服务,提供服务的过程中可能要查询或者创建一些记录;而在线分析处理的场景需要批量处理用户数据,数据分析师会根据用户产生的数据分析用户行为和画像、产出报表和模型。


标题中提到的列式存储与传统关系型数据库的行式存储相对应,如下图所示,其中行式存储以数据行或者实体为逻辑单元管理数据,数据行的存储都是连续的,而列式存储以数据列为逻辑单元管理数据,相邻的数据都是具有相同类型的数据。



图 2 - 行式存储和列式存储

既然我们已经了解了标题中提到的两个概念:OLAP 和列式存储,那么接下来将从以下两个方面分析为什么列式存储更适合 OLAP 的场景。


  • 列式存储可以满足快速读取特定列的需求,在线分析处理往往需要在上百列的宽表中读取指定列分析;

  • 列式存储就近存储同一列的数据,使用压缩算法可以得到更高的压缩率,减少存储占用的磁盘空间;

按需读取

在线服务需要应对用户发起的增删改查需求,虽然查询的需求往往都是写入请求的几倍、甚至几十倍,但是写操作带来的负责一致性问题成为了在线服务数据存储不得不解决的问题,MySQL 和 PostgreSQL 等使用关系型数据库提供的事务可以提供很好的方案。


正是因为 OLTP 场景中大多数的操作都是以记录作为单位的,所以将经常被同时使用的数据相邻存储也是很符合逻辑的,但是如果我们将 MySQL 等数据库用于 OLAP 场景,最常见的查询也可能需要遍历整张表中的全部数据。



图 3 - 在行式存储获取特定列

如上图所示,当我们仅需要获取上表中年龄的分布时,也仍然需要读取表中的全部数据并在内存中丢弃不需要的数据行,其中黄色部分都是我们不关心的数据,这浪费了大量的 I/O 和内存资源。虽然我们可以使用辅助索引解决这些问题,但是对于 OLAP 中常见的几十列甚至上百列的宽表就捉襟见肘了。

列式存储会按列存储数据,这也意味着在读取数据表中的特定列时,我们只需要找到相应内存空间的起始位置,然后读取这片连续的内存空间就可以获得关心的全部数据。



图 4 - 在列式存储获取特定列

哪怕在几百列的大表中找到几个特定列也不需要遍历整张表,只需要找到列的起始位置就可以快速获取相关的数据,减少了 I/O 和内存资源的浪费,这也是为什么面向列的存储系统更适合在 OLAP 的场景中使用。

数据压缩

因为列式存储将同一列的数据存储在一起,所以使用压缩算法可以得到更高的压缩率,减少存储占用的磁盘空间。压缩算法的基本原理其实很简单,它使用基于特定规则的数据表示原数据,如下所示的字符串中包含连续的相同字符,我们使用最符合直觉的压缩算法就可以减少字符串的长度:



图 5 - 简单的压缩算法

上图中所有的黄色方块表示前面字符串的重复次数,这种简单的压缩策略可以在保证无损的情况下将字符串的长度压缩 33%,然而压缩率是由压缩算法和数据的特性共同决定的。与面向行的数据存储相比,面向列的数据存储会将相同类型的数据就近存储,这也给压缩算法的提供了更多发挥的空间。


虽然压缩算法实际上是一种使用 CPU 时间换取 I/O 时间和空间的策略,但是在多数情况下,这种生意都是稳赚不赔的。压缩算法通过减少数据的大小、减少磁盘的寻道时间提高 I/O 的性能、减少数据的传输时间并提高缓冲区的命中率,节省的 I/O 时间可以轻易补偿它带来的 CPU 额外开销4

总结

在线分析处理的场景虽然一直都存在,不过随着数字化浪潮的演进,我们也只是在最近才采集到了海量的用户数据。因为过去的系统无法满足今天海量数据的分析和处理需求,所以才出现了为细分场景设计的系统,面向列的存储系统也因为它的以下特性在 OLAP 的场景中焕发了光彩:


  • 列式存储可以满足快速读取特定列的需求,在线分析处理往往需要在上百列的宽表中读取指定列分析,而传统的行式存储在分析数据时往往需要使用索引或者遍历整张表,带来了非常大的额外开销;

  • 列式存储就近存储同一列的数据,使用压缩算法可以得到更高的压缩率,减少存储占用的磁盘空间,虽然带来了 CPU 时间的额外开销,但是节省的 I/O 时间比带来的额外开销更多;


列式存储在 OLAP 的场景中有着种种优势,不过它也不是数据存储中的银弹,仍然有很多缺点,不过在这里就不做讨论了。到最后,我们还是来看一些比较开放的相关问题,有兴趣的读者可以仔细思考一下下面的问题:


  • 列式存储在 OLTP 的场景中有哪些缺点?

  • HTAP 的场景会使用哪种方式存储数据?


推荐阅读


如果对文章中的内容有疑问或者想要了解更多软件工程上一些设计决策背后的原因,可以在博客下面留言,作者会及时回复本文相关的疑问并选择其中合适的主题作为后续的内容。


  1. Wikipedia: Online analytical processing https://en.wikipedia.org/wiki/Online_analytical_processing ↩︎

  2. Wikipedia: Online transaction processing https://en.wikipedia.org/wiki/Online_transaction_processing ↩︎

  3. Wikipedia: Hybrid transactional/analytical processing https://en.wikipedia.org/wiki/Hybrid_transactional/analytical_processing ↩︎

  4. Abadi D, Madden S, Ferreira M. Integrating compression and execution in column-oriented database systems[C]//Proceedings of the 2006 ACM SIGMOD international conference on Management of data. 2006: 671-682. ↩︎


本文转载自:Draveness

原文链接:为什么 OLAP 需要列式存储

2021-03-21 08:002416

评论

发布
暂无评论
发现更多内容

TCP拥塞控制四种算法

赖猫

TCP 网络协议

【科创人】维格表创始人陈霈霖:喜茶数字化转型的结晶是vika维格表

科创人

本科毕业,六年Java开发经验,阿里技术三面+HR面,拿下38*16薪资P7offer

Java架构之路

Java 程序员 架构 面试 编程语言

【死磕JVM】一道面试题引发的“栈帧”!!!

牧小农

JVM Java虚拟机 运行时数据区 Java虚拟机栈 栈帧

集成融云 IMLib 时,如何实现一套类似于 IMKit 的用户信息管理机制

融云 RongCloud

腾讯高级工程师保姆级“Java成长手册”,层层递进,全是精华

Java架构追梦

Java 腾讯 面试 架构师

三步上线自己的在线监考系统

融云 RongCloud

BOE(京东方)物联网解决方案让会议更“智慧”

爱极客侠

HECO火币生态链挖矿系统开发搭建技术

薇電13242772558

数字货币 区块链生态

第八章学习总结

Kalman

产品经理 产品经理训练

邀请领好礼!米家显示器挂灯、雷蛇烈焰神虫送给你!

滴滴云

架构师训练营第六周作业 - 命题作业

阿德儿

GitHub Action + ACK:云原生 DevOps 落地利器

阿里巴巴云原生

容器 运维 云原生 k8s 应用服务中间件

Redis 在项目中合理使用经验总结

Java小咖秀

redis

架构师训练营第十周作业 - 命题作业

阿德儿

面试字节跳动定级2-2,拿32*16offer,P8大佬的算法教程给了我春天!

Java架构之路

Java 程序员 架构 面试 编程语言

使用 Arthas 排查 SpringBoot 诡异耗时的 Bug

阿里巴巴云原生

Java 开发者 云原生 中间件 Arthas

第八章作业

Kalman

产品经理 产品经理训练

万物互联网络在企业中的价值和展望 | 趋势解读

浪潮云

物联网

一分钟了解EFT公链新一代超级DeFi公链——EGG超级公链

币圈那点事

区块链 公链 挖矿

中台还没建就开始拆中台了?医疗中台何去何从?

菜根老谭

中台 医疗中台

恭喜自己2021金三银四收到的第五个Offer:字节跳动Java研发岗

比伯

Java 编程 架构 面试 程序人生

如何写好操作类说明文档

lenka

3月日更

阿里P7亲自讲解!整理几个重要的Android知识,最全Android知识总结

欢喜学安卓

android 程序员 面试 移动开发

阿里P7亲自教你!一线互联网大厂中高级Android面试真题收录!讲的明明白白!

欢喜学安卓

android 程序员 面试 移动开发

Python 初学者必看:Python 异常处理集合

华为云开发者联盟

Python 异常 代码 程序 错误

《精通比特币》学习笔记(第十一章)

棉花糖

区块链 学习 3月日更

融云聊天室属性 kv

融云 RongCloud

音视频

PBAC相对于传统ABAC的优势

龙归科技

IT 架构师 权限 ABAC PBAC

翻译:《实用的Python编程》06_01_Iteration_protocol

codists

Python

华为18级工程师总结的50W字算法、LeetCode、操作系统、计算机底层刷题必备笔记

Java架构之路

Java 程序员 架构 面试 编程语言

为什么 OLAP 需要列式存储_语言 & 开发_面向信仰编程_InfoQ精选文章