【遇见Doris】Apache Doris (incubating) 0.12.0版本预览



Doris线下沙龙完美收官!本次沙龙邀请了来自百度、美团、京东的技术大牛带来实战分享。了解更多详情请关注Doris官方公众号,嘉宾分享回顾会陆续放出。公众号后台回复“1222”立即get现场录像及嘉宾PPT。



今天带来的是Doris主创团队的黄康平带来的Apache Doris (incubating) 0.12.0版本预览。  

What's Doris


【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第1张图片

Doris是一款基于Mesa模型的MPP、列式数据仓库,具有兼容MySQL协议,方便用户使用,在线运维等特点。
  Doris的架构中主要包含两个模块:FE和BE。FE模块主要用来进行元数据管理、事务管理、查询规划和任务调度,Doris支持多个FE,实现了在线的高可用;BE负责数据的存储、查询计划的执行。BE能够按需进行动态的伸缩,在线扩展,方便部署和运维。   我们已经发布了0.11.0版本,在下一个版本0.12.0中,主要包含Segment V2这个新的功能,用新的存储格式来解决原来的一些问题。


What's Segment


Doris之前的存储格式被称为Segment V1,如下图所示,BE中的存储引擎会将数据存成Segment文件。Segment V1是一种跟orcfile类似的存储文件,实现了纯列式的存储,并且加上Short Key Index,在其中还支持了Zone Map/Bloom Filter索引,并支持了谓词下推和向量化执行等优化。

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第2张图片


但V1版本的Segment中,存在以下问题
  • 按照字节流的方式进行读取和解析,效率不高

  • 存在随机Seek的问题,在解析流的时候,需要先读8字节的头部信息,然后在读取一个压缩块信息

  • String类型按照Plain方式存储,效率比较低

  • 对Cache不友好,只有Column Stream粒度的Cache

  • 只缓存压缩之后的数据,对数据的多次读取,会解压多次数据

  • 难以扩展新的索引,比如Bitmap索引

  • 读取的逻辑比较复杂,难以理解




Segment V2,存储效率及性能提升

 
由于Segment V1的种种问题,Doris设计了Segment V2以提升存储的效率和性能。

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第3张图片


如上图所示,Segment V2也是一种纯列存的存储格式,分为三个部分:数据区,索引区和元数据区。数据是按照P age为粒度进行组织的,能够解决原来按照字节处理的问题。Page是编码和压缩的单位,并且我们在Page粒度实现了Cache,Cache解压缩之后的数据,对同一份数据的反复读取,只会解压缩一遍。  

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第4张图片


并且,我们实现了原来的Short Key、Bloom Filter、Zone Map的索引,同时我们增加了行号索引和Bitmap索引。在优化方面,我们实现了谓词下推和向量化执行,延迟物化的优化目前也在开发之中。    Segment V2——Page 


【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第5张图片

首先来介绍一下最基本的概念:Page。在V2上,Page是编码和压缩的基本单位,而且索引的粒度基本也都是Page的,也是Cache的基本单位。
  Page的格式分为头部信息,数据信息和Checksum。其中头部信息包含Page的第一行行号及Page中包含的行数。如果C olumn是Nullable,则还会存储NullBitmap的长度和NullBitmap信息。Data就是经过编码和压缩的数据信息。最后会在Page的末位存储Page的Checksum信息,用于校验数据的正确性。    Segment V2——Index Page   

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第6张图片

除了Data Page,我们还引入了另外一个概念:Index Page,用来存储索引信息,支持行号索引和Value索引,主要用于带索引数据列的实现,比如Bitmap索引和Bloom Filter索引。具体内容就是存储行号到Page Pointer的信息或者Value到Page Pointer的信息。
   Segment V2——Index     

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第7张图片

上图是V2中索引的实现大概示意图。目前我们实现了Shortkey索引、行号索引、Zonemap索引、Bloomfilter索引和Bitmap索引,其中Short Key索引是构建在Row Block粒度的;行号、Zonemap、Bloomfilter索引是构建在Page粒度的,Bitmap索引是在行号上的。我们实现行号索引,能够比较简单的将各种索引组合在一起,以提升查询的性能;并且能够方便扩展新的二级索引。
   Segment V2——Write 


【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第8张图片


