溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Hive與Spark開發(fā)生產(chǎn)中遇到的問題有哪些

發(fā)布時(shí)間:2021-12-31 14:37:45 來源:億速云 閱讀:302 作者:iii 欄目:大數(shù)據(jù)

本篇內(nèi)容主要講解“Hive與Spark開發(fā)生產(chǎn)中遇到的問題有哪些”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實(shí)用性強(qiáng)。下面就讓小編來帶大家學(xué)習(xí)“Hive與Spark開發(fā)生產(chǎn)中遇到的問題有哪些”吧!

生產(chǎn)環(huán)境版本 Hive: 1.2.1, Spark: 2.3.2

1.insert overwrite directory 不會(huì)覆蓋數(shù)據(jù)

注意,生成結(jié)果是目錄,生成目錄里面的不同文件名不會(huì)被覆蓋,因此很容易出現(xiàn)數(shù)據(jù)double或者沒有覆蓋到數(shù)據(jù)的問題,比如數(shù)據(jù)分片原始結(jié)果如下:

/mytable/000000_0
/mytable/000000_1
/mytable/000000_2
/mytable/000000_3 
## 新生成的數(shù)據(jù)只含有 000000_0分片,那么1 2 3分片并不會(huì)被刪掉

解決方式:使用目錄上面建立外表insertoverwrite, 如果這個(gè)目錄是導(dǎo)入其他系統(tǒng)的目錄文件,可能更致命。注意建立外表時(shí)候,如果是分區(qū)表,刪除掉分區(qū),然后insert overwrite也會(huì)導(dǎo)致數(shù)據(jù)重復(fù),測試版本2.3.2

//a文件數(shù)據(jù)內(nèi)容
//2  10
//2  10
//2  10
//創(chuàng)建管理表
create table t2(id int) partitioned by (dt string);
load data local inpath '/xxx/a'

// 創(chuàng)建外分區(qū)表
create external table t1(id int) partitioned by (dt string);
// overwrite分區(qū)10
insert overwrite table t1 partition(dt='10') select 1 from t2 where dt=10;
//刪除分區(qū)10
ALTER TABLE t1 DROP PARTITION(dt='10');
// overwrite 10這個(gè)分區(qū)
insert overwrite table t1 partition(dt='10') select 2 from t2 where dt=10;

結(jié)果顯示6條數(shù)據(jù),顯然是異常的,在hive中這個(gè)結(jié)果是正常的(ps,最后發(fā)現(xiàn)是由于組內(nèi)小伙伴自己調(diào)試原因,改了參數(shù),其實(shí)默認(rèn)參數(shù)是沒問題的,就是true)

解決方式:

set spark.sql.hive.convertMetastoreParquet=true
set spark.sql.hive.convertMetastoreOrc=true

2.insert tableA select xx from tableB 字段屬性問題

注意:select 的字段名即使和tableA中的字段一樣,但是插入順序與字段順序不一樣,那么結(jié)果也是有問題的

常見發(fā)生情況為 later view 下的select,以為字段名對了,插入就沒問題,實(shí)際上是按順序插入的,即select再插入,也許與底層是mr實(shí)現(xiàn)有關(guān)系

3.spark.write 寫文件如果是覆蓋寫,如果是并發(fā)多個(gè)寫,同樣可能會(huì)出現(xiàn)數(shù)據(jù)重復(fù)

通過spark.write寫的方式,然后再與表關(guān)聯(lián),寫路徑的方式主要有下面兩種,通過參數(shù):mapreduce.fileoutputcommitter.algorithm.version 來控制,

Spark寫入HDFS是依賴于Hadoop的FileOutputCommitter的,它有兩種算法,一種是直接寫到臨時(shí)目錄,再copy到輸出目錄,稱之為v1版本,另外一種是直接輸出到結(jié)果目錄,稱之為v2版本,輸出性能上v2版本好一點(diǎn),但是這兩種都不能保證最終一致性,也就是在并發(fā)寫,情況下都是有問題的,其中v1是兩階段提交,可以保證讀的時(shí)候,不是臟數(shù)據(jù)

具體可參考:https://blog.csdn.net/u013332124/article/details/92001346

常發(fā)生于任務(wù)剛啟動(dòng),然后停止,又立刻重新調(diào)度

注意:離線的事務(wù)性比較差,多注意一下,盡量不要立刻重啟任務(wù),讓同一個(gè)目錄寫數(shù)據(jù)的操作同時(shí)進(jìn)行,如果一定要馬上重啟調(diào)度任務(wù),解決方式是kill掉任務(wù),刪除_remporay文件即可,離線情況下一致性往往大于性能,拒自己情況選擇v1還是v2版本的提交。

4.msck repair table 的問題

在回溯數(shù)據(jù)和例行執(zhí)行任務(wù)時(shí)候,可能會(huì)出現(xiàn)寫數(shù)據(jù)還沒寫完,回溯的任務(wù)將表msck repair ,導(dǎo)致下游任務(wù)讀到的數(shù)據(jù)不完全,跟3問題類似,其中兩個(gè)version的提交,在msck repair 之后,都會(huì)出現(xiàn),數(shù)據(jù)不完全,下游任務(wù)就檢測到分區(qū)

