【数据蒋堂】第8期:列式存储的另一面

列存是常见的数据存储技术,在许多场景下也确实很有效,因而也被不少数据仓库类产品采用,在业内列存也常常就意味着高性能。

可是,列存真有这么好吗?搜索一下,容易找到的列存缺点一般是针对数据修改的,而对于只读的分析计算任务,却很少能见到较详细的讨论。我们在这里来研究一下这个问题。

对内存计算意义不大

列存的原理很简单:由于磁盘不适合跳动式读取,采用行式存储时在读取数据时会扫描所有列,而一次运算可能只涉及很少的列,这样就会多读很多用不上的数据。采用列存则只需要读取需要用到的列,数据访问量大概率会大幅减少,而大数据计算中磁盘扫描时间的占比很大,减少访问量就能节约大量时间。另外,同一列数据相同值情况较多,采用列存更容易做合并压缩,从而进一步减少数据存储量,提高性能。

从原理可以看出,列存能提高性能主要是因为减少了磁盘访问量,但对于计算量减少并没有帮助。如果数据已经被加载进内存,再采用列存就没多大意义了。普通结构化数据运算都是以行为单位的,在内存中使用列存反而会加大构造完整记录的复杂度,降低性能。所以,除了专业的向量式运算(数据挖掘中常用,运算本身就是以列为单位的)外,类似关系数据库型的内存运算(包括内存数据库)并不合适采用列式存储。

加剧硬盘的不连续访问程度

列式存储时,各列是连续存储的,这样同时访问多个列进行计算时,就会导致造成不连续的随机访问,访问的列越多造成的不连续性就越强。而针对机械硬盘的不连续读取会严重影响性能,在访问列数较多或总列数并不多时,就可能发生还不如行存的性能好的现象,因为行存是连续访问的,跳动的成本有可能超过。如果有并发任务(以及下面会说到的并行计算)还会严重加剧这一问题,当然行存并发时也会发生磁盘跳动,但程度比列存轻得多,列存时每多一个并发计算任务会多出几个(涉及列数)对磁盘的并发访问请求,行存则只会多一个磁盘并发请求。

一个办法是加大读取缓存区以减少磁盘寻道时间的占比,但这样为每个涉及列都设置缓存区,列较多时会占用大量内存。另一个办法是增加磁盘数量,把不同的列存储到不同的磁盘上,不过列存一般应用场景都是总数列很多的情况,常常远大于机器可以接受的硬盘数量,还会较大概率地造成磁盘随机访问冲突。

固态硬盘没有寻道时间的问题,列式存储更适合采用固态硬盘。

索引效率低

索引也是常用技术,用于从大数据集中按键值找出指定记录。我们在以前文章中讲过,索引的本质是排序,索引表中将存储有序的键值及该键值对应的原表记录位置。对于行式存储来说,整条记录的位置可以用一个数表示;但列存就不一样了,整条记录的每个列分别有各自的位置,原则上需要都记录下来,这样一来,索引表几乎和原表一样大,访问成本变高很多,空间占用也太大,这和复制原表后排序区别并不大了。

每条记录只存储一个序号,然后用乘法计算出位置,这样可以吗?有些数据类型的字段值的长度本身就是不固定的(串型),而固定长度的字段值(整数、日期)也可能因为要压缩编码(列存中常用的技术)而变成不固定,一定要用定长方式存储,索引倒是简单了,访问也很快,但会加大存储量,遍历时又不划算了,而这是列存更主要的应用场景。

实际常用的手段是把数据分块,块内数据采用列存,索引只建立在块上。这样可以用索引迅速定位中所需要的数据在哪个块中,然后只要块内进行扫描即可。

这种索引比行存索引会多一个块内扫描的过程,性能要低一些。如果原数据按索引键值有序(索引键常常就是原表主键),那可以很容易地定位出目标数据所在的少量的几个块(大概率只在一块中),这时性能损失还可以容忍,可适用于按唯一ID值找出指定记录的场景。但如果原数据对索引键无序,那这个索引几乎没有用处,目标数据可能落在几乎所有的块中,这就和全表扫描区别不大了。

分段并行麻烦

要充分利用多CPU(核),多线程并行能力是个必须考虑的问题,而要并行这就需要先把数据分段。