下面大概介绍一下V2的写入流程:
  • Add Row,数据是一行一行添加在Segment中,但是是保存在内存中

  • 当Segment文件大小达到阈值,就会将Segment文件刷到磁盘,整个刷数据的顺序就是按照前面Segment图中描述的顺序写入的,先写数据,然后写索引,然后再写Footer

  • 如果Segment文件大小没有满,就会将数据添加到当前的Page中,进行编码;如果Page满了就会进行压缩,将Page添加Page List中,保存在内存中


整个过程具有以下的特点:
  • Segment文件是缓存在内存中,等到阈值时一次性写入到磁盘。一方面是为了实现控制文件的组织结构,另外一方面是为了顺序I/O

  • Segment Size阈值可以配置

  • 各个列的同一种类型的索引是写到一起的


 Segment V2——Read 


【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第9张图片


下面讲一下Segment读取的流程
  • 在Doris中,数据是按照Batch方式读取的,不是一条一条读取。调用next_batch读取下一个批次的数据,Batch大小是1024行,在调用这个接口的时候会传入Predicate信息。

  • 获取要读取的行号范围,该过程会利用Predicate信息和索引信息,过滤掉一些不需要的行号范围

  • 将行号范围映射到各个列的Page Ids范围

  • 在各个列中查询该列的Page是否被缓存,如果缓存在内存中,就Decode Page信息,填充到返回结果的Batch内存中

  • 如果该列的该Page没有被缓存,就会进行I/O操作,将Page加载到内存中,进行解压缩,然后加到Page Cache中,然后Decode该Page的数据,填充到Batch中

  • 最后会拼装各个列的数据,进行向量化执行Predicate过滤,之后返回给调用方。


   Segment V2——PredicatePushdown 


【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第10张图片

这里大概介绍一下,在读取过程中谓词下推是怎么实现的。 在V2中,暂时支持的Predicate还比较简单,后续打算会进行扩展。 下图是一个例子,如果用户查询age = 35 and phone in 的语句,那么在Zone Map和Bloomfilter索引过滤之后,就会只剩下红框中的数据需要读取,降低读取的数据量。

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第11张图片

     Segment V2——Encoding& Compression Framework    在V2中,为了实现高效的在Page粒度的编码,我们目前已经支持了多种方式的编码:
  • Run Length Encoding

  • Bitshuffle encoding

  • Plain encoding

  • Frame of reference encoding

  • Dict encoding

  • Prefix encoding

未来也会在此基础上增加新的编码,如PageBuilder/PageDecoder以及EncodingInfo Factory
  现在也支持了多种压缩的框架:
  • Zlib

  • Snappy

  • Lz4

  • lz4f

未来也会支持更多压缩框架,如BlockCompressionCodec,Compression Codec Factory等     Segment V2——String Encoding 

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第12张图片

相对V1做了字典压缩的功能,原有V1版本中用的是Plain Encoding的方式,效率比较低。Dict Encoding主要是用来解决低基列的字符串类型的存储。最终实现的例子如下:会建一份词典,并存储词典对应的编码来对应原始数据。同时Prefix Encoding也已经实现了,后续会进行一些优化。
 

性能数据


【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第13张图片


下面是一些性能测试。 用随机构造的不同基数下的数据进行测试,V2的词典压缩效果在低基数要明显优于v1。 用TPCH的Part表进行测试,效果会更加明。 同时,从业务数据上看,词典压缩效果也比较明显,能够节省达50%的存储空间。

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第14张图片

数据导入在不同的情况下也有不同程度的提升。


【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第15张图片


我们使用TPCDS catalog_sales进行了测试,从上面的数据来看,目前相对于V1,V2的性能有所提升,但是有进一步的优化空间,我们正在努力进一步提升V2的效率和性能。



Road Map



【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第16张图片


未来Doris的主要工作包括:继续优化Segment V2,并在下一个版本中发布Bitmap索引的功能,并持续探索复杂类型的支持和云原生的设计。

 

欢迎扫码关注:

【遇见Doris】Apache Doris (incubating) 0.12.0版本预览_第17张图片

Apache Doris(incubating)官方公众号


相关链接:

Apache Doris官方网站:

http://doris.incubator.apache.org

Apache Doris Github:

https://github.com/apache/incubator-doris

Apache Doris Wiki:

https://github.com/apache/incubator-doris/wiki

Apache Doris 开发者邮件组:

[email protected]

本文分享自微信公众号 - ApacheDoris(gh_80d448709a68)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。

你可能感兴趣的:(运维,大数据,数据库,python,java)