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系列-基础的更多相关文章

  1. iOS系列 基础篇 03 探究应用生命周期

    iOS系列 基础篇 03 探究应用生命周期 目录: 1. 非运行状态 - 应用启动场景 2. 点击Home键 - 应用退出场景 3. 挂起重新运行场景 4. 内存清除 - 应用终止场景 5. 结尾 本 ...

  2. iOS系列 基础篇 04 探究视图生命周期

    iOS系列 基础篇 04 探究视图生命周期 视图是应用的一个重要的组成部份,功能的实现与其息息相关,而视图控制器控制着视图,其重要性在整个应用中不言而喻. 以视图的四种状态为基础,我们来系统了解一下视 ...

  3. iOS系列 基础篇 05 视图鼻祖 - UIView

    iOS系列 基础篇 05 视图鼻祖 - UIView 目录: UIView“家族” 应用界面的构建层次 视图分类 最后 在Cocoa和Cocoa Touch框架中,“根”类时NSObject类.同样, ...

  4. iOS系列 基础篇 06 标签和按钮 (Label & Button)

    iOS系列 基础篇 06 标签和按钮 (Label & Button) 目录: 标签控件 按钮控件 小结 标签和按钮是两个常用的控件,下面咱们逐一学习. 1. 标签控件 使用Single Vi ...

  5. iOS系列 基础篇 07 Action动作和输出口

    iOS系列 基础篇 07 Action动作和输出口 目录:  1. 前言及案例说明 2. 什么是动作? 3. 什么是输出口? 4. 实战 5. 结尾 1. 前言及案例说明 上篇内容我们学习了标签和按钮 ...

  6. iOS系列 基础篇 08 文本与键盘

    iOS系列 基础篇 08 文本与键盘 目录: 1. 扯扯犊子 2. TextField 3. TextView 4. 键盘的打开和关闭 5. 打开/关闭键盘的通知 6. 键盘的种类 7. 最后再扯两句 ...

  7. iOS系列 基础篇 09 开关、滑块和分段控件

    iOS系列 基础篇 09 开关.滑块和分段控件 目录: 案例说明 开关控件Switch 滑块控件Slider 分段控件Segmented Control 1. 案例说明 开关控件(Switch).滑块 ...

  8. Java多线程系列--“基础篇”11之 生产消费者问题

    概要 本章,会对“生产/消费者问题”进行讨论.涉及到的内容包括:1. 生产/消费者模型2. 生产/消费者实现 转载请注明出处:http://www.cnblogs.com/skywang12345/p ...

  9. Java多线程系列--“基础篇”04之 synchronized关键字

    概要 本章,会对synchronized关键字进行介绍.涉及到的内容包括:1. synchronized原理2. synchronized基本规则3. synchronized方法 和 synchro ...

随机推荐

  1. ListView中的组件Button的OnClick事件触发时机

    Android开发时,ListView中的组件Button的OnClick事件必须在ListView之外的组件事件触发后才能触发? 此处ListView无OnItemClick事件,而且ListVie ...

  2. IISEXPRESS64位运行

    调试时使用IISEXPRESS 64位.经网上查找这样开启

  3. docker-compose.yml(2)

    实例2:version: '3'services: user-service: image: "$DOCKER_SERVICE_IMAGE_TAG" network_mode: & ...

  4. Annihilate(SA)

    题目描述 黑暗之主的蜈蚣几乎可以毁灭一切,因此小正方形陷入了苦战…… 小正方形现在需要减弱黑暗之主的攻击. 一个黑暗之主的攻击可以用一个仅有小写字母的字符串表示. 现在黑暗之主向小正方形发动了若干攻击 ...

  5. JQuery未来元素事件监听写法

    $(document).on('click','.div1',function(){ alert("abc"); }); 格式一致,第一个参数写事件,第二个参数给谁写事件(选择器) ...

  6. C# Winfrom MDI(多文档界面)

    1.首先设置父级Form1界面,只需要将该界面的IsMdiContainer属性设置为true: 2.设置按钮的事件来打开子级的窗口Form2,Form3等等: 3.在From1内设置一个容器pane ...

  7. 洛谷P1020 导弹拦截

    n²谁都会打,不说了. 这里讨论一下nlogn算法(单调不减): 首先开始考虑单调性,我习惯性的以为是单调队列/栈优化的那个套路,想要找到一个跟下标有关的单调性却发现没有. 例如:我想过当下标增加时f ...

  8. A1131. Subway Map (30)

    In the big cities, the subway systems always look so complex to the visitors. To give you some sense ...

  9. [bzoj1717][Milk Patterns 产奶的模式]

    题目链接 思路 先求出后缀数组,并且求出LCP.二分一下长度len.check的时候就是看有没有连续的k个后缀的LCP大于len.也就是判断是不是有连续的k-1个height大于len. 代码 #in ...

  10. html 网页背景图片根据屏幕大小CSS自动缩放

    https://blog.csdn.net/coslay/article/details/47109281 腾讯微博和QQ空间的登录背景图片是根据访客的屏幕大小自动缩放的,但是好像是用JQuery代码 ...