rcfile和orcfile

news2024/11/16 17:29:01

一、数据存储要考虑哪些方面

  1. 数据加载时间

    Facebook数仓每天存储的数据量超过20TB,数据加载既有磁盘I/O又有网络传输,时间占用大

  2. 快速的数据查询

  3. 低的空间占用

    数据压缩/数据编码

  4. 适合多种查询模式

    如果所有人都查相同的字段,那么就可以针对这个字段做优化,如建立索引,但是不同的人在查询数据的时候,数据组合模式不同。

  5. 数据的写速度(我理解在大数据中不重要)

二、行式存储和列式存储

在这里插入图片描述

1. 行存储

001:10,Smith,Joe,40000;002:12,Jones,Mary,50000;003:11,Johnson,Cathy,44000;004:22,Jones,Bob,55000;

**优点:**适用于OLTP系统,每次都查一整行数据的,数据的写速度快

缺点:

  1. 在数仓中查询速度慢,因为一般仅需要查少数几列数据,但行存储会加载所有数据
  2. 压缩率低(我理解是不同的列存储在一起,很少会有相邻数据有重复,等后面看了数据压缩再确定)

2. 列存储

10:001,12:002,11:003,22:004;Smith:001,Jones:002,Johnson:003,Jones:004;Joe:001,Mary:002,Cathy:003,Bob:004;40000:001,50000:002,44000:003,55000:004;

2.1 两种模式:

  • Column-store

​ 每列是单独的关系,称为 Column-store,如MonetDB

优点:减少数据加载量

缺点:无法保证一行里的所有列存在同一个节点上, 这样会在重组时带来网络传输开销,过度的网络传输是MR的瓶颈。

  • Column-group

​ 把列按照不同的组合存储,称为 Column-group,如 C-store

​ **优点:**如果能把查询模式确定下来,那就能减少重组带来的消耗

​ **缺点:**数仓中查询模式一般都难以确定,所以不太可能带来上面的优点,多种组合(一个列反复和其他列组合)又会增加存储

在这里插入图片描述

三、RCFile的设计与实现

3.1 数据分布

  1. 采用行列结合的方式

    切块(block) -> 切行(row group) -> 切列 (可以想一下为什么先切行,再切列)

    一个表可以存储在多个block,一个block上的可以有多个row group

  2. 每个 row group 分成三个部分:

    • sync maker,标记一个 row group 的开始,用来做 row group 分割
    • row group的元数据信息,存了多少记录,每列占了多少字节,一列中的每个字段有多少字节(可以想一下为什么存这些信息)
    • 实际的数据

在这里插入图片描述

3.2 数据压缩

​ 在每一个row group中,元数据和数据分开压缩

元数据:采用 RLE 编码(Run Length Encoding )算法来压缩,因为一个列中有很多字段的长度是一样的

​ **数据:**每列单独压缩(为什么),使用 GZIP 压缩算法来达到高的压缩率

3.3 数据读取和懒解压

  • 数据读取

​ 根据元数据信息,只读取需要列的数据

​ 例:table:(c1, c2, c3, c4)

​ select c1 from table where c4 = 1

​ 只读取 c1 和 c4 到内存

  • 懒解压

    当一个列真正被需要的时候才解压对应的 row group(where 为 true)

​ 如上面的sql会先解压c4,如果发现了 c4 = 1的row group,才解压 c1的列

3.3 row group size

​ row group szie的设计要考虑的问题:

  1. 存储空间占用率,大的 row group size 有更高的压缩率,Facebook使用 GZIP 压缩,当 row group size 达到 4MB 的时候,存储空间占用率下降到瓶颈;

在这里插入图片描述

  1. 读取性能,小的 row group size 在做懒解压时候性能更好

**总结:**RC File的诞生解决了当时现有存储的问题,在存储性能、查询效率上都有了很大的提升。具体对比看下面的:

http://web.cse.ohio-state.edu/hpcs/WWW/HTML/publications/papers/TR-11-4.pdf

五、ORC

5.0 RC File 的缺点

  • RC File 没有类型,存的全是blob (Blob 对象表示一个不可变、原始数据的类文件对象。它的数据可以按文本或二进制的格式进行读取)
    • 不能按类型优化
    • 因为不知道存储的是什么类型,所以不能保存有用的索引信息
    • 复杂类型不能被分解,都是字节流
  • 基于流的编码器压缩(不确定是什么意思,我觉得可以和下面提到的压缩做对比)
    • 解压时必须从 row group 的头部开始
  • 懒解压慢

5.1 ORC 做的改进

提升查询效率

  • 添加索引信息