解決方式

write + repair —> insert / write + add partition

5.insert overwrite自個(gè)表分區(qū)

在hive里面直接寫是支持的,在spark里面會(huì)先刪數(shù)據(jù)分區(qū),然后懶加載才開始讀數(shù)據(jù),這樣就導(dǎo)致空指針,空數(shù)據(jù)問題,解決方法是先cache + 隨便一個(gè)action 數(shù)據(jù)緩存到內(nèi)存。

注意:一般這樣不建議,除非是剛開始開發(fā)的不重要的表,離線的做法是增加version來區(qū)分版本,常用在增加字段,修改字段生成邏輯,先增加個(gè)version,在新version上來搞,搞完了通知下游切換,或者保證無誤,將version改到老分區(qū)。

6.切記用最近的邏輯來依賴分區(qū)

實(shí)際場景中,要盡可能地讓數(shù)據(jù)跑批冪等,否則會(huì)出現(xiàn)在不知情維護(hù)情況下出現(xiàn)線上問題,增量表冪等常用處理方式ods_day ≤ 當(dāng)天 ,全量表常用處理方式ods_day=當(dāng)天即使并不需要卡這個(gè)時(shí)間,在當(dāng)前天修數(shù)據(jù),或者回溯時(shí)候,就不能保證數(shù)據(jù)一直有效,不能回溯的數(shù)據(jù),查問題會(huì)讓你惡心至極。

7.Spark和Hive的不兼容問題

對于Orc文件格式和Parquet文件格式,從兼容上來說,Spark實(shí)現(xiàn)更新一點(diǎn),Hive稍微舊一點(diǎn),比如用Spark建立的分區(qū)在某些情況寫出現(xiàn)null, empty等問題,可以設(shè)置下面兩個(gè)參數(shù),開啟使用hive的orc和Parquet格式來建表,這樣Spark和Hive就可以讀到可以同時(shí)兼容的數(shù)據(jù)表了,建議除非一些臨時(shí)表,需要落庫的表,可以盡量用Hive的方式來建,建完以后,Spark寫的時(shí)候多加下面的參數(shù)就不會(huì)有兼容問題了

//第一種
set spark.sql.hive.convertMetastoreParquet=true
set spark.sql.hive.convertMetastoreOrc=true 

//第二種
// Spark使用與Hive相同的約定寫parquet數(shù)據(jù)
.config("spark.sql.parquet.writeLegacyFormat", "true")

8.讀文件Qps過高問題

20/12/07 19:39:17 ERROR executor.Executor: Exception in task 740.2 in stage 2.0 (TID 5250)
org.apache.http.ConnectionClosedException: Premature end of Content-Length delimited message body (expected: 16,384; received: 0)

Hive與Spark開發(fā)生產(chǎn)中遇到的問題有哪些

遇到如圖所示問,從表面展示出來的是,讀文件太高,導(dǎo)致傳輸只傳輸了一半數(shù)據(jù),與機(jī)器限流有關(guān),就我廠而言,問過bmr維護(hù)的人,給的答復(fù)是,減少對某一文件的讀取頻率

解決方式:剛開始有些郁悶,離線數(shù)據(jù)讀難道還有并發(fā)問題,其實(shí)是限制的在某個(gè)datanode上某個(gè)文件塊的讀取qps, 所以,從這些方面來排查,首先分析哪些表是關(guān)鍵表,對關(guān)鍵表看看是否都是大文件,如果是的話調(diào)整其為小文件,常見方式有repatition 輸出或者h(yuǎn)ive的reduce數(shù)。

9.排序窗口函數(shù)的bug

經(jīng)過多次測試,-這個(gè)符號不起作用

spark.sql(sql).withColumn("rn", row_number().over(Window.partitionBy('f_trans_id).orderBy(-'f_modify_time)))
// 替代方案(最好用sql形式而不是DSL,感覺不是很直觀)
spark.sql(sql).withColumn("rn", row_number().over(Window.partitionBy('f_trans_id).orderBy($"f_modify_time".desc))
spark.sql(sql).withColumn("rn", row_number().over(Window.partitionBy('f_trans_id).orderBy(col(f_modify_time).desc))

10.alter table cascase

alter table 要加CASCADE,否則回溯的歷史數(shù)據(jù)分區(qū)的數(shù)據(jù)在hive中看不到,原理是不加cascade只對加了字段以后的元數(shù)據(jù)有用,對于舊分區(qū)回溯,即使數(shù)據(jù)回溯完成,你也是拿不到的,如果在回溯完才發(fā)現(xiàn)這個(gè)問題,可以change colunmn的方式來補(bǔ)元數(shù)據(jù)

到此,相信大家對“Hive與Spark開發(fā)生產(chǎn)中遇到的問題有哪些”有了更深的了解,不妨來實(shí)際操作一番吧!這里是億速云網(wǎng)站,更多相關(guān)內(nèi)容可以進(jìn)入相關(guān)頻道進(jìn)行查詢,關(guān)注我們,繼續(xù)學(xué)習(xí)!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI