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 ...
随机推荐
- 自学Python之路-Python并发编程+数据库+前端
自学Python之路-Python并发编程+数据库+前端 自学Python之路[第一回]:1.11.2 1.3
- 自学Python4.3-装饰器固定格式
自学Python之路-Python基础+模块+面向对象自学Python之路-Python网络编程自学Python之路-Python并发编程+数据库+前端自学Python之路-django 自学Pyth ...
- 【BZOJ3215/3216】[ZJOI2013]话旧/话旧2(组合数学,动态规划)
[BZOJ3215/3216][ZJOI2013]话旧/话旧2(组合数学,动态规划) 题面 BZOJ3215 BZOJ3216 题解 先解决\(3216\),求的是最小值为\(0\). 因为起点就是\ ...
- iptables防火墙详解(二)
-- 基于状态的iptables 如果按照tcp/ip来划分连接状态,有11种之多(课后可以自己去读一下相关知识) 但iptables里只有4种状态:ESTABLISHED.NEW.RELATED及I ...
- map映照容器
//map映照容器是由一个键值和一个映照数据组成的,键值与映照数据之间具有一一映照的关系 //map映照容器的键值不允许重复 ,比较函数值对元素 //的键值进行比较,元素的各项数据可通过键值检索出来 ...
- JS原生 未来元素监听写法
绑定事件的另一种方法是用 addEventListener() 或 attachEvent() 来绑定事件监听函数. addEventListener()函数语法:elementObject.addE ...
- A1118. Birds in Forest
Some scientists took pictures of thousands of birds in a forest. Assume that all the birds appear in ...
- A1112. Stucked Keyboard
On a broken keyboard, some of the keys are always stucked. So when you type some sentences, the char ...
- ASP.NET MVC计划任务实现方法(定时执行某个功能)
系统中定时执行某个任务是比较常用的功能,如一个部门定期向上级部门上报数据是一个典型的例子,下面就简单说说在.net mvc中如何实现定时执行某个功能的方法. 1.首先修改Glocal.asax文件,在 ...
- 第十八篇-Spinner下拉列表的使用
效果图 MainActivity.java package com.example.aimee.spinnertest; import android.support.v7.app.AppCompat ...