分段有两个基本需求:每段数据量基本相同(每线程处理能力相当),可以较灵活的分段(事先不能预测线程数)。行式存储时相对容易实现分段,只要每条(也可以每N条)记录后做一个结束标记,在分段时按字节数平均分成K段,然后在每段中寻找到结束标记后作为开始点即可。但列式存储不能采用同样的办法,由于前述原因,字段值是不定长的,某个列的分段点未必和另一个列的同样的分段点同步落在同一条记录上,这会错位导致错误的数据。

列式存储的分段一般也是采用前述的分块方案:分段必须以块为单位,在块内不再分段并行。这样就会有一个矛盾,首先,分块数不能太少了,否则就无法做到灵活分段了(只有5个分块时不可能做出10个分段),按现代服务器的CPU(核)数,要有上百个分块才能比较自由地平衡分段;但是,分块数又不能太多,列数据在物理上会被拆成多个不连续的小块,不仅使得遍历代码复杂很多,而且还会多读入少量两块之间的无用数据,对于机械硬盘还有寻道时间问题,分块数越多这些问题就越严重。只有分块内列数据占用空间比读入缓冲区大很多时,无用数据读入时间和寻道时间的占比才会比较小,这就要求每个分块中有足够多的记录数,也就是说,实现列存并行,数据量要足够大才有意义,对于机械硬盘(包括用机械硬盘构成的阵列)上一般得达到单机单表十亿记录、空间约在百G以上。规模较小的数据量就不容易获得并行计算的性能提升,而特别适合使用列存的多维分析业务的数据量就处于这种尴尬的规模中。另外,分块容量在数据追加前就要确定下来,随着数据的不断追加,相邻分块却不能物理上合并,分块数就会越来越多,这将给管理造成不少麻烦,需要可扩展的空间专门存储分块的索引信息。

我们在这里介绍列存的另一面,并非要否定列存在许多计算场景时的巨大优势 ,但完全不区分情况地全面采用列存也是不负责任的。对于数据仓库类产品,正确的做法应当将这个自由度留给系统管理员,由用户来决定是否采用列存、如何分块、哪些数据采用列存、有些数据甚至会行存和列存共存,以冗余换取更高的性能。

原文发布时间为:2017-5-26

本文作者:蒋步星

本文来自合作伙伴“数据蒋堂”,了解相关信息可以关注“数据蒋堂”微信公众号

时间: 2024-10-26 16:47:30

【数据蒋堂】第8期:列式存储的另一面的相关文章

【数据蒋堂】列式存储的另一面

列存是常见的数据存储技术,在许多场景下也确实很有效,因而也被不少数据仓库类产品采用,在业内列存也常常就意味着高性能. 可是,列存真有这么好吗?搜索一下,容易找到的列存缺点一般是针对数据修改的,而对于只读的分析计算任务,却很少能见到较详细的讨论.我们在这里来研究一下这个问题. 对内存计算意义不大 列存的原理很简单:由于磁盘不适合跳动式读取,采用行式存储时在读取数据时会扫描所有列,而一次运算可能只涉及很少的列,这样就会多读很多用不上的数据.采用列存则只需要读取需要用到的列,数据访问量会大幅减少,而大

【12.2新特性】在Oracle Active Data Guard上部署列式存储

一.In-Memory and Active Data Guard 在Active Data Guard上部署列式存储的目的 可以选在在主库.备库或者两者同时部署列式存储.当在主备库上同时部署了列式存储的时候,可以在两个库上对相同或者不同的对象集做操作,如果是操作不同的对象集,那就相当于增加了In-Memory的存储大小. 在主备库上部署同样的In-Memory. 在最简单的情况下,主数据库和备用数据库都包含具有相同大小(不是必需的)的IM列存储. IM列存储包含相同的对象. 此方案的优点是分析

【数据蒋堂】第7期:硬盘的性能特征

