1、Apache Kudu介绍及架构、工作原理、两种部署方式、使用限制详解

Apache Kudu 系列文章

1、Apache Kudu介绍及架构、工作原理、两种部署方式、使用限制详解
2、Apache Kudu-java api操作kudu详细示例以及kudu的三种实现示例
3、Apache Kudu集成impala(shell和java操作)的详细操作



本文简单的介绍了kudu的基本情况、架构、部署、原理和使用注意事项。
本文依赖CDH环境好用。
本分分为5个部分,即介绍、架构、安装部署、工作原理和注意事项。

一、kudu介绍

1、出现背景介绍

在KUDU之前,大数据主要以两种方式存储;

  • 静态数据:以 HDFS 引擎作为存储引擎,适用于高吞吐量的离线大数据分析场景。这类存储的局限性是数据无法进行随机的读写。
  • 动态数据:以 HBase、Cassandra 作为存储引擎,适用于大数据随机读写场景。局限性是批量读取吞吐量远不如 HDFS,不适用于批量数据分析的场景。

这两种数据在存储方式上完全不同,进而导致使用场景完全不同,但在真实的场景中,边界可能没有那么清晰,面对既需要随机读写,又需要批量分析的大数据场景,该如何选择呢?
这个场景中,单种存储引擎无法满足业务需求,我们需要通过多种大数据工具组合来满足这一需求,如下图所示:
在这里插入图片描述
如上图所示,数据实时写入 HBase,实时的数据更新也在 HBase 完成,为了应对 OLAP 需求,定时将 HBase 数据写成静态的文件(如:Parquet)导入到 OLAP 引擎(如:Impala、hive)。这一架构能满足既需要随机读写,又可以支持 OLAP 分析的场景,但他有如下缺点:

  • 架构复杂。从架构上看,数据在HBase、消息队列、HDFS 间流转,涉及环节太多,运维成本很高。并且每个环节需要保证高可用,都需要维护多个副本,存储空间也有一定的浪费。最后数据在多个系统上,对数据安全策略、监控等都提出了挑战。
  • 时效性低。数据从HBase导出成静态文件是周期性的,一般这个周期是一天(或一小时),在时效性上不是很高。
  • 难以应对后续的更新。真实场景中,总会有数据是延迟到达的。如果这些数据之前已经从HBase导出到HDFS,新到的变更数据就难以处理了,一个方案是把原有数据应用上新的变更后重写一遍,但这代价又很高。

为了解决上述架构的这些问题,KUDU应运而生。KUDU的定位是Fast Analytics on Fast Data,是一个既支持随机读写、又支持 OLAP 分析的大数据存储引擎。
在这里插入图片描述
从上图可以看出,KUDU 是一个折中的产品,平衡了HDFS 和 HBase随机读写和批量分析的性能。

2、kudu是什么

Apache Kudu是由Cloudera开源的存储引擎,可以同时提供低延迟的随机读写和高效的数据分析能力。它是一个融合HDFS和HBase的功能的新组件,具备介于两者之间的新存储组件。
Kudu支持水平扩展,并且与Cloudera Impala和Apache Spark等当前流行的大数据查询和分析工具结合紧密。
在这里插入图片描述

3、kudu应用场景

  • 适用于那些既有随机访问,也有批量数据扫描的复合场景
  • 高计算量的场景
  • 使用了高性能的存储设备,包括使用更多的内存
  • 支持数据更新,避免数据反复迁移
  • 支持跨地域的实时数据备份和查询

二、Apache Kudu架构

与HDFS和HBase相似,Kudu使用单个的Master节点,用来管理集群的元数据,并且使用任意数量的Tablet Server(类似HBase中的RegionServer角色)节点用来存储实际数据。可以部署多个Master节点来提高容错性。
在这里插入图片描述

1、Table

表(Table)是数据库中用来存储数据的对象,是有结构的数据集合。kudu中的表具有schema和全局有序的primary key(主键)。kudu中一个table会被水平分成多个被称之为tablet的片段。

2、Tablet

  • 一个 tablet 是一张 table连续的片段,tablet是kudu表的水平分区,类似于HBase的region。每个tablet存储着一定连续range的数据(key),且tablet两两间的range不会重叠。一张表的所有tablet包含了这张表的所有key空间
  • tablet 会冗余存储。放置到多个 tablet server上,并且在任何给定的时间点,其中一个副本被认为是leader tablet,其余的被认之为follower tablet。每个tablet都可以进行数据的读请求,但只有Leader tablet负责写数据请求

