1. 表与schema
Kudu设计是面向结构化存储的,因此Kudu的表需要用户在建表时定义它的Schema信息,这些Schema信息包含:
- 列定义(含类型)
- Primary Key定义(用户指定的若干个列的有序组合)
数据的唯一性,依赖于用户所提供的Primary Key中的Column组合的值的唯一性。
Kudu提供了Alter命令来增删列,但位于Primary Key中的列是不允许删除的。
Kudu当前并不支持二级索引。
从用户角度来看,Kudu是一种存储结构化数据表的存储系统。
在一个Kudu集群中可以定义任意数量的table,每个table都需要预先定义好schema。每个table的列数是确定的,每一列都需要有名字和类型,每个表中可以把其中一列或多列定义为主键。这么看来,Kudu更像关系型数据库,而不是像HBase、Cassandra和MongoDB这些NoSQL数据库。
不过Kudu目前还不能像关系型数据一样支持二级索引。
Kudu使用确定的列类型,而不是类似于NoSQL的“everything is byte”(一切都是字节)。
这可以带来两点好处:
- 确定的列类型使Kudu可以进行类型特有的编码
- 可以提供 SQL-like 元数据给其他上层查询工具使用,比如BI工具。
2. kudu的底层数据模型
Kudu的底层数据文件的存储,未采用HDFS这样的较高抽象层次的分布式文件系统,而是自行开发了一套可基于Table/Tablet/Replica视图级别的底层存储系统
这套实现基于如下的几个设计目标:
-
可提供快速的列式查询
-
可支持快速的随机更新
-
可提供更为稳定的查询性能保障

-
一个Table会被分成若干个tablet,其中Tablet的数量是根据hash或者是range进行设置的
-
一个Tablet中包含MetaData信息和多个RowSet信息,其中MetaData信息是block和block在data中的位置。
-
一个RowSet包含一个MemRowSet和多个DiskRowSet,其中MemRowSet用于存储insert数据和update后的数据,写满后会刷新到磁盘中也就是多个DiskRowSet中,默认是1G刷新一次或者是2分钟。
-
DiskRowSet用于老数据的mutation(改变),比如说数据的更新操作,后台定期对DiskRowSet进行合并操作,删除历史数据和没有的数据,减少查询过程中的IO开销。
-
一个DiskRowSet包含1个BloomFilter,1个Ad_hoc Index,多个UndoFile、RedoFile、BaseData、DeltaMem
- BloomFile:根据一个DiskRowSet中的key生成一个bloom filter,用于快速模糊定位某个key是否在DiskRowSet中存在。
- Ad_hoc Index:是主键的索引,用于定位key在DiskRowSet中的具体哪个偏移位置。
- BaseData是MemRowSet flush下来的数据,按列存储,按主键有序。
- UndoFile是基于BaseData之前时间的历史数据,通过在BaseData上apply UndoFile中的记录,可以获得历史数据。
- RedoFile是基于BaseData之后时间的变更(mutation)记录,通过在BaseData上apply RedoFile中的记录,可获得较新的数据。
- DeltaMem用于DiskRowSet中数据的变更mutation,先写到内存中,写满后flush到磁盘形成RedoFile。


本文深入剖析Kudu数据库的设计理念,包括表结构与Schema定义、底层数据模型、读写更新原理及优化策略等内容。此外,还详细介绍了Kudu的使用限制与最佳实践。
最低0.47元/天 解锁文章
895