我们都知道内存比硬盘要快得多,大概能快出一两个数量级(价格也要贵这么多).不过,硬盘的问题并不只是访问速度慢. 硬盘不适合做频繁小量访问 所谓频繁小量访问,是指运算过程中每次获取的数据量很小,而读取的次数很多.对于内存,每次取10字节.取1000万次.总共访问1亿字节:和每次取1000万字段.取10次.也访问1亿字节:这两者耗时是差不多的.内存访问数据的最小单位就是字节,无论怎么做,最后涉及到的字节数是一样的. 但硬盘的机制完全不同,在硬盘中数据是按扇区存放的,数据访问的最小单位是扇区(一般是5

Parquet 支持数据嵌套的列式数据存储格式

简介         Apache Parquet 是一个列存储格式,主要用于 Hadoop 生态系统.对数据处理框架.数据模型和编程语言无关.Cloudera的大数据在线分析(OLAP)项目Impala中使用该格式作为列存储.         Parquet是Twitter内部的列式存储,目前开源并将代码托管在 parquet-format上         Parquet是一种供Hadoop使用的列式存储格式.Parquet为Hadoop生态系统中的所有项目提供支持高效率压缩的列式数据表达,

【数据蒋堂】第1期:多维分析的后台性能优化手段

多维分析就是针对一个事先准备好的数据立方体实施旋转.切片(切块).钻取等交互操作的过程,经常也被直接称为OLAP.它的后台运算在结构上很简单,如果用SQL语法描述,大体形式为: SELECT D,..., SUM(M), ... FROM C WHERE D'=d' AND ... GROUP BY D,... 即对立方体按某些维度分组汇总某些测度.其中C是数据立方体,D,...是选出维度,M,...是聚合测度,聚合函数也可以不是SUM.D'是切片维度,切块时条件为D IN (d,...),WH

【数据蒋堂】多维分析的后台性能优化手段

" 开篇辞 <数据蒋堂>的作者蒋步星,从事信息系统建设和数据处理长达20多年的时间.他丰富的工程经验与深厚的理论功底相互融合.创新思想与传统观念的相互碰撞,虚拟与现实的相互交织,产生出了一篇篇的沥血之作.此连载的内容涉及从数据呈现.采集到加工计算再到存储以及挖掘等各个方面.大可观数据世界之远景.小可看技术疑难之细节.针对数据领域一些技术难点,站在研发人员的角度从浅入深,进行全方位.360度无死角深度剖析:对于一些业内观点,站在技术人员角度阐述自己的思考和理解.蒋步星还会对大数据的发展

海量高性能列式数据库HiStore技术架构解析

HiStore 介绍 HiStore是阿里中间件团队研发的数据库产品,是一款基于独特的知识网格技术的列式数据库,定位于海量数据高压缩比列式存储,是低存 储成本,低维护成本,海量数据OLAP存储引擎;有效的解决了海量数据存储的成本问题,以及在百亿数据场景下支持实时高效的多维度自 由组合的检索. 关键字: 列式,分布式,高压缩比; 一.HiStore HiStore 专门针对OLAP应用程序进行设计和优化,在常规X86服务器上,HiStore可以在百亿数据场景下进行高性能,多维度自由组合 的adho

海量高性能列式数据库HiStore介绍

HiStore是阿里中间件技术团队研发的数据库产品,是一款基于独特的知识网格技术的列式数据库,定位于海量数据高压缩比列式存储,是低存储成本,低维护成本,海量数据OLAP存储引擎:有效的解决了海量数据存储的成本问题,以及在百亿数据场景下支持实时高效的多维度自由组合的检索. HiStore的优势 • 存储数据量大:TB级数据大小,百亿条记录.数据量存储主要依赖自己提供的高速数据加载工具(2TB/小时)和高数据压缩比(>10:1): • 高压缩比:平均压缩比>10:1,远高于常规压缩算法,甚至可以达

《NoSQL权威指南》——2.1 列式数据库的历史

2.1 列式数据库的历史 列式存储以及倒排或不按顺序存储文件的方式并不是最新提出的.TAXIR是1969年为生物学建立的第一个列式数据库存储系统.加拿大统计局于1976年实现了RAPID系统,并将其用于加拿大人口和住房普查数据的处理和检索,以及其他与统计相关的一些应用.RAPID被拿来与世界各地的其他统计机构共享,并在20世纪80年代被广泛使用.直到20世纪90年代,它一直被加拿大统计局使用. 多年来,Sybase IQ是市面上唯一一个可以商用的列式DBMS.然而,当OLAP(online an