3、Tablet Server

  • tablet server负责数据存储,并提供数据读写服务
  • 一个 tablet server 存储了table表的tablet,向kudu client 提供读取数据服务。对于给定的 tablet,一个tablet server 充当 leader,其他 tablet server 充当该 tablet 的 follower 副本
  • 只有 leader服务写请求,然而 leader 或 followers 为每个服务提供读请求 。一个 tablet server 可以服务多个 tablets ,并且一个 tablet 可以被多个 tablet servers 服务着

4、Master Server

集群中负责集群管理、元数据管理等功能。

三、Apache Kudu安装

此处安装提供两种安装方式,一种是在CDH中直接安装,一种是下载文件安装。

1、CDH方式安装kudu

cdh安装详见CDH(Cloudera DataHub 6.2.1)部署(centos6、7)、常用组件(zookeeper、hive、hdfs、yarn、oozie、hue、impala、hbase)安装及验证的cdh部署。

1)、确保服务器时间同步正常

[root@server8 ~]# ntpstat
synchronised to NTP server (192.168.10.180) at stratum 4
   time correct to within 295 ms
   polling server every 128 s

2)、安装kudu

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2、下载安装

1)、节点服务配置

在这里插入图片描述

2)、本地yum源配置

1、cdh包下载

现在下载可能需要cdh账号
http://archive.cloudera.com/cdh5/repo-as-tarball/5.14.0/cdh5.14.0-centos6.tar.gz
下载cdh5.14.0-centos6.tar.gz文件,大小约5G左右

2、上传解压

把压缩文件上传其中某一台服务器,作为本地yum源服务器。

cd /usr/local/bigdata
tar -zxvf cdh5.14.0-centos6.tar.gz
3、制作本地yum源

本步骤涉及的地方比较多,如果出现异常详见本节第1部分关于CDH方式安装中的安装CDH。
使用Apache Server来充当web服务器,使得其他机器可以通过http方式读取本地制作的yum源软件。这里我们选用第三台机器(server-3)作为yum源。
执行以下命令安装apache Server:

yum -y install httpd
service httpd start
#然后创建新增一个解析本地yum源的配置文件 
cd /etc/yum.repos.d
vim localimp.repo
[localimp]
name=localimp
baseurl=http://server-3/cdh5.14.0
gpgcheck=0
enabled=1
4、创建连接、启动httpd
ln -s /usr/local/bigdata/cdh/5.14.0 /var/www/html/cdh5.14.0

访问http://server-3/cdh5.14.0验证是否成功
在这里插入图片描述
如果出现访问异常:You don’t have permission to access /cdh5.14.0/ on this server,则需要关闭Selinux服务

#临时关闭  执行命令
setenforce 0
#永久关闭    
vim /etc/sysconfig/selinux
SELINUX=enforcing 改为 SELINUX=disabled

#重启服务reboot

#将server-3上制作好的localimp配置文件发放到所有需要kudu的节点上去
scp /etc/yum.repos.d/localimp.repo server-1:/etc/yum.repos.d
scp /etc/yum.repos.d/localimp.repo server-2:/etc/yum.repos.d

3、安装kudu

使用yum命令,在不同的服务器下载对应的服务
在这里插入图片描述
命令说明

yum install kudu # Kudu的基本包 
yum install kudu-master # KuduMaster 
yum install kudu-tserver # KuduTserver 
yum install kudu-client0 #Kudu C ++客户端共享库 
yum install kudu-client-devel # Kudu C ++客户端共享库 SDK

在这里插入图片描述

4、kudu节点配置

需要在所有节点的/etc/kudu/conf目录下有两个文件:master.gflagfile和tserver.gflagfile。

1)、修改master.gflagfile

# cat /etc/kudu/conf/master.gflagfile
# Do not modify these two lines. If you wish to change these variables,
# modify them in /etc/default/kudu-master.
--fromenv=rpc_bind_addresses
--fromenv=log_dir
--fs_wal_dir=/usr/local/bigdata/kudu/master
--fs_data_dirs=/usr/local/bigdata/kudu/master
--master_addresses=server-1:7051,server-2:7051,server-3:7051

2)、修改tserver.gflagfile

# Do not modify these two lines. If you wish to change these variables,
# modify them in /etc/default/kudu-tserver.
--fromenv=rpc_bind_addresses
--fromenv=log_dir
--fs_wal_dir=/usr/local/bigdata/kudu/tserver
--fs_data_dirs=/usr/local/bigdata/kudu/tserver
--tserver_master_addrs=server-1:7051,server-2:7051,server-3:7051

3)、修改 /etc/default/kudu-master

export FLAGS_log_dir=/var/log/kudu
#每台机器的master地址要与主机名一致,这里是在node-1上
export FLAGS_rpc_bind_addresses=server-1:7051

4)、修改 /etc/default/kudu-tserver

export FLAGS_log_dir=/var/log/kudu
#每台机器的tserver地址要与主机名一致,这里是在server-1上
export FLAGS_rpc_bind_addresses=server-1:7050
kudu默认用户就是KUDU,所以需要将/usr/local/bigdata/kudu权限修改成kudu:
mkdir /usr/local/bigdata/kudu
chown -R kudu:kudu /usr/local/bigdata/kudu

(如果使用的是普通的用户,那么最好配置sudo权限)/etc/sudoers文件中添加:
在这里插入图片描述

5、kudu集群启动和关闭

1)、安装ntp服务

启动的时候要注意时间同步

#安装ntp服务
yum -y install ntp
#设置开机启动
service ntpd start 
chkconfig ntpd on
#可以在每台服务器执行
/etc/init.d/ntpd restart

2)、启动kudu集群

在每台服务器上都执行下面脚本

service kudu-master start
service kudu-tserver start

如果启动失败,请前往日志目录下查看输出日志信息进行排错。

3)、关闭kudu集群

在每台服务器上都执行下面脚本

service kudu-master stop
service kudu-tserver stop

6、kudu web UI

kudu的web管理界面。http://master主机名:8051
在这里插入图片描述

1)、Master的web地址

可以查看每个机器上master相关信息。http://server-1:8051/masters
示例图片如下
在这里插入图片描述

2)、TServer的web地址

http://server-1:8051/tablet-servers
示例图片如下
在这里插入图片描述

7、安装注意事项

1)、给普通用户授予sudo出错

sudo: /etc/sudoers is world writable
#解决方式:
pkexec chmod 555 /etc/sudoers

2)、启动kudu的时候报错

Failed to start Kudu Master Server. Return value: 1 [FAILED]
#去日志文件中查看:
Service unavailable: Cannot initialize clock: Error reading clock. Clock considered
unsynchronized
#解决:
¥第一步:首先检查是否有安装ntp:如果没有安装则使用以下命令安装:
yum -y install ntp
#第二步:设置随机启动:
service ntpd start
chkconfig ntpd on

3)、启动过程中报错

