以下博文转载自:https://www.iteblog.com/archives/2525.html

Apache Hive 从 HIVE-1555 开始引入了 JdbcStorageHandler ,这个使得 Hive 能够读取 JDBC 数据源,关于 Apache Hive 引入 JdbcStorageHandler 的背景可以参见 《Apache Hive 联邦查询(Query Federation)》。本文主要简单介绍 JdbcStorageHandler 的使用。

语法

JdbcStorageHandler 使得 Hive 能够读取 JDBC 数据源,目前 JdbcStorageHandler 不支持将数据写入到 JDBC 数据源。为了使用 JdbcStorageHandler ,我们需要在 Hive 中创建外部表,具体如下:

CREATE EXTERNAL TABLE iteblog
(name string,age int,gpa double
)
STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
TBLPROPERTIES ("hive.sql.database.type" = "MYSQL","hive.sql.jdbc.driver" = "com.mysql.jdbc.Driver","hive.sql.jdbc.url" = "jdbc:mysql://www.iteblog.com/sample","hive.sql.dbcp.username" = "hive","hive.sql.dbcp.password" = "hive","hive.sql.table" = "STUDENT","hive.sql.dbcp.maxActive" = "1"
);

我们可以使用 alter table 命令来修改表的 JdbcStorageHandler 属性,就和正常的表一样,如下:

ALTER TABLE iteblog SET TBLPROPERTIES ("hive.sql.dbcp.password" = "passwd");

JdbcStorageHandler 支持的表属性

必选属性
在 Hive 中使用 JdbcStorageHandler ,下面的属性是必须指定的

  1. hive.sql.database.type :JDBC数据库类型,支持 MYSQL, POSTGRES, ORACLE, MSSQL, DERBY;
  2. hive.sql.jdbc.url: jdbc 链接字符串;
  3. hive.sql.jdbc.driver: jdbc driver 类;
  4. hive.sql.dbcp.username: jdbc 连接用户名;
  5. hive.sql.dbcp.password: jdbc 明文密码。强烈建议不要通过这个参数设置密码。推荐将密码存储在keystore 中,详情参见下面的安全密码设置章节。
  6. hive.sql.table / hive.sql.query: 我们需要指定 “hive.sql.table” 或 “hive.sql.query” 来说明如何从 jdbc 数据库获取数据。 “hive.sql.table” 表示单个表,“hive.sql.query” 表示任意 sql 查询。

可选属性:
除了上面的必选属性,JdbcStorageHandler 还支持以下几个可选属性:

  1. hive.sql.catalog: jdbc catalog 名字(仅仅在 hive.sql.table 被指定的时候才支持)
  2. hive.sql.schema: jdbc schema 名称 (仅仅在 hive.sql.table 被指定的时候才支持)
  3. hive.sql.jdbc.fetch.size: 每个批次获取的行数
  4. hive.sql.dbcp.xxx: 所有 dbcp 参数都将传递给 commons-dbcp。
  5. https://commons.apache.org/proper/commons-dbcp/configuration.html。比如如果你在表的属性里面指定了 hive.sql.dbcp.maxActive=1 , Hive 将会传递 maxActive=1 到 commons-dbcp。

支持的数据类型

JdbcStorageHandler 表中列支持的数据类型有:

  1. 数字数据类型: byte, short, int, long, float, double
  2. Decimal,支持 scale 和 precision
  3. String 数据类型: string, char, varchar
  4. Date
  5. Timestamp
    复杂的数据类型,比如 struct, map, array 目前还不支持。

列和数据类型映射

hive.sql.table / hive.sql.query 使用模式定义表格数据,模式定义必须与表模式定义相同。 例如,以下 create table 语句将失败:

CREATE EXTERNAL TABLE iteblog
(name string,age int,gpa double
)
STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
TBLPROPERTIES (. . . . . ."hive.sql.query" = "SELECT name, age, gpa, gender FROM STUDENT",
);

但是 hive.sql.table / hive.sql.query 模式的列名和列类型可能与表的模式不同。 在这种情况下,数据库列按位置映射到 hive 列;如果数据类型不同,Hive 将尝试根据 Hive 表模式转换它。 例如:

CREATE EXTERNAL TABLE iteblog
(sname string,age int,effective_gpa decimal(4,3)
)
STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
TBLPROPERTIES (. . . . . ."hive.sql.query" = "SELECT name, age, gpa FROM STUDENT",
);

In case the conversion is not possible, Hive will produce null for the field.

Hive 将尝试将 STUDENT 表的 gpa 的 double 类型转换为 decimal(4,3) 作为 iteblog 表的 effective_gpa 字段。如果无法进行转换,Hive 将把该字段的值转换为 null。

Auto Shipping

如果在查询中使用了 JdbcStorageHandler,JdbcStorageHandler 会自动将所需的 jar 发送到 MR/Tez/LLAP 后端。用户无需手动添加 jar。 如果在 classpath 中检测到任何 jdbc 驱动程序的 jar(包括mysql、postgres、oracle 和 mssql),JdbcStorageHandler 还会将所需的 jdbc 驱动程序 jar 发送到后端。但是,用户仍然需要将 jdbc 驱动程序 jar 复制到 hive 的 classpath(通常是 hive 的 lib 目录)。

