- 背景
後端查詢數據庫時,要用到hive表和MySQL表
當前的做法是:先查詢MySQL數據表,得到的結果通過參數的形式傳遞給hive表進行查詢
弊端: 當傳遞的參數太多時,SQL查詢有長度限制,當往關鍵字in中傳遞時,有長度和效率的限制
爲了解決這個問題,做以下探索:
- 在hive下創建一張與MySQL表相同的表,後端SQL查詢採用join的方式
- 在HBASE下創建表並映射到hive下,後端SQL查詢採用join的方式
比較兩種方式的查詢效率
- hive建表
一. 以TXT形式保存
建表語句:
create EXTERNAL `sys_workday` (
`mday` int COMMENT '',
`is_weekend` int COMMENT '',
`holiday_state` int COMMENT '')
row format delimited fields terminated by ';'
STORED AS TEXTFILE
LOCATION
'/user/sys_workday_txt'
建表後,接下來就是將數據傳入進去。從上面建表語句可以知道:
1.數據存儲格式是TXT文件;
2.TXT文件存放在hdfs地址爲:/user/sys_workday_txt下
3.TXT文件中的數據以“;”(分號)分割
具體的做法是從MySQL中導出TXT格式的數據,注意分隔符的選擇
執行完建表語句後,在Hadoop中會自動生成/user/sys_workday_txt路徑,接下來只需將MySQL導出的TXT數據上傳到Hadoop的/user/sys_workday_txt路徑
hdfs dfs -put ./sys_workday.txt /user/sys_workday_txt
運行MSCK REPAIR TABLE命令,hive就會去檢測這個表在hdfs上的文件,把沒有寫入metastore的分區信息寫入metastore
MSCK REPAIR TABLE sys_workday
二.以PARQUET格式存儲
建表語句:
create EXTERNAL `sys_workday_pq` (
`mday` int COMMENT '',
`is_weekend` int COMMENT '',
`holiday_state` int COMMENT '')
STORED AS PARQUET
LOCATION
'/user/sys_workday_pq'
建表後,將數據導入到sys_workday_pq中
具體做法:在spark-shell中讀取sys_workday所有數據,之後通過PARQUET格式保存到sys_workday_pq中
spark-shell
scala> import org.apache.spark.SparkConf
scala> import org.apache.spark.sql.SparkSession
scala> var sparkSession = SparkSession.builder().config(new SparkConf().setAppName("ApplicationName").
set("spark.serializer", "org.apache.spark.serializer.KryoSerializer").
set("spark.sql.sources.partitionOverwriteMode", "dynamic").
set("spark.sql.parquet.binaryAsString", "true").
set("spark.hadoop.hive.optimize.skewjoin", "true").
set("spark.hadoop.hive.groupby.skewindata", "true").
set("spark.hadoop.hive.exec.dynamic.partition.mode", "nonstrict").
set("spark.hadoop.hive.exec.max.dynamic.partitions", "100000").
set("spark.hadoop.hive.optimize.index.filter", "false")).enableHiveSupport().getOrCreate()
scala> var sql=s"""select * from sys_workday"""
scala> sparkSession.sql(sql).write.mode("Append").parquet("/user/sys_workday_pq")
scala> sparkSession.sql(s"msck repair table sys_workday_pq")
- HBASE建表及關聯hive
進入HBASE shell窗口
hbase shell
新建命名空間
hbase> create_namespace 'hongq'
創建HBASE表並指定列族
hbase> create 'hongq:sys_workday_hb', {NAME=>'info'}
建表後,向HBASE表中導入數據
具體做法將需要導入的文件上傳到hdfs上,如:sys_workday.txt
mday | is_weekend | holiday_state
20190701,1,0
…
在Linux上console執行以下命令即可將數據導入到HBASE表中:
hbase org.apache.hadoop.hbase.mapreduce.ImportTsv -Dimporttsv.separator="," -Dimporttsv.columns=HBASE_ROW_KEY,info:is_weekend,info:holiday_state hongq:sys_workday_hb /sys_workday.txt
接下來就是關聯hive表,在hive上創建sys_workday_hb,關聯HBASE中相應的表即可
CREATE EXTERNAL TABLE `sys_workday_hb`
( `mday` int COMMENT '',
`is_weekend` int COMMENT '',
`holiday_state` int COMMENT '')
STORED BY 'org.apache.hadoop.hive.hbase.HBaseStorageHandler'
WITH SERDEPROPERTIES ( 'hbase.columns.mapping'=':key,info:is_weekend,info:holiday_state')
TBLPROPERTIES ( 'hbase.table.name'='hongq:sys_workday_hb')
至此關聯完成
- 兩種方式SQL查詢效率對比
HIVE PARQUET > HBASE關聯
具體原因之後抽時間探索以下