数据_数据格式_Parquet存储文件格式原理

应用三阶段

 01.初步了解如何使用这种格式? 
 02.进一步如何优化这种格式
 03.再然后是在面对新的问题时候,如何解决问题


格式具体是如何设计的,以及为什么这样设计?
这个系统为了解决什么问题?为此提供了什么功能?

数据持久化 是将内存中的数据模型转换为存储模型,以及将存储模型转换为内存中的数据模型的统称.
	 据持久化对象的基本操作有:保存、更新、删除、加载、查询等
	  
二进制持久化
	--序列化和反序列化  Parquet文件格式选用 thrift完成文件元数据的序列化和反序列化
    --索引	 

数据模型

Parquet 的 数据模型 也是 schema 表达方式,   Parquet文件格式选用 thrift完成文件元数据的序列化和反序列化。
 在parquet-format项目的thrift目录下,文件parquet.thrift详细定义了parquet文件的元数据类型 用关键字 message 表示
schema协议 
  采用类似于Protobuf 协议来描述,每个字段有三个属性:重复性(Repetition)、类型 (Type)和名称 (Name) 
      optional 可选,required 必需和 repeated 重复字段	
	Parquet的设计者引入了两个新的概念:
	    repetition level 和 definition level。这两个值会保存额外的信息,可以用来重构出数据原本的结构  
	     repetition level主要用来表达数组类型字段的长度,但它并不直接记录长度,而是通过记录嵌套层级的变化来间接地表达长度
            repetition level主要用来表达数组的长度
            definition level主要用来表达null的位置
		对非数组类型的值不保存repetition level”,“对必填字段不保存definition level”等,真正存储这两个level时,也使用的是bit-packing + RLE编码

工程实现

Parquet 的 存储模型 主要由行组(Row Group)、列块(Column Chuck)、页(Page)组成
   这个系统为了解决什么问题?为此提供了什么功能? 
    实质:列式存储一个类型包含嵌套结构的数据集。		  
	Header  data index  Footer 
        data: Row-group
                      ColumnChunk  ColumnChunk ColumnChunk 
                       page	 page page page page				  
	        01.存储的对象是一个数据集,而这个数据集往往包含上亿条record,所以我们会进行一次水平切分,把这些record切成多个“分片”,每个分片被称为Row Group
	        02.水平切分之后,就轮到列式存储标志性的垂直切分
		          repetition level 和 definition level。
		        把一个嵌套结构打平以后拆分成多列,其中每一列的数据所构成的分片就被称为Column Chunk
		    03.Page是Parquet文件最小的读取单位,同时也是压缩的单位 
		       Column Chunk,Parquet会进行最后一次水平切分,分解成为一个个的Page。每个Page的默认大小为1m	
		Header的内容很少,只有4个字节,本质是一个magic number,用来指示文件类型
		      “PAR1”代表的是普通的Parquet文件,
			 “PARE”代表的是加密过的Parquet文件。
		Index是Parquet文件的索引块,主要为了支持“谓词下推”(Predicate Pushdown)功能
		     Parquet的索引有两种 一种是Max-Min统计信息,一种是BloomFilter
		Footer是Parquet元数据的大本营,包含了诸如schema,Block的offset和size,Column Chunk的offset和size等所有重要的元数据。
		    另外Footer还承担了整个文件入口的职责
              元数据信息存储在数据之后,包含了所有列块元数据信息的起始位置。
			 读取的时候首先从文件末尾读取文件元数据信息,再在其中找到感兴趣的 Column Chunk 信息,并依次读取
    Block-File Parquet 是以二进制存储数据
	  Parquet 不使用任何分隔符来分隔数据。相反,它依赖于编码和压缩方案来有效地存储和检索数据
	    Parquet 常用的编码技术包括:
           字典编码(dictionary encoding)
		   Run-length encoding(RLE):用来优化具有重复值的列
		   位打包(bit packing):用来优化具有小整数值的列
	    Parquet 中常用的压缩算法有 Snappy、Gzip 和 LZO

序列化阶段

1.使用编程语言内置的序列化机制
2.使用一种广泛支持的、与语言无关的格式,比如 JSON (或者 XML
3.使用Thrift, Protocol Buffers 或 Avro 高效的跨语言数据序列化和代码生成
    Thrift、ProtoBuf 和 Avro 都支持模式演进--用于接口和数据升级
      Avro 和 ProtoBuf 标准化了单一的二进制编码,
	  而 Thrift 则 包含 了各种不同的序列化格式(它称之为“协议”)

Iceberg数据存储格式

Iceberg 是一个分布式列式存储库
   开放式表格式则充当元数据抽象层
1.Iceberg表结构
  Table  Tablet  Snapshot
  Manifest Partition  Block
       表(Table):存储数据的逻辑单元  Tablet(分片  Snapshot(快照):代表一个Table在某个时间点的数据状态,由一份或多份Tablet组成
       Manifest(清单):描述Table状态的元数据,包括Table的Schema(模式)、Partition Spec(分区规范)和Current Snapshot ID(当前快照ID)等信息。
       Partition(分区):将数据按照指定规则分隔成的逻辑单元,
       Block(块):其中存储的是Partition的数据,每个块都有一个唯一的ID,块的大小可以在表级别进行配置
  每一个 snapshot 对应一组 manifest,每一个 manifest 再对应具体的数据文件
2. Iceberg数据文件 是指实际存储表格数据的文件,通常以Parquet格式存储

3. Snapshot 表快照  :记录了表格在某个特定时间点的状态和元数据信息,包括架构、分区规则、数据文件等等。
   data files 数据文件 是实际存储表格数据的文件,通常以Parquet格式存储
   Manifest 清单列表 :是Iceberg表格的所有数据文件的列表,包括数据文件的元数据信息,如大小、数据量、创建时间、分区信息等等。

CyberRT_Recorder和ROS_Bag

Bag 的设计思路
      消息的保存和读取 就涉及到一个广义上的问题序列化和反序列化
	     序列化 :
		 反序列化; 通过消息类型名称(字符串)来生成对象,这在很多语言中叫做反射(reflection
	  何快速的查找-索引
	       把一个包拆分为几个块(Chunk),而chunk中有消息的时间段
		   index data则更进一步,直接索引了不同类型的消息在块中的时间戳和偏移
1.消息的持久化
	01.序列化和反序列化
	02.消息索引
2.	序列化和反序列化	
    Rosbag的序列化和反序列化是自己实现的,ros是单个消息序列化,apollo是整个chunk序列化
	apollo record则采用了protobuf来进行序列化和反序列化
3.消息索引		
4.功能
    Bag header 头信息放在文件首部,
	Chunk info 块的索引和消息元信息的索引都是放在文件的末尾-2个统计record都会保存在文件末尾。	
	Index data

具体示例

Rosbag storage format 
  概念:
      Bag
         header_len/header/data_len/data		  
	     header/Chunk/Connection/Message data/Index data/Chunk info
  Rosbag 文件由许多的record组成,每个record由header和data组成, header和data,还需要保存header_len和data_len
        六种 record
		   Bag header(op=0x03)   Message data(op=0x02)   Index data(op=0x04)  Chunk(op=0x05)  Chunk info(op=0x06)  Connection(op=0x07)
		   
		   Chunk 用来存储链接(connection)和消息数据(message data
 信息头(Headers)。每个记录头包含一系列 name=value 字段 Op 码所有的信息头必须包含Op码字段
    record0  Bag header 主要存放bag包整体的信息,必须是第一个 record	 
    record1:
            Message data 块的结构之一,消息序列化之后以二进制存储,
     		                          通过Connection获取消息格式后进行反序列化
            Connection 块的结构之一,存放信息的格式信息,有了消息的格式,才能解析消息
            Chunk 主要的数据结构,可以被压缩,可以理解为把N个消息打包为一个块(Chunk) 一个块中可能有多种不同的消息
            Chunk info 块的结构之一,主要描述块的信息,例如消息的起始和结束时间等
            Index data 索引数据,因为一个块比较大,索引消息在块中的位置	

    数据结构的读取顺序为:
    
        先解析  Bag header,获取到 index_pos
        然后跳到 index_pos 读取 Connection
        接着读取 Chunk info,上述2个步骤相当于建立起了整个Bag包,块的索引
        接着根据 Chunk info 逐个读取 Chunk ,先解析Chunk,获取压缩类型和数据大小
        接着跳到 Chunk 尾部解析 Index data ,这里是一个消息对应一个 index
        最后根据 index data 实例化消息(通过接口 instantiateBuffer )



CyberRT Record文件由许多的 Section 组成
  Header 
  Section TypeChunkHeader ChunkBoady RecordInfo Index Channel

    Section 0:第一个Section 0HEADER类型。Header中指明了索引区Index的位置
    Section 1Index Data 包含一个SingleIndex类型数组,作为Section的索引,保存了ChannelChunkHeaderChunkBody三种Section的位置和简要数据。
            record.proto中并不存在Chunk这个结构,而是用ChunkHeaderChunkBody两部分来表示。

现代数据湖仓架构

 Apache Iceberg  其定义特性之一是元数据与数据的分离,允许高效的基于快照的隔离和规划。
三个关键组件之上:存储层、开放式表格式和计算引擎
引入了 Iceberg 来支持模式演进、特征回填和并发读写
      最开始反序列化为 Arrow ,后续的操作就完全基于 Arrow 进行,从而降低了序列化和反序列化开销,进一步提升训练速度
	  Parquet 并不支持数据回填
开放式表格式和对象存储正在重新定义组织构建其数据系统		  
    ADS:applicationData Service应用数据服务
    DW   DWD,DWB,DWS  DWD:data warehouse details   DWB:data warehouse base 数据基础层  DWS:data warehouse service 数据服务层
    ODS:Operation Data Store 数据准备区
 基于 Protobuf 定义的半结构化数据

比较典型的就是小文件问题和存储成本问题       
     小文件问题是怎么产生的
	 如何解决小文件问题
	     小文件合并的核心是
		   如何把一个分区下的多个 Parquet 小文件合并成一个,
		   由于 Parquet 格式具有特殊的编码规则,文件内部被划分为多个功能子模块,我们不能直接把 2 个 Parquet 文件首尾拼接进行合并
	借鉴了 Parquet 社区所提供的 merge 工具
	     一类是被压缩和编码后的实际数据,而另一类则是记录了数据是如何被编码和排列的元数据。
	快速合并  相比于 普通合并

参考

 详解Parquet文件格式原理  https://zhuanlan.zhihu.com/p/538163356
  Cyber_数据解析—Apollo_Record&rosbag保存格式 	 
  Rosbag格式分析 https://zhuanlan.zhihu.com/p/494474804
  字节跳动基于Iceberg的海量特征存储实践 https://www.163.com/dy/article/HNF0BBCR0511CUMI.html		  
posted @   辰令  阅读(38)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
· 全程使用 AI 从 0 到 1 写了个小工具
· 从文本到图像:SSE 如何助力 AI 内容实时呈现?(Typescript篇)
历史上的今天:
2021-01-13 Spark开发-Spark中的设计模式_创建型模式大类
2021-01-13 数据开发_工程化UML以及设计模式
点击右上角即可分享
微信分享提示