降低存储占用

  • 使用有类型的Writer和Reader,提供轻量级压缩技术,如dictionary encoding,bit packing,delta encoding和run length encoding,使得文件变小。
  • 在轻量级压缩的基础上,可以使用通用的压缩技术,如ZLIB、snappy、LZO、LZ4、ZSTD

5.2 结构

在这里插入图片描述

5.2.1 Postscript

  • 怎样解析其他部分的信息,如 footer 和 metadata
    • 文件的版本,即最低支持那个版本的hive
  • 采用的压缩格式(none,zlib,snappy)

在这里插入图片描述

5.2.2 Footer

  • 整体文件布局
  • 列的类型信息
  • 行数
  • 文件级别每列的统计信息
    • 原始类型都记录min/max,int, double, string, decimal, date, timestamp
    • 数值类型记录sum
    • 从hive1.1.0开始,记录hasNull用来优化 ‘is null’ 查询

5.2.3 File Metadata

  • stripe级别的列统计信息

5.3 类型信息

在真正存储的时候不会存储复杂类型,会把复杂里涉及到的列展开存储,

如下列sql创建一个这样的表,真正存储的时候会先序遍历这个树来进行存储

在这里插入图片描述

在这里插入图片描述

5.2 压缩

5.3 运行时长度编码(Run Length Encoding,RLE)

5.3.1 整数

编码规则:

  • **无符号数:**varint编码

    我们存储的大部分数据都是小整数,根本占不到32位,如果用32位来存储的话,会有很多字节是0,这样太浪费了,varint编码解决的就是把整数用更少的字节来存储,编码规则是源码的每 7 个bit分成一组,然后在每组的最高有效位放置 1 或者 0,1代表下一个字节还是属于这个整数,0代表下个字节开启新的整数

    如整数300,32位编码大端序是 00000000 00000000 00000001 00101100

    ​ 小端序是 00101100 00000001 00000000 00000000

    进行 varint 编码后就是:10101100 00000010,只需要占2个字节

    解码:按照首位的1把字节拼接,去掉每一组的最高有效位,进行计算

    ​ 10101100 00000010

    ​ -> 0101100 0000010(小端序)

    反转 -> 0000010 0101100

  • **有符号数:**ZigZag 编码

    负数不能用源码存储,需要用反码存储,反码是源码除了符号位外,其余取反加一

    如 -1的源码:1000000 00000000 00000000 00000000,反码是 11111111111111111111111111111111

    因为负数的最高有效位是符号为,如果直接用 varint编码的话,无法降低存储(目前理解是最少也要占 5 个字节,教程说要把负数转成 Long 再用 varint 编码,占用的就是10个字节,现在还不懂。)

    ZigZag的思路是把负数映射到无符号数上,在对无符号数进行varint编码,映射算法:

    (n << 1) ^ (n >> 31) (对于 32 位整数),把符号为移到最后一位
    如 n = -1
    -1: 11111111111111111111111111111111
    n << 1: 11111111111111111111111111111110
    n >> 31: 11111111111111111111111111111111
    (n << 1) ^ (n >> 31) = 00000000000000000000000000001 = 1
    对1进行 varint 编码就能用 1 个字节表示
    
    解码:
    (n >> 1) ^ - (n & 1)
    如编码之后的 n = 1
    n & 1: 00000000000000000000000000001 = 1
    -(n & 1): 11111111111111111111111111111111
    1 >> 1: 00000000000000000000000000000
    (1 >> 1) ^ -(n & 1) = 11111111111111111111111111111111
    

存储:

​ 数据分成两类,一类是间隔一个小整数的序列 Run,如 1, 3, 5, 7, 9;一类是正常的整数序列 Literal

​ Run:

​ [起始数字 - 3, 差值, 结束数字],起始数字的范围是 0 ~ 127,如序列 100 - 1编码为 [0x61, 0xff, 0x64].

​ Literals:

​ 序列长度取反,varint编码数字

​ 如[2, 3, 6, 7, 11]被编码为[0xfb, 0x02, 0x03, 0x06, 0x07, 0xb]

5.3.2 Byte Run Length Encoding

​ 把数据分成两类,一类是连续相同的字节 Run(至少三个),一类是连续不相同的字节 Literals

​ Runs:

​ 存连续的字节数 - 3(不清楚为什么要 -3)用来当控制字符,0 ~ 127,如 100 个 0 的编码是 [0x61, 0x00]

​ Literals:

​ 存连续的字节数取反用来当控制字符 -128 ~ -1,0x44, 0x45 的编码是 [0xfe, 0x44, 0x45]

0xfe: 
反码:11111110
源码:10000010 = -2

