在數據倉庫的建設中從業務庫同步數據到分析庫後者hive是不可避免的流程。在關係型數據庫到hive的流程中,現有的業務是用sqoop去同步,可是sqoop1的bug仍是有的,例如同步數據的時候的編碼問題,特殊字符問題,字段爲null的問題等。使用hive的JdbcStorageHandler能夠簡化數據同步的過程,本文記錄使用hive這個功能的過程,和遇到的已經解決的還未解決的問題。java
使用這個功能須要先加載hive-jdbc-handler的依賴包,若是不加jar包的話,會有以下的提示:FAILED: SemanticException Cannot find class 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
因此須要先下載對應的jar包,在建表以前將jar包引入。add jar /home/user/hive-jdbc-handler-3.1.2.jar;
sql
建表的語法以下,須要指定數據庫的host,dbname,用戶名密碼等,同時還要指定在hive中使用的方式是read仍是write,以下是說在hive中只read響應的表,不須要insert。
``
CREATE EXTERNAL TABLE tmp.click_farm
(
stat_date date,
kind string,
type string,
click_number int,
flag int,
update_time string
)
STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
TBLPROPERTIES (
"hive.sql.database.type" = "POSTGRES",
"hive.sql.jdbc.driver" = "org.postgresql.Driver",
"hive.sql.jdbc.url" = "jdbc:postgresql://host:port/dbname",
"hive.sql.jdbc.read-write" = "read",
"hive.sql.dbcp.username" = "user_name",
"hive.sql.dbcp.password" ="pswd",
"hive.sql.table" = "=tmp.click_farm",
"hive.sql.query"="select * from tmp.click_farm"
);
``數據庫
參數 | 描述 | |
---|---|---|
hive.sql.jdbc.database.type | 數據庫類型 | |
hive.sql.jdbc.url | jdbc鏈接字符串 | |
hive.sql.jdbc.driver | jdbc驅動程序類 | |
hive.sql.jdbc.username | 用戶名 | |
hive.sql.jdbc.password | 密碼 | |
hive.sql.jdbc.read-write | 只讀表 read 可讀可寫表 read,write | |
hive.sql.table | 對應的表名 | |
hive.sql.jdbc.partition.column | 對應分區字段 | |
hive.sql.jdbc.partition.nums | 分區數量 | |
hive.sql.jdbc.split.size | 切分map的大小 | |
hive.sql.jdbc.fetch.size | jdbc 讀取數據 fetch 大小 | |
hive.sql.jdbc.batch.size | jdbc 每次提交的數據量(批量插入數據庫) |
在上面的建表語句中,數據庫的密碼就寫在建表語句中,show create table 就能看到密碼,很不安全。官方提供了能夠將密碼隱去的方式:https://cwiki.apache.org/confluence/display/Hive/JdbcStorageHandlerapache
按照wiki上的用法,使用hadoop credential create host1.password -provider jceks://hdfs/user/user.jceks
命令在hdfs上生成祕鑰,驗證祕鑰確實存在。安全
`
add jar /home/ticketdev/hive-jdbc-handler-3.1.2.jar;
CREATE EXTERNAL TABLE tmp.click_farm
(
stat_date date,
kind string,
type string,
click_number int,
flag int,
update_time string
)
STORED BY 'org.apache.hive.storage.jdbc.JdbcStorageHandler'
TBLPROPERTIES (
"hive.sql.database.type" = "POSTGRES",
"hive.sql.jdbc.driver" = "org.postgresql.Driver",
"hive.sql.jdbc.url" = "jdbc:postgresql://host:port/dbname",
"hive.sql.dbcp.username" = "user_name",
"hive.sql.dbcp.password.keystore" = "jceks://hdfs/user/user.jecks",
"hive.sql.dbcp.password.key" = "host1.password",
"hive.sql.table" = "tmp.click_farm",
"hive.sql.query"="select * from tmp.click_farm"
);ide
`
此時會提示:FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. java.lang.RuntimeException: MetaException(message:org.apache.hadoop.hive.serde2.SerDeException org.apache.hive.storage.jdbc.exception.HiveJdbcDatabaseAccessException: Error while trying to get column names: Cannot create JDBC driver of class 'org.postgresql.Driver' for connect URL 'jdbc:postgresql://host:port/dbname')
提示的是找不到對應的祕鑰,可是祕鑰確實在hdfs上,這個問題沒解決。oop
用暴露用戶名和密碼的方式建了一張表,表的大小是110G,3億的數據量,在hive中去查詢的時候會發現查詢一直卡住。對於大表,這種方式的風險仍是很大的,而且高度依賴索引。測試30G體量,6000萬數據的表,發現查詢速度還能夠。post