kudu 的基本架构 、存储结构与读写原理

时间:2019-03-19
本文章向大家介绍kudu 的基本架构 、存储结构与读写原理,主要包括kudu 的基本架构 、存储结构与读写原理使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

kudu 的基本架构与存储结构

1. 基本架构

TMaster and TServer

TMaster 主要用来管理元数据,即tablet 和 表的基本信息,监听TServer的状态,TMaster之间通过raft协议进行数据同步

TServer 主要用来管理tablet 。tablet 负责这一张表的某块内容的读写,接受其他tablet leader 传来的同步信息,至于什么是tablet,看下面。

2. 存储结构

kudu的整个存储架构可以看成这样:

一张table 会分成若干个tablet ,每个tablet中会包含的是 MetaData(元信息)和 若干个RowSet,每个RowSet里面包含的是MemRowSet 和若干个DiskRowSet,其中MemRowSet负责的是存储插入和更新的数据,当MemRowSet 写满后(默认是1G或者两分钟),会刷写到DiskRowSet(磁盘中)。

DiskRowSet用于对老数据的mutation(变化)操作,例如对数据更新,合并,删除历史和无用数据,减少查询过程的IO开销。一个DiskRowSet中,包含一个BoomFile、一个Ad_hoc Index、多个UndoFIle、RedoFile、BaseData和DeltaMem

  • BloomFile:根据DiskRowSet中key生成一个bloom filter,用于快速模糊的定位某一个key是否在DiskRowSet中
  • Ad_hoc Index:是主键的索引,用于定位key在DiskRowSet中具体哪个偏移位置
  • BaseData:是MemRowSet flush下来的数据,按照列存储,按照主键有序
  • UndoFile:是BaseData之前的数据历史数据
  • RedoFile:是BaseData之后的mutation记录,可以获得较新的数据
  • DeltaMem:用于在内存中存储mutation记录,先写到内存中,然后写满后flush到磁盘,形成 DeltaFile

MemRowSet的实现方式是 B+树

DiskRowSet的实现方式是二叉平衡树,他的内部数据组织是在内存(DeltaMem)中是B+树,在磁盘中存放在CFile文件中。

DiskRowSet的数据在磁盘上的分布情况:

3. KUDU的存储方式

  1. kudu是一个真正的面像列式存储的数据库,表中的每一个列都是单独存放的;
  2. kudu在建表的时候要求制定每一列的类型,为了给每一列设置制定合适的编码格式,实现更高的数据压缩比,降低IO;
  3. kudu在存储的时候也加入timestamp这个字段,只是并不是用来更新或插入数据使用,而是在scan 的时候可以设置timestamp,查看历史数据;
  4. kudu为了提高批量读取的效率,要求设置主键并且唯一,这样的话,kudu在更新数据的时候就不能向HBASE那样,直接插入一条新的数据就可以了,kudu的选择是将插入和更新操作分开进行;

4. KUDU的读写流程

写流程:

a)插入操作:
  1. 客户端连接到TMaster获取表的相关信息(分区和tablet信息);
  2. 找到负责写请求的tablet 所在的TServer,kudu接受客户端的请求,检查本次写操作是否符合要求;
  3. kudu在 tablet 中所有RowSet 中,查找是否存在与待插入数据相同主键的记录,如果存在,返回错误?否则继续;
  4. 写入操作先被提交到tablet 的预写日志(WAL)上,然后根据Raft 一致性算法取得追随节点的同意后,才会被添加到其中一个tablet 的内存中,插入到MenRowSet中。(因为在MemRowSet 中支持了多版本并发控制(mvcc) ,对最近插入的行(未刷新到磁盘上的新的行)的更新和删除操作将被追加到MemRowSet中的原始行之后以生成Redo 记录的列表)。
  5. kudu在MemRowSet 中写入新数据,在MemRowSet 达到一定大小或者时间限制(1G 或者 120s),MemRowSet 会将数据落盘,生成一个DiskRowSet 用于持久化数据 和 一个 MemRowSet 继续接受新数据的请求。
b)更新操作:
  1. 客户端连接到TMaster获取表的相关信息(分区和tablet信息);

  2. 找到负责写请求的tablet 所在的TServer,kudu接受客户端的请求,检查本次写操作是否符合要求;

  3. 因为待更新的数据可能位于MemRowSet ,也可能位于DiskRowSet 中,所以根据待更新的数据所处的位置,kudu有不同的做法:

    a) 当待更新的数据位于MemRowSet时,找到它所在的行,然后将跟新操作记录在所在行中的一个mutation的链表中,在MemRowSet 数据落地的时候,kudu会将更新合并到base data,并生成undo records 用于查看历史版本的数据和MVCC, undo records 实际上也是以 DeltaFile 的形式存放;

    b)当待跟新的数据位于DiskRowSet时,找到待跟新数据所在的DiskRowSet ,每个DiskRowSet 都会在内存中设置一个DeltaMemStore,将更新操作记录在DeltaMemStore中,在DeltaMemStore达到一定大小时,flush 在磁盘,形成Delta并存放在DeltaFile中。

读流程:

  1. 客户端连接TMaster 获取表的相关信息,包括分区和表中的tablet 的信息;
  2. 客户端找到 tablet 所在的TServer 以后,kudu接受读请求,并记录timestamp(没有显示指定就使用当前时间)信息;
  3. 从内存中读取数据,即是从MemRowSet 和 DeltaRowSet中读取数据,根据timestamp来找到对应的mutation链表;
  4. 从磁盘中读取数据,从metadata文件中使用boom

filter 快速模糊的判断所有候选的RowSet中是否包含此key,然后从DiskRowSet 中读取数据,实际上是根据B+树,判断key 在这些DiskRowSet 中的range 范围内,然后从metadata文件中,获取index来判断rowID 在Data中的偏移,根据读操作中的timestamp 信息判断是否需要对basedata中的数据进行回滚,从而获取数据。

5. KUDU的设计思想是基于HBASE的,那么KUDU和HBASE有什么区别呢?

这个人讲解的很透彻

https://blog.csdn.net/weixin_39478115/article/details/78470294

https://www.cnblogs.com/163yun/p/9014815.html

总结:

​ Kudu通过要求完整的表结构设置,主键的设定,以列式存储作为数据在磁盘上的组织方式,更新和数据分开等技巧,使得Kudu能够实现像HBase一样实现数据的随机读写之外,在HBase不太擅长的批量数据扫描(scan)具有较好的性能。而批量读数据正是olap型应用所关注的重点,正如Kudu官网主页上描述的,Kudu实现的是既可以实现数据的快速插入与实时更新,也可以实现数据的快速分析。Kudu的定位不是取代HBase,而是以降低写的性能为代价,提高了批量读的性能,使其能够实现快速在线分析。


参考来自:https://blog.csdn.net/weixin_39478115/article/details/78470294

参考来自:https://www.cnblogs.com/163yun/p/9014815.html

参考来自:https://blog.csdn.net/lingbo229/article/details/80359987