5.3.3 Boolean Run Length Encoding

​ boolean类型编码把多个值放到一个 byte 存储,如 [0xff, 0x80] 表示 1 个true和7个false(1000 0000)

5.3.4 String,Char,VarChar

​ 两种编码方式:

  • 直接编码:

    记录两个流:

    ​ DATA,LENGTH

    ​ 如:[“Nevada”, “California”] 的 DATA 是 NevadaCalifornia,LENGTH 是 [6, 10].

  • 字典编码(解决重复字符串的问题):

    记录三个流:

    ​ DATA,DICTIONARY_DATA,LENGTH

    ​ 如 [“Nevada”, “California”, “Nevada”, “California”, and “Florida”]

    ​ DICTIONARY_DATA 是 CaliforniaFloridaNevada”

    ​ LENGTH 是 [10, 7, 6]

    ​ DATA 是 [2, 0, 2, 0, 1].

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/164534.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

QT添加使用图片与UI资源

QT添加使用图片与UI资源1 QT添加使用图片资源1.1 添加新文件1.2 添加QT - QT Resources File 【UI资源文件】1.3 命名资源包名称 并 添加到项目文件1.4 .pro 文件发生变化 art.qrc1.5 点击qrc文件&#xff0c;添加现有文件 - 添加进去的图片文件可以进行正常引用。1.6 修改样式…

分布式任务处理xxljob

7.1 分布式任务处理 7.1.1 什么是分布式任务调度 视频上传成功需要对视频的格式进行处理&#xff0c;如何用Java程序对视频进行处理呢&#xff1f;这里有一个关键的需求就是当视频比较多的时候我们如何可以高效处理。 如何去高效处理一批任务呢&#xff1f; 1、多线程 多线…

通过Docker启动DB2,并在Spring Boot整合DB2

1 简介 DB2是IBM的一款优秀的关系型数据库&#xff0c;简单学习一下。 2 Docker安装DB2 为了快速启动&#xff0c;直接使用Docker来安装DB2。先下载镜像如下&#xff1a; docker pull ibmcom/db2:11.5.0.0 启动数据库如下&#xff1a; docker run -itd \--name mydb2 \--…

Allegro如何导入和导出Pin Delay操作指导

Allegro如何导入和导出Pin Delay操作指导 在做PCB设计等长设计的时候,Pin Delay是个非常重要的数据,关系到信号的长度,Allegro支持把Pin Delay数据导入到PCB中,并且还支持导出,如下图 具体操作如下 导入Pin Delay,选择File选择Import

图论基础: 邻接矩阵与邻接表(c++实现)

文章目录邻接矩阵邻接表邻接矩阵 邻接矩阵&#xff08;Adjacency Matrix&#xff09;是表示顶点之间相邻关系的矩阵。 设G(顶点&#xff0c;边)&#xff1a;G(V,E)是一个图。其中V{v1,v2,…,vn} [1] 。G的邻接矩阵是一个具有下列性质的n阶方阵&#xff1a; 无向图的邻接矩阵…

手眼标定,9点标定过程及其运算

在工业领域常常会遇到将相机安装在机器手中&#xff0c;由相机快速引导机器手进行工作的方式。其中9点标定的作用是将图像的坐标转化为机器手的坐标。 9点标定的作用意义&#xff1a; 1.计算像素当量&#xff0c;通过9点标定后的计算&#xff0c;可以得出一个由像素值转化为机器…

水平分表、分库和垂直分表、分库和公共表的代码实现和讲解

文章目录一、环境准备二、水平分表1.概念2.代码三、水平分库1.概念2.代码四、垂直分表1.概念2.代码五、垂直分库1.概念2.代码六、公共表1.概念2.代码一、环境准备 操作系统&#xff1a;Win10数据库&#xff1a;MySQL5.7JDK&#xff1a;64位 jdk1.8.0_202应用框架&#xff1a;s…

DOS和DDOS攻击和防御(ATTACK)

目录 一、DOS攻击和DDOS攻击的区别 第一、我们可以从他们两个的英文全称上来看初步的区别 第二、攻击方法不同 二、DOS和DDOS攻击的实现方式 1.DOS攻击 1、SYN Flood(是DOS和DDOS攻击方式之一) 2、UDP洪水攻击 3、Ping洪流攻击 4、teardrop攻击 5、Land攻击 6、Smurf攻击 7、Fr…

【 uniapp - 黑马优购 | 登录与支付 1】登录组件布局实现、用户信息布局与渲染