密码保护(Securing Password)

在大多数情况下,我们不希望在表属性“hive.sql.dbcp.password”中以明文的形式存储 jdbc 密码。相反,用户可以使用以下命令将密码存储在 HDFS 上的 Java 密钥库文件中:

hadoop credential create host1.password -provider jceks://hdfs/user/foo/test.jceks -v passwd1
hadoop credential create host2.password -provider jceks://hdfs/user/foo/test.jceks -v passwd2

这将在 hdfs://user/foo/test.jceks 里面创建一个 keystore 文件,其中包含两个密钥:host1.password 和 host2.password。在 Hive 中创建表时,我们需要在 create table 语句中指定“hive.sql.dbcp.password.keystore”和“hive.sql.dbcp.password.key”而不是“hive.sql.dbcp.password”,具体如下:

CREATE EXTERNAL TABLE iteblog
(name string,age int,gpa double
)
STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
TBLPROPERTIES (. . . . . ."hive.sql.dbcp.password.keystore" = "jceks://hdfs/user/foo/test.jceks","hive.sql.dbcp.password.key" = "host1.password",. . . . . .
);

我们需要通过仅授权目标用户读取此文件来保护 keystore 文件。Hive 将检查 keystore 文件的权限,以确保用户在创建/更改表时具有读取权限。

分区

Hive 能够拆分 jdbc 数据源并以并行的方式处理每个分片。用户可以使用以下表属性来决定是否拆分以及拆分的分片数:

  1. hive.sql.numPartitions: 为数据源生成多少个分片,如果不需要拆分则设置为 1
  2. hive.sql.partitionColumn: 需要对哪个列进行拆分。如果指定了这个,Hive 会将此列拆分成hive.sql.numPartitions,每个分区的拆分点需要使用 hive.sql.lowerBound 和 hive.sql.upperBound 计算。如果没有指定这个参数,但 numPartitions > 1,Hive 将使用 offset 拆分数据源。但是,对于某些数据库,偏移量并不总是可靠的。 如果要拆分数据源,强烈建议定义partitionColumn。partitionColumn 必须存在于"hive.sql.table"/“hive.sql.query” 模式中。
  3. hive.sql.lowerBound / hive.sql.upperBound: 用于拆分 partitionColumn 计算间隔的下限/上限。两个属性都是可选的。如果未定义,Hive 将对数据源执行 MIN/MAX 查询以获得下限/上限。请注意,hive.sql.lowerBound 和 hive.sql.upperBound 都不能为 null。

使用示例如下:

TBLPROPERTIES (. . . . . ."hive.sql.table" = "DEMO","hive.sql.partitionColumn" = "num","hive.sql.numPartitions" = "3","hive.sql.lowerBound" = "1","hive.sql.upperBound" = "10",. . . . . .
);

这种表将会拆分成3个分片,num<4 or num is null, 4< =num<7, num>=7

TBLPROPERTIES (. . . . . ."hive.sql.query" = "SELECT name, age, gpa/5.0*100 AS percentage FROM STUDENT","hive.sql.partitionColumn" = "percentage","hive.sql.numPartitions" = "4",. . . . . .
);

Hive 将执行 jdbc 查询以获取 percentage 列的 MIN/MAX,这张表对应的 min/max 为 60/100。然后表将创建4个分片:(,70),[70,80),[80,90),[90,)。 第一个分片还包括空值。

如果要查看 JdbcStorageHandler 生成的分片,可以在 hiveserver2 日志或 Tez AM 日志中查找以下消息:

jdbc.JdbcInputFormat: Num input splits created 4
jdbc.JdbcInputFormat: split:interval:ikey[,70)
jdbc.JdbcInputFormat: split:interval:ikey[70,80)
jdbc.JdbcInputFormat: split:interval:ikey[80,90)
jdbc.JdbcInputFormat: split:interval:ikey[90,)

计算下推

Hive 会积极地将计算推送到 jdbc 表,因此我们可以充分利用 jdbc 数据源的计算能力。比如,我们有另外一张名为 iteblog_hadoop 表,如下:

CREATE EXTERNAL TABLE iteblog_hadoop
(name string,age int,registration string,contribution decimal(10,2)
)
STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
TBLPROPERTIES ("hive.sql.database.type" = "MYSQL","hive.sql.jdbc.driver" = "com.mysql.jdbc.Driver","hive.sql.jdbc.url" = "jdbc:mysql://www.iteblog.com/sample","hive.sql.dbcp.username" = "hive","hive.sql.dbcp.password" = "hive","hive.sql.table" = "VOTER"
);

那么下面的 Join 操作将会下推到 MySql 执行:

select * from iteblog join iteblog_hadoop on student_jdbc.name=voter_jdbc.name;

可以通过explain查看生成的执行计划:

explain select * from iteblog join iteblog_hadoop on student_jdbc.name=voter_jdbc.name;. . . . . .TableScanalias: iteblog properties:hive.sql.query SELECT `t`.`name`, `t`.`age`, `t`.`gpa`, `t0`.`name` AS `name0`, `t0`.`age` AS `age0`, `t0`.`registration`, `t0`.`contribution`
FROM (SELECT *
FROM `STUDENT`
WHERE `name` IS NOT NULL) AS `t`
INNER JOIN (SELECT *
FROM `VOTER`
WHERE `name` IS NOT NULL) AS `t0` ON `t`.`name` = `t0`.`name`. . . . . .

计算下推仅在 jdbc 表由 hive.sql.table 定义时才会发生。 Hive 将重写 hive.sql.query,并在 jdbc 表上进行更多计算。在上面的例子中,mysql 将运行查询并检索 join 的结果,而不是获取两个表的数据,然后在 Hive 中进行 join 操作。

目前支持算子下推的操作符包括 filter, transform, join, union, aggregation 以及 sort。

Apache Hive JdbcStorageHandler 编程入门指南相关推荐

  1. [译]函数式响应编程入门指南

    原文地址:An Introduction to Functional Reactive Programming 原文作者:Daniel Lew 译文出自:掘金翻译计划 本文永久链接:github.co ...

  2. 编程指南_今晚7点,译者编程入门指南抽奖!

    各位关注"简言"的同学们好.老师们! 我的新书<译者编程入门指南>出版啦!感谢大家一直以来的支持和陪伴,我每次发完文章后都会得到大家的点赞.转发.留言甚至打赏,我感到非 ...

  3. 编程入门指南 v1.4

    著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:Badger 链接:http://zhuanlan.zhihu.com/xiao-jing-mo/19959253 来源: ...

  4. python编程入门指南-最简单的Python编程入门指南,没基础也能快速入门Python编程...

    原标题:最简单的Python编程入门指南,没基础也能快速入门Python编程 对Python这门编程语言来讲,几乎是没什么不能做到的.最难的不过是如何入门,也就是你进入Python编程的第一步. 其实 ...

  5. python编程入门指南-编程入门指南

    编程入门指南 ----------------------------------------------- 编程入门指南 v1.5 --- https://zhuanlan.zhihu.com/p/ ...

  6. Matlab编程入门指南:简介、安装、学习路线和几十个编程案例分析。

    一.Matlab编程入门指南:简介.安装.学习路线和几十个编程案例分析. 1.Matlab编程语言是一种广泛应用于科学计算.工程计算.数据分析.统计分析.信号处理等领域的高级数值计算和数据可视化软件. ...

  7. pro unity xl编程手册_UnityProXL编程入门指南资料

    UnityProXL编程入门指南资料 (29页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.90 积分 M340使用Unity Pro XL编程入门第 ...

  8. 萧井陌java_萧井陌编程入门指南

    萧井陌编程入门指南下载!萧井陌编程入门指南pdf是一款为学习JAVA用户打造的视频教程.需要学习JAVA的用户赶紧下载,此套JAV编程思想的课程适合想要自学java的同学们,课程抽丝拨茧,层层推进,让 ...

  9. 编程入门指南 @萧井陌 的心得

    编程入门指南 v1.4 这是一个知乎上的程序员大神,给了我很多帮助,还有轮子哥vczh.感谢这些大神的无私分享精神,才让我一窥什么是程序员,以及如何成为一名程序员.下面进入正题: 今年的目标:APP ...

最新文章

  1. Spring基础专题——引言
  2. 微软职位内部推荐-Senior SDE
  3. Unity游戏暂停之Update与FixedUpdate区别
  4. 前端学习(981):jquery入门
  5. windows下配置tensorflow
  6. linux查看帮助信息,命令帮助信息的获取
  7. MyCat:取代Cobar数据库中间件
  8. 人力资源学python有意义吗-为什么每个HR都应该学习一点编程?
  9. react中p标签_React 2020 p1简介和安装
  10. verp中的Viewable objects
  11. ffmpeg 音频转amr
  12. 程序员必读: 摸清Hash表的脾性
  13. 量化研究-恐慌和贪婪指数
  14. SQL SERVER数据库置疑后恢复步骤
  15. UE4_UE5蓝图command节点的使用(开启关闭屏幕响应-log-发布全屏显示)
  16. 培训三天敏捷我懂了这些
  17. php 商户转账到微信零钱
  18. 从titles表获取按照title进行分组,每组个数大于等于2,给出title以及对应的数目t
  19. 手把手教你打造一个VIM-IDE
  20. AsyncTask 复用

热门文章

  1. javascript 校验 非空_JavaScript_form表单非空验证;
  2. python分布式框架有哪些_Python并行分布式框架Celery详解
  3. Pandas打印所有行和列(显示所有的行和列)
  4. 小余学调度:学习记录(2022年1月)
  5. VTK:参数样条用法实战
  6. VTK:等参细胞演示用法实战
  7. VTK:vtkCamera用法实战
  8. opengl加载显示3D模型STL类型文件
  9. wxWidgets:wxMenu类用法
  10. wxWidgets:wxInitDialogEvent类用法