开发者学堂课程【2020版大数据实战项目之DMP广告系统(第一阶段):kudu原理_存储原理】学习笔记,与课程紧密联系,让用户快速学习知识。
课程地址:https://developer.aliyun.com/learning/course/676/detail/11757
kudu原理_存储原理
内容介绍:
一、tablet 的存储结构
二、tablet 的 Insert 流程
三、tablet 的 update 流程
Kudu 存储原理比较复杂,本节课简化了解 kudu 流程。
一、tablet 存储结构
一个表中的某一个分区就是某一个 tablet,一个 tablet 对应了表真实存放数据的地方,在 Kudu 中,为了同时支持批量分析和随机访问,在整体上的设计一边参考了 Parquet 这样的文件格式的设计,一边参考了 HBase 的设计。
了解 kudu 存储原理就是在了解 tablet 存储原理
tablet 存储数据方式
一个 tablet 在存放数据的时候大致分为两个结构,一个为 MemRowSet, 还有一个为 DiskRowSet。
如上图,红色对应 MemRowSet,橘黄色对应 DiskRowSet。
MemRowSet 这个组件就很像 HBase 中的 Memorystore,是一个缓冲区,数据来了先放缓冲区,保证响应速度。MemRowSet 对应内存,一条数据来了不是直接落盘的而是先存在内存当中,然后存在 MemRowSet 当中,它并不是列存储而是行存储。MemRowSet 组织数组的形式是按行组织的,它并不是列存储而是行存储。在一定的时机下,比如说多长时间数据量到达了多少,这是可配置的。达到这样的阈值以后 MemRowSet 会进行一次溢写,会把这次的数据溢写到DiskRowSet中,DiskRowSet 是一个逻辑单位,DiskRowSet 最终管理的是文件。DiskRowSet 中是按照列来存储的。DiskRowSet 中是由两大类文件进行管理的,第一大类叫基础数据,有的时候也称之为基线数据,还有一类数据叫做变更数据,如果数据没有存储于 DiskRowSet 中,它会先放在 Base 中,在更改某一条数据的时候不是直接修改文件,而是存到类似于基线中。
二、tablet 的 Insert 流程
数据存放到 MemRowSet 中,MemRowSet 会按照每隔两分钟或者达到一个G的数据,达到阈值后整个 MemRowSet会写成 DiskRowSet1,第二次达到阈值了会写成 DiskRowSet2,所以 MemRowSet 是会有一个预写的过程,Insert 的时候把数据插入到 MemRowSet 当中,然后 MemRowSet 预写到 DiskRowSet 当中。
三、tablet 的 update 流程
这个更新流程尤其复杂,首先数据在插入的时候它会有一个确认的过程,会先询问一下MemRowSet 里面是否有这一条数据,然后 K 是否存在,然后询问 DiskRowSet K是否存在,它会先确定在插入一条数据的时候数据的K没有存在,会保证K的唯一性,如果存在就会报错,因为有这一步的存在,在一定程度上会损耗插入性能。在到每一个DiskRowSet 里面来进行判断的时候会使用一个过滤器。
数据在进行更新的时候会确认数据是否存在,在 MemRowSet 没有会再次依次询问 DiskRowSet1,DiskRowSet2。经过这样的过程确定数据在 DiskRowSet2以后,数据会存入 DiskRowSet 当中,DiskRowSet 中存储了三个文件,两个类似的文件,一个 BaseData 是基本数据或者基线数据。在插入流程的时候,把 MemRowSet 写成 DiskRowSet 的时候的数据会存在于基线数据当中,也就是说数据首次插入的时候会直接插入基线数据当中,但数据在更新的时候,不更新基线数据而是先更新 DeltaMemStore,这个数据会先放进 DeltaMemStore 当中,这是一个逻辑单位,每一个DiskRowSet 都会持有一个 DeltaMemStore
接下来 MemRowSet 会在一定阈值下存放到 RedDeltaFile 中,Delta 就是变更数据的意思。数据存放在变更数据以后,它总是要有一种机制是往BaseData中合并的,因为 DeltaMemStore 一次溢写写会生成个 RedoDeltaFile。在满足条件的时候会触发一次溢写生成一个 RedDeltaFile,所以很容易产生大量的小文件,要有一个合并的过程,这个合并分为三类,要了解两类。一种是 miner 另一种是 major。miner 的合并是把多个 RedoDeltaFile 合并成一个RedoDeltaFile。major 是把 RedoDeltaFile 最终合并到基线数据当中,
也就是 BaseData 中存储的是固定的数据,如果数据发生了支化会先存到 DeltaMemStore 中,在满足一定条件的情况下溢写为一个文件,叫做 RedoDeltaFlle,因为会产生很多 RedoDeltaFile 所以要有一个台并的过程,合并有两种类型,一种是合并进入 BaseData 一种只是合并 RedoDeltaFile。
这个数据在更新的时候不是直接写到 BaseData 当中,在插入的时候也不是直接写到 BaseData 当中。在更新的时候是先放入内存当中,在一定条件下溢写为 RedoDeltaFile。RedoDeltaFile 中的操作是可以合并的可修改的,然后多个RedoDeltaFile 进行合并的时候,有一定策略。首先当产生大量小文件的时候,合并成一个大文件效率会更高一些,但是把 RedoDeltaFile 合并进 BaseData 中的开销比较大,所以它会在一定情况下例如 RedoDeltaFile 实在是太大,它才会触发 major 合并,触发一次全局合并到 BaseData 当中,如果没有这些满足条件,即使把 RedoDeltaFile 合并到BaseData 当中,依然没有产生很多性能增益就不会往里面合并了。而产生 miner 合并,miner 合并只是把多个RedoDeltaFile 合并到一起。kudu 如何保证插入速度的同时还满足分析的性能呢,就是在插入的时候优先选内存。
满足分析性能的方式。首先 DiskRowSet 是一个列式存储,并且 DiskRowSet 的数据是经过编码的。BaseDatafile 类似 Parquet 的格式。因此 kudu 既保证了插入的效率也在进行扫描分析的时候因为有 DiskRowSet 的存在性能比较高。