个人名片&#xff1a; &#x1f43c;作者简介&#xff1a;一名大二在校生&#xff0c;讨厌编程&#x1f38b; &#x1f43b;‍❄️个人主页&#x1f947;&#xff1a;小新爱学习. &#x1f43c;个人WeChat&#xff1a;见文末 &#x1f54a;️系列专栏&#xff1a;&#x1f5bc;…

设计模式-原型模式

设计模式-原型模式一 官方定义二 案例演示解决方案一 - 一般实现方式实现过程案例分析解决方案二使用场景实现过程一实现过程 二案例分析三 浅拷贝和深拷贝浅拷贝问题演示实现过程案例分析解决方案-----深拷贝实现方式一&#xff1a;重写clone()方法扩展思考一 官方定义 原型模…

在VMware 虚拟机(Win7)中还原真机Ghost备份的Win10系统

要求&#xff1a; 将真机Ghost备份的Win10系统还原到VMware安装的虚拟机&#xff08;Win7&#xff09;上 真机&#xff08;物理机&#xff09;&#xff1a;win10pro_pure_20220709.GHO &#xff08;备份的GHO文件&#xff09;&#xff1b;安装模式&#xff1a;Win10UEFIGPT 虚…

HashMap源码学习:红黑树原理详解

前言 JDK1.8后的HashMap引入了红黑树&#xff0c;在学习HashMap源码之前&#xff0c;了解了红黑树原理&#xff0c;及其如何通过代码进行实现后&#xff0c;在整体的看HashMap的源码就会简单很多。 概述 红黑树的特性 根节点必须是黑色节点。节点是红色或黑色。所有叶子都是…

Redis原理

Redis内部使用的是文件事件处理器file event handler,它是单线程的,所以Redis叫做单线程模型。它采用IO多路复用机制同时监听多个socket,将产生事件的socket压入内存队列中,事件分派器根据socket上的事件类型来选择对应的事件处理器进行处理。文件事件处理器包含4个部分:多…

【Java寒假打卡】Java基础-线程池

【Java寒假打卡】Java基础-线程池概述基本使用Executors创建指定上限的线程对象线程池-ThreadPoolExecutorvolatile概述 基本使用 package com.hfut.edu.test12;import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors;public class test1 {publ…

java+springboot笔记2023003

java的版本发布&#xff1a; 编译型语言是指使用专门的编译器&#xff0c;针对特定平台&#xff08;操作系统&#xff09; 将某种高级语言源代码一次性“翻译”成可被该平台硬件执行的机器码&#xff08;包括机器指令和操作数&#xff09;&#xff0c;并包装成该平台所能识别的…

Linux下更新curl版本

一、前景 由于低版本的curl存在一定的漏洞&#xff0c;会对我们的服务器安全造成问题&#xff0c;所以&#xff0c;我们需要将curl由低版本安装到高版本。 二、步骤 1、首先检测服务器安装的curl版本 curl --version 2、查看服务器安装的curl的安装包 rpm -qa curl 3、卸载…

基于springboot+mybatis+mysql+jsp房屋租赁管理系统(含论文)

基于springbootmybatismysqljsp房屋租赁管理系统&#xff08;含论文&#xff09;一、系统介绍二、所用技术三、功能展示三、其它系统四、获取源码一、系统介绍 包括管理员、房东、租客三种角色&#xff0c;外加游客(未登录情况) 出租类型包含整租和合租 权限 游客 < 租客 …

适合编程初学者的开源项目:小游戏2048(鸿蒙ArkTS版)

目标 为编程初学者打造入门学习项目&#xff0c;使用各种主流编程语言来实现。 2048游戏规则 一共16个单元格&#xff0c;初始时由2或者4构成。 1、手指向一个方向滑动&#xff0c;所有格子会向那个方向运动。 2、相同数字的两个格子&#xff0c;相遇时数字会相加。 3、每次…

用 JavaScript 写一个新年倒计时

目录前言&#xff1a;主题&#xff1a;运行结果&#xff1a;对应素材&#xff1a;代码实现思路&#xff1a;运行代码&#xff1a;春节的由来&#xff1a;总结&#xff1a;前言&#xff1a; 在春节即将到来&#xff0c;钟声即将响起&#xff0c;焰火即将燃起的日子里&#xff0c…

Kubernetes_CRD自定义资源

系列文章目录 文章目录系列文章目录前言一、CRD操作命令1.1 定义一种资源并查看1.2 使用刚刚定义的资源二、CRD效果演示2.1 实践&#xff1a;定义一种资源并查看2.2 实践&#xff1a;使用刚刚定义的资源总结前言 CRD就是自定义资源&#xff0c;就是自定义 apiVersionKind 参考…