Kudu 是一个分布式结构化存储系统,由 Cloudera 开源,和 Apache Hadoop 生态紧密结合,共享了很多相同的工具集,可以跑在相同的硬件上,都支持水平扩展。

Kudu 要解决的问题

在了解 Kudu 之前先要了解两个概念 OLTP 和 OLAP:

  • OLTP,online transaction processing ,database modifying system 数据库
  • OLAP,online analytical procession, online database query answering system 线上分析处理

上面两种系统可以简单的理解为一类是需要频繁修改低延迟写入的数据库系统,一种是需要大量连续读分析的高性能分析系统

结构化数据在 Hadoop 生态系统中存储,通常分为两类:

  • 静态数据,二进制存储 HDFS (Avro ),HDFS 为高吞吐连续访问数据场景设计,单独行更新或者随机访问性能差
  • 动态数据,半结构化方式存储(HBase,Cassandra),低延迟读写单独行,对 SQL 分析连续大量读取性能差

两类系统各有自己的优缺点,为了解决各自的问题,一种常用的做法就是 pipeline,比如 Kafka,在数据快速写入到 HBase 的同时通过 pipeline 将其导出给其他分析系统,这时又会遇到一致性等问题。

Kudu 本意上为了解决上面的问题,寻求一个结合点,在一个系统的一份数据中,Kudu 结合了 HDFS 和 HBase 的有点,既能够支持 OLTP 实时读写能力,又能支持 OLAP 的分析能力。Kudu 提供简单的插入,更新和删除,同时通过 table scan 来处理数据分析。

Kudu 解决方案

Kudu 提供 table 概念,每个 table 都有预先定义好的 schema,Schema 定义多个 column,每一个 column 有名字,类型,是否允许 NULL 等。column 组成 primary key。在使用 Kudu 之前用户必须先建立 table,可以通过 DDL 语句添加或者删除 column,但不能删除包含 primary key 的 column。Kudu 的数据模型和关系型数据库非常相似。

Kudu 提供两种一致性模型:snapshot consistency 和 external consistency. snapshot consistency 为默认方式,更好的读性能。external consistency 能够保证写入数据后,任何读取都能读到最新数据。

Kudu 使用 Raft 算法来保证分布式环境下面数据一致性。

Kudu 应用场景

  • 实时分析,数据更新实时体现在分析结果上,比如实时报表
  • 迭代计算,每次计算的结果需要修改数据集
  • 时间序存储,通过 hash partition 可以防止出现热点

架构

Kudu 采用 Master-Slave 形式的中心节点架构,管理节点叫做 Kudu Master,数据节点叫做 Tablet Server。表数据被分割为一个或者多个 Tablet,Tablet 部署在 Tablet Server 提供数据读写服务。

Master 作用

  • 作为 catalog manager,存放 Schema 信息,负责处理建表请求
  • 作为 cluster coordinator,管理 Tablet Server,在 Tablet Server 异常后协调数据重新部署
  • 作为 tablet directory,存放 Tablet 到 Tablet Server 的信息

master 存放集群所有的信息,当 client 需要读写时先请求 master,然后路由到对应 client,但这样 master 一定会成为瓶颈,所以 client 会缓存最近路由,当失效时才会从 master 获取

Kudu 的数据模型类似于关系型数据库,数据存储在结构化的表中。同时 Kudu 是一个分布式的存储引擎,数据最终会分成很多的 tablets 存储在不同的机器上,而表的 partition 则定义了数据会被放到哪些 tablet 中。在同一个 tablet 中,数据根据主键有序排列。

column schema

Kudu column schema :

  • 表包含多个 column,至少需要包含一个 key column(主键)
  • column 必须指定 name 和 type
  • column 还可以指定 encoding 方式和压缩方式

partition

Kudu 支持两种类型的 partition:rang 和 hash

  • range partition 需要指定 N 个 splits key,这些 key 将数据的 key 空间分成 N+1 块,每块都对应与一个 tablet。一个表只可以指定包含一个 range partition
  • hash partition 需要指定根据哪些 column 来进行 hash 分桶,以及分桶的个数 M。一个 table 可以指定多个 hash partition,但 paritions 的 key column 之间不能有重叠

最终 table 的 tablets 数目为 N*M

Kudu 的分区可以按照 Range 和 Hash 方式划分到不同的 Tablet。Hash Partition 数据较均匀的分布在 Tablet 中,原来的数据排序特点被打乱。Range Partition 数据按照用户指定的有序 Primary Key Column 的组合 String 顺序分区。

Tablet 在 Kudu 中被切分更小的单位,RowSets,只存在内存的叫做 MemRowSets,而另一些使用 disk 和 memory 共享存放,叫做 DiskRowSets,任何一行数据只存在一个 RowSets 中。

任何时候,一个 Tablet 仅有一个单独的 MemRowSet 用来保存最近插入的数据,后台线程定期将 MemRowSet 刷入 disk。之前的 MemRowSet 被刷入 disk 后变成 DiskRowSet,空出新的 MemRowSet。

reference