Kudu系列-基础
Apache Kudu 支持Insert/Update/Delete 等写操作(Kudu 随机写效率也很高, 实测对一个窄表做全字段update, 其速度达到了Insert速度的88%, 而vertica的update效率比insert差很多), Kudu 表文件是列式数据格式(和Parquet格式类似), 所以Kudu是一个支持记录修改的分析型系统, Kudu+Impala组合起来就是一个很有竞争力的MPP架构.
SQL on kudu 不同与SQL on hadoop, Hive 和其他 SQL on hadoop都是read on schema方式, 而 impala on kudu 是 write on scheme(这和普通的DB一样), 这就导致了两个不同点:
1. impala 插入kudu 表, 将根据记录的分区键写到对应的kudu tablet中, 而SQL on hadoop无法精细控制记录写入到哪个data node中.
2. 不合法的记录将无法写入到kudu表, 而使用hive 却能写入到hdfs文件中, 比如一个int字段,我们无法将'abc'这样的字符串写入到kudu表; 但使用hive可以写入, 只是读取时该字段被处理为null.
3. 因为kudu知道一个记存放在哪里(通过主键), 如果我们的Select/delete/update语句能利用上主键(聚集主键), 执行效率比较高. 如果利用不上的话, 效率就差了.
Apache Kudu 虽然是Cloudera贡献的, 但并没有包含在CDH中, 需要单独安装, 因为 Kudu 其实并不依赖 Hadoop 运行环境, 文件并不是存放在hdfs上. 但如果搭配Impala使用, 就需要Hadoop环境(impala以来Hive).
---==============================
安装 kudu
---==============================
在CDH 5.5.10 VM版本以上(impala 2.7版以上), 使用下面命令安装kudu软件.
$ sudo yum install kudu # Base Kudu files
$ sudo yum install kudu-master # Kudu master init.d service script and default configuration
$ sudo yum install kudu-tserver # Kudu tablet server init.d service script and default configuration
$ sudo yum install kudu-client0 # Kudu C++ client shared library
$ sudo yum install kudu-client-devel # Kudu C++ client SDK
kudu安装包会自动在Linux alternatives 数据库下创建 kudu-conf 入口,
sudo alternatives --display kudu-conf
手动启动kudu
$ sudo service kudu-master start
$ sudo service kudu-tserver start
自动启动设置
$ sudo chkconfig kudu-master on # RHEL / CentOS / SLES
$ sudo chkconfig kudu-tserver on # RHEL / CentOS / SLES
---==============================
主键
---==============================
主键: 每个表都必须有一个Unique主键, 主键可以是单独字段也可以由多个字段组成, 但主键中的每个字段都应该是non null, 而且不能是boolean和浮点类型字段. 重复的PK的记录将无法Insert到Kudu表中, 而且主键值是不能修改的. Kudu主键是聚集索引, 也就是说每个tablet中的记录将按照主键排序存储, 在scan时候能利用这些排序加快记录查找.
通过Kudu API更新/删除记录必须提供主键, 通过Impala查询引擎没有这个限制.
注意:
1. 在建表DDL语句中, 主键要放到字段清单的前段.
2. 除了主键, kudu不支持建立其他索引
3. 主键值不能被update
4. insert语句中, 主键名是大小写敏感的, 其他语句大小写不敏感. [怀疑是kudu的bug]
主键的选择原则:
1. 选择性强的字段(比如id 类) 应该放在PK清单最前面, 这个规则对查询性能影响最大.
2. PK清单中只加必要的unique字段, 越少越好.
3. 如果查询针对PK中所有字段都加了条件, 其性能是最优的. 但只要有一个PK字段未加条件, 相当于完全用不上PK索引,性能就很差.
我专门又写了个文章讨论主键选择策略, http://www.cnblogs.com/harrychinese/p/kdu_pk.html
---==============================
分区
---==============================
分区键: Kudu要求分区键必须属于主键. 如果没有显式指定分区键的时候, 主键就是分区键, 即按照主键Hash分区, 分区数量为1个, 而且只有缺省方式才能建立1 个 partition, 专门用语句指定的话, partition数量必须大于1.
既然分区键一定属于主键, 所以Kudu表的主键最好除了包含业务主键, 最好再加上也写常用的查询字段, 比如时间字段和userId这样的字段, 这样能更好地设计分区策略.
分区数如何确定:
Kudu每个表在tablet server上的切片数量不能大于60个(含replica), 按照20个tablet server算, 一个表最多400个partition, Impala的限制是100K个, Vertica的限制是512个.
通常增加分区(切片)数, 对于写入是有利的, 但对于读取可能有利有弊(会提升读取的并行度, 但会增加扫描切片的数量).
总的原则是: 切片数不要大于集群中CPU的总core数, 如果切片数超过CPU core数, 性能反倒会下降.
具体为:
1. Fact表, 切片数<=集群中CPU的总core数, 并是机器数量的倍数, 以防止数据倾斜.
2. Dim表, 切片数应<<集群中CPU的总core数, 保证每个tablet的size至少1GB.
分区方法:
Kudu分区方法只能在建表的时候确定, 所以确定分区方法一定要仔细考虑. Kudu支持Hash和Range分区, 而且支持使用Hash+Range作分区.
1. hash 分区: 写入压力较大的表, 比如发帖表, 按照帖子自增Id作Hash分区, 可以有效地将写压力分摊到各个tablet中. 因为hash的分区键是自增性的, 就不会有 hot 切片(瓶颈). 可见, 纯hash分区比较适合选择性好的分区键.
2. range 分区: 如果时间字段可以作为主键的一部分, 可以考虑将时间字段作为range分区键, 往往会得到较好的查询效果. 因为Kudu分区数不能超过1000个, 所以通常不适合用日期作分区键, 因为这样仅能存放3年数据, 往往使用月份作为分区键. 纯range分区的表一般不能太大, 否则当前月的分区往往会是hot分区, 影响性能.
3. hash + range 分区: 对于较大的事实表, 推荐使用 hash+range分区方法, 使用选择性强的字段作为hash键, 使用月份作为range分区键, 这样能避免纯range分区表的缺点.
---==============================
Kudu的一些限制:
---==============================
压缩前的字段长度应该小于64KB.
集群最多100 个tablet server.
每个tablet server推荐最多1000个tablet(含replica).
每个tablet server最多管理4TB的数据(压缩后的数据量, 含replica).
每个tablet server存储的数据最大为4T.
每个tablet 最好控制在20GB内, 1000万笔以内.
每个表在单个tablet server上最多60个partition(含replica). 按照20个tablet server算(replica三份), 一个表最多400个partition; 按照50个tablet server算, 一个表最多1000个partition.
更多信息: https://kudu.apache.org/docs/known_issues.html
---==============================
SQL on Kudu 工具:
---==============================
impala 操作kudu的文档: https://impala.apache.org/docs/build/html/topics/impala_kudu.html
impala 或 Spark SQL
虽说 Kudu 提供了高效的单行插入和更新功能, 但Impala还是侧重数据分析, 并没有对单行Insert/Update进行优化, 所以如果有大量小型DML的操作, 推荐使用Kudu API而不是Impala SQL方式. 当一定要使用Impala SQL时, 最好采用批处理方式, 即一个Insert 语句一次性插入多行数据. 测试Insert 写到Vertica小集群速度近为7000笔/秒, 而Impala(通过Hive JDBC Driver)写到Kudu仅仅70笔/秒, Impala(通过Impala JDBC Driver)写到Kudu仅仅40笔/秒,
---==============================
Kudu 建表
---==============================
Kudu的数据类型:
BOOL, INT8, INT16, INT32, BIGINT, INT64, FLOAT, DOUBLE, STRING, BINARY, TIMESTAMP.
但 DECIMAL,CHAR,VARCHAR,DATE 和 ARRAY 等复杂类型不受支持.
Impala 的数据类型:
BIGINT,BOOLEAN,CHAR,DECIMAL,DOUBLE,FLOAT,INT,REAL,SMALLINT,STRING,TIMESTAMP,TINYINT,VARCHAR
还有Array,Struct,Map等复杂类型
当我们使用Impala创建Kudu格式的表, 必须使用kudu数据类型建表, 而不能使用impala支持的数据类型.
kudu 表文件是列式数据格式, 另外kudu允许为每个字段指定不同的压缩的encoding 算法和压缩算法.
强烈推荐 impalad 服务加上启动参数 -kudu_master_hosts, 这样每个impala定义kudu表的DDL语句中, 就不需要在TBLPROPERTIES中指定kudu.master_addresses属性.
kudu.table_name 表属性, 可以理解为在kudu中的表名(物理表名), 而建表语句的表名可以理解为impala catalog中的名称(逻辑名称).
drop table if exists kudu_somedb.kudu_test ;
CREATE TABLE kudu_somedb.kudu_test
(
ActionDate timestamp ENCODING BIT_SHUFFLE COMPRESSION LZ4,
UID string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY,
Operation string ENCODING DICT_ENCODING COMPRESSION SNAPPY,
EUTIME timestamp ENCODING BIT_SHUFFLE COMPRESSION LZ4,-- default now(),
EID_kudu string ENCODING PLAIN_ENCODING COMPRESSION SNAPPY,-- concat(cast(unix_timestamp() as string),uuid()) ,
PRIMARY KEY (ActionDate,Uid,Operation)
)
PARTITION BY HASH (Uid) PARTITIONS 6 ,
RANGE (ActionDate) (
PARTITION '2018-03-16' <= VALUES < '2018-03-17',
PARTITION '2018-03-17' <= VALUES < '2018-03-18',
PARTITION '2018-03-18' <= VALUES < '2018-03-19',
PARTITION '2018-03-19' <= VALUES < '2018-03-20'
)
STORED AS KUDU
TBLPROPERTIES (
'kudu.table_name' = 'somedb.kudu_test',
'kudu.master_addresses' = '10.205.6.121:7051,10.205.6.122:7051,10.205.7.134:7051' ,
'kudu.num_tablet_replicas' = '3'
);
下面是增加和删除 range 分区的语法:
alter table kudu_somedb.kudu_test add IF NOT EXISTS range partition '2018-03-20' <= VALUES < '2018-03-21' ;
alter table kudu_somedb.kudu_test drop IF EXISTS range partition '2018-03-20' <= VALUES < '2018-03-21' ;
-- Create select 方式建表语法, 注意这里的primary key()中的字段名必须使用小写字母.
create table temptable.test
Primary key(id,name)
STORED AS KUDU
TBLPROPERTIES (
'kudu.table_name' = 'temptable.test',
'kudu.master_addresses' = '10.205.6.121:7051,10.205.6.122:7051,10.205.7.134:7051',
'kudu.num_tablet_replicas' = '1'
)
as
select 1 id, 'name' name, 20 ag
;
---==============================
善用 if exists 语句
---==============================
很多时候我们需要在程序中创建临时表, 逻辑一般是, 如果临时表存在先drop, 然后新建这个临时表. 因为是在程序中, 所以删除动作不希望报错, 这时候可以在drop table后加上 if exists. 下面用视图说明这个技巧.
drop view if exists kudu_guba.v1
;
create view if not exists kudu_guba.v1
as
select 1 a
;
---==============================
蛋疼的大小写规则:
---==============================
1. 使用Impala insert SQL时候, 主键字段名必须是小写; 而update/delete无限制.
2. 使用 impala 创建kudu表, kudu.table_name名称会保持DDL语句中的大小写, 字段名会自动转成小写字母.
3. 使用 kudu API 访问表时候, 表名称大小写敏感的(必须按照kudu.table_name名的写法), 字段名也是大小写敏感的(也就是必须使用小写字母).
4. 采用Create select 方式建表语法, 注意这里的primary key()中的字段名必须使用小写字母.
5. 普通的DDL建表, primary key()中的字段名大小写都可以.
Kudu系列-基础的更多相关文章
- iOS系列 基础篇 03 探究应用生命周期
iOS系列 基础篇 03 探究应用生命周期 目录: 1. 非运行状态 - 应用启动场景 2. 点击Home键 - 应用退出场景 3. 挂起重新运行场景 4. 内存清除 - 应用终止场景 5. 结尾 本 ...
- iOS系列 基础篇 04 探究视图生命周期
iOS系列 基础篇 04 探究视图生命周期 视图是应用的一个重要的组成部份,功能的实现与其息息相关,而视图控制器控制着视图,其重要性在整个应用中不言而喻. 以视图的四种状态为基础,我们来系统了解一下视 ...
- iOS系列 基础篇 05 视图鼻祖 - UIView
iOS系列 基础篇 05 视图鼻祖 - UIView 目录: UIView“家族” 应用界面的构建层次 视图分类 最后 在Cocoa和Cocoa Touch框架中,“根”类时NSObject类.同样, ...
- iOS系列 基础篇 06 标签和按钮 (Label & Button)
iOS系列 基础篇 06 标签和按钮 (Label & Button) 目录: 标签控件 按钮控件 小结 标签和按钮是两个常用的控件,下面咱们逐一学习. 1. 标签控件 使用Single Vi ...
- iOS系列 基础篇 07 Action动作和输出口
iOS系列 基础篇 07 Action动作和输出口 目录: 1. 前言及案例说明 2. 什么是动作? 3. 什么是输出口? 4. 实战 5. 结尾 1. 前言及案例说明 上篇内容我们学习了标签和按钮 ...
- iOS系列 基础篇 08 文本与键盘
iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...
- iOS系列 基础篇 09 开关、滑块和分段控件
iOS系列 基础篇 09 开关.滑块和分段控件 目录: 案例说明 开关控件Switch 滑块控件Slider 分段控件Segmented Control 1. 案例说明 开关控件(Switch).滑块 ...
- Java多线程系列--“基础篇”11之 生产消费者问题
概要 本章,会对“生产/消费者问题”进行讨论.涉及到的内容包括:1. 生产/消费者模型2. 生产/消费者实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p ...
- Java多线程系列--“基础篇”04之 synchronized关键字
概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchro ...
随机推荐
- 自学华为IoT物联网_10 IoT联接管理平台配置及开发实验1
点击返回自学华为IoT物流网 自学华为IoT物联网_10 IoT联接管理平台配置及开发实验1 实验1:OceanConnect平台实验 通过基本的编程操作与配置,帮助读者熟悉O ...
- linux test条件测试
语法 test EXPRESSION [ EXPRESSION ] [[ EXPRESSION ]] 1.数值测试 -eq 是否等于 -ne 是否不等 -gt 是否大于 -ge 是否大于等于 -lt ...
- BM算法
BM算法 用来求解一个数列的递推式. 即给定\(\{x_i\}\)求解一个\(\{a_i\}\),满足\(|a|=m,x_n=\sum_{i=1}^ma_i*x_{n-i}\). 考虑增量法构造. 假 ...
- 单片机的外围功能电路 LET′S TRY“嵌入式编程”: 2 of 6
单片机的外围功能电路 LET′S TRY“嵌入式编程”: 2 of 6 本连载讲解作为嵌入式系统开发技术人员所必需具备的基础知识.这些基础知识是硬件和软件技术人员都应该掌握的共通技术知识. 上期在&l ...
- Anaconda For Linux (附C#交互式编程的引入)
汇总系列:https://www.cnblogs.com/dunitian/p/4822808.html#ai Jupyter美化: https://www.cnblogs.com/dotnetcra ...
- Arcgis for qml - 鼠标拖拽移动
以实现鼠标拖拽文本图层为例 GitHub:ArcGIS拖拽文本 作者:狐狸家的鱼 目的是利用鼠标进行拖拽. 实现两种模式,一种是屏幕上的拖拽,第二种是地图上图层的挪动. 屏幕上的拖拽其实跟ArcGIS ...
- [Splay][学习笔记]
胡扯 因为先学习的treap,而splay与treap中有许多共性,所以会有很多地方不会讲的很细致.关于treap和平衡树可以参考这篇博客 关于splay splay,又叫伸展树,是一种二叉排序树,它 ...
- unittest的使用一
selenium: (1).firefox官方下载驱动geckodriver,windows:放在\python36或者是27的目录下 Mac: /usr/local/bin (2).firefox的 ...
- STL学习笔记:空间配置器allocator
allocator必要接口: allocator::value_type allocator::pointer allocator::const_pointer allocator::referenc ...
- HR算法具体过程
首先研究HR算法在概率分布估计中的实现,我们再考虑如何将其应用于频繁项挖掘中. 一.确定输入数据类型 def generate_uniform_distribution(k): raw_distrib ...