Invalid argument: Unable to initialize catalog manager: Failed to initialize systables
async: on-disk master list
#解决:
(1):停掉master和tserver
(2):删除掉之前所有的/usr/local/bigdata/kudu/master/*和/usr/local/bigdata/kudu/tserver/*

4)、启动过程中报错

error: Could not create new FS layout: unable to create file system roots: unable to
write instance metadata: Call to mkstemp() failed on name template
/usr/local/bigdata/kudu/master/instance.kudutmp.XXXXXX: Permission denied (error 13)
#这是因为kudu默认使用kudu权限进行执行,可能遇到文件夹的权限不一致情况,更改文件夹权限即可

四、Apache Kudu工作原理

1、table与schema

Kudu设计是面向结构化存储的,因此,Kudu的表需要用户在建表时定义它的Schema信息,这些Schema信息包含:列定义(含类型),Primary Key定义(用户指定的若干个列的有序组合)。
数据的唯一性,依赖于用户所提供的Primary Key中的Column组合的值的唯一性。Kudu提供了Alter命令来增删列,但位于Primary Key中的列是不允许删除的。

从用户角度来看,Kudu是一种存储结构化数据表的存储系统。在一个Kudu集群中可以定义任意数量的table,每个table都需要预先定义好schema。每个table的列数是确定的,每一列都需要有名字和类型,每个表中可以把其中一列或多列定义为主键。Kudu更像关系型数据库,而不是像HBase、Cassandra和MongoDB这些NoSQL数据库。Kudu目前还不能像关系型数据一样支持二级索引。

Kudu使用确定的列类型,而不是类似于NoSQL的“everything is byte”。带来好处:确定的列类型使Kudu可以进行类型特有的编码,可以提供元数据给其他上层查询工具。

2、kudu数据模型

Kudu的底层数据文件的存储,未采用HDFS这样的较高抽象层次的分布式文件系统,而是自行开发了一套可基于Table/Tablet/Replica视图级别的底层存储系统。
这套实现基于如下的几个设计目标:

  • 可提供快速的列式查询

  • 可支持快速的随机更新

  • 可提供更为稳定的查询性能保障
    在这里插入图片描述

  • 一张table会分成若干个tablet,每个tablet包括MetaData元信息及若干个RowSet。

  • RowSet包含一个MemRowSet及若干个DiskRowSet,DiskRowSet中包含一个BloomFile、Ad_hoc Index、BaseData、DeltaMem及若干个RedoFile和UndoFile。

  • MemRowSet用于新数据insert及已在MemRowSet中的数据的更新,一个MemRowSet写满后会将数据刷到磁盘形成若干个DiskRowSet。默认是1G或者或者120S。

  • DiskRowSet用于老数据的变更,后台定期对DiskRowSet做compaction,以删除没用的数据及合并历史数据,减少查询过程中的IO开销。

  • BloomFile根据一个DiskRowSet中的key生成一个bloom filter,用于快速模糊定位某个key是否在DiskRowSet中。

  • Ad_hocIndex是主键的索引,用于定位key在DiskRowSet中的具体哪个偏移位置。

  • BaseData是MemRowSet flush下来的数据,按列存储,按主键有序。

  • UndoFile是基于BaseData之前时间的历史数据,通过在BaseData上apply UndoFile中的记录,可以获得历史数据。

  • RedoFile是基于BaseData之后时间的变更记录,通过在BaseData上apply RedoFile中的记录,可获得较新的数据。

  • DeltaMem用于DiskRowSet中数据的变更,先写到内存中,写满后flush到磁盘形成RedoFile。

REDO与UNDO与关系型数据库中的REDO与UNDO日志类似(在关系型数据库中,REDO日志记录了更新后的数据,可以用来恢复尚未写入Data File的已成功事务更新的数据。而UNDO日志用来记录事务更新之前的数据,可以用来在事务失败时进行回滚)
在这里插入图片描述
MemRowSets可以对比理解成HBase中的MemStore,而DiskRowSets可理解成HBase中的HFile。

MemRowSets中的数据被Flush到磁盘之后,形成DiskRowSets。 DisRowSets中的数据,按照32MB大小为单位,按序划分为一个个的DiskRowSet。 DiskRowSet中的数据按照Column进行组织,与Parquet类似。

这是Kudu可支持一些分析性查询的基础。每一个Column的数据被存储在一个相邻的数据区域,而这个数据区域进一步被细分成一个个的小的Page单元,与HBase File中的Block类似,对每一个Column Page可采用一些Encoding算法,以及一些通用的Compression算法。 既然可对Column Page可采用Encoding以及Compression算法,那么,对单条记录的更改就会比较困难了。

前面提到了Kudu可支持单条记录级别的更新/删除,是如何做到的?

与HBase类似,也是通过增加一条新的记录来描述这次更新/删除操作的。DiskRowSet是不可修改了,那么 KUDU 要如何应对数据的更新呢?在KUDU中,把DiskRowSet分为了两部分:base data、delta stores。base data 负责存储基础数据,delta stores负责存储 base data 中的变更数据。

在这里插入图片描述
如上图所示,数据从 MemRowSet 刷到磁盘后就形成了一份 DiskRowSet(只包含 base data),每份 DiskRowSet 在内存中都会有一个对应的 DeltaMemStore,负责记录此 DiskRowSet 后续的数据变更(更新、删除)。DeltaMemStore 内部维护一个 B-树索引,映射到每个 row_offset 对应的数据变更。DeltaMemStore 数据增长到一定程度后转化成二进制文件存储到磁盘,形成一个 DeltaFile,随着 base data 对应数据的不断变更,DeltaFile 逐渐增长。

3、tablet工作过程

当创建Kudu客户端时,其会从主服务器上获取tablet位置信息,然后直接与服务于该tablet的服务器进行交互。
为了优化读取和写入路径,客户端将保留该信息的本地缓存,以防止他们在每个请求时需要查询主机的tablet位置信息。随着时间的推移,客户端的缓存可能会变得过时,并且当写入被发送到不再是tablet领导者的tablet服务器时,则将被拒绝。然后客户端将通过查询主服务器发现新领导者的位置来更新其缓存。如下图所示
在这里插入图片描述

4、kudu写流程

当Client请求写数据时,先根据主键从Master Server中获取要访问的目标Tablets,然后到依次对应的Tablet获取数据。

因为KUDU表存在主键约束,所以需要进行主键是否已经存在的判断,这里就涉及到之前说的索引结构对读写的优化了。一个Tablet中存在很多个RowSets,为了提升性能,我们要尽可能地减少要扫描的RowSets数量。

首先,先通过每个 RowSet 中记录的主键的(最大最小)范围,过滤掉一批不存在目标主键的RowSets,然后在根据RowSet中的布隆过滤器,过滤掉确定不存在目标主键的 RowSets,最后再通过RowSets中的 B-树索引,精确定位目标主键是否存在。

如果主键已经存在,则报错(主键重复),否则就进行写数据(写 MemRowSet)。
在这里插入图片描述

5、kudu读流程

数据读取过程是先根据要扫描数据的主键范围,定位到目标的Tablets,然后读取Tablets 中的RowSets。

在读取每个RowSet时,先根据主键过滤要scan范围,然后加载范围内的base data,再找到对应的delta stores,应用所有变更,最后union上MemRowSet中的内容,返回数据给Client。
在这里插入图片描述

6、kudu更新流程

数据更新的核心是定位到待更新数据的位置,等定位到具体位置后,然后将变更写到对应的delta store 中。
在这里插入图片描述

五、Kudu使用限制

1、Kudu主键的限制

  • 表创建后主键不可更改
  • 一行对应的主键内容不可以被Update操作修改。要修改一行的主键值,需要删除并新增一行新数据,并且该操作无法保持原子性
  • 主键的类型不支持DOUBLE、FLOAT、BOOL,并且主键必须是非空的(NOT NULL)
  • 自动生成的主键是不支持的
  • 每行对应的主键存储单元(CELL)最大为16KB

2、Kudu列的限制

  • MySQL中的部分数据类型,如DECIMAL, CHAR, VARCHAR, DATE, ARRAY等不支持
  • 数据类型以及是否可为空等列属性不支持修改
  • 一张表最多有300列

3、Kudu表的限制

  • 表的备份数必须为奇数,最大为7
  • 备份数在设置后不可修改

4、Kudu单元(Cells)的限制

  • 单元对应的数据最大为64KB,并且是在压缩前

5、Kudu分片的限制

  • 分片只支持手动指定,自动分片不支持
  • 分片设定不支持修改,修改分片设定需要”建新表-导数据-删老表”操作
  • 丢掉多数备份的Tablets需要手动修复

6、Kudu容量限制

  • 建议tablet servers的最大数量为100
  • 建议masters的最大数量为3
  • 建议每个tablet server存储的数据最大为4T(此处存疑,为何会有4T这么小的限制?)
  • 每个tablet server存储的tablets数量建议在1000以内
  • 每个表分片后的tablets存储在单个tablet server的最大数量为60

7、Kudu其他使用限制

  • Kudu被设计为分析的用途,每行对应的数据太大可能会碰到一些问题
  • 主键有索引,不支持二级索引(Secondary indexes)
  • 多行的事务操作不支持
  • 关系型数据的一些功能,如外键,不支持
  • 列和表的名字强制为UTF-8编码,并且最大256字节
  • 删除一列并不会马上释放空间,需要执行Compaction操作,但是Compaction操作不支持手动执行
  • 删除表的操作会立刻释放空间

以上,简单的介绍了kudu的基本情况、架构、部署、原理和使用注意事项,后续将介绍其与impala和java api的使用。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

一瓢一瓢的饮 alanchanchn

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值