1.前言
在進行大數據開發過程中,避免不了遇到數據錯位的情況,出現數據錯位的情況通常處於大數據開發的上游環節,為了保證數據質量需要對Hive表數據進行修復處理,本文由一次真實的Hive數據錯位修復經歷所啟發,在這個基礎上總結和擴展數據錯位發生場景、數據錯位修復思路和修復案例演示demo。
2. 發生數據錯位的場景
首先需要清楚以下2個概念:
1.上游數據來源表為不同渠道的數據,如關系型數據庫MySQL的數據、網站或應用的埋點數據日志和第三方提供的數據等;
2.下游Hive表在這邊主要指的是ODS層的表,即從各個渠道來的數據所抽取到Hive的表。
在將原始數據導入到Hive表的時候可能會發生數據錯位,發生錯位的場景有以下2種
1.數據來源表的結構發生變化
因為不可避免的原因如業務調整或別的不可控因素,上游數據來源表的結構發生了變化,這種表結構的變化包含了數據來源表字段的增加、刪除、修改這3種變化,復雜度依次增加,這些情況都會導致數據錯位。
2.數據的分隔符發生變化
還有因為分隔符導致的數據錯位,第1種情況是切換數據來源之后數據的分隔符和以前的不一致,第2種情況是某些字段中包含了分隔符,這2種情況都會導致數據錯位。
3. 數據修復的思路
我們在上一節已經描述了問題產生的場景,接下來是確定解決問題的思路
3.1 數據來源表結構發生變化情況下的修復思路
在數據來源表結構發生變化的場景中,不管是增刪改中的哪一種情況,核心解決思路是通過建立臨時表對最新數據進行處理再回填到Hive表完成修復。
3.1.1 數據來源表字段增加
如果Hive表的下游加工需要用到新增的字段,則根據新增字段的位置重新建表,並將歷史數據回填到新表,一般情況下新增字段的表結構為在舊表的后面追加新增字段,如果新增字段不在舊表的后面則按照來源表結構新建;如果下游加工用不到新增字段,則建立Hive臨時中間表,表結構與數據來源表一致,把需要的數據從Hive臨時中間表回填到Hive表。
3.1.2 數據來源表字段刪除
如果Hive表的下游加工需要用到刪除的字段,則需要提前通知下游評估影響並反饋解決方案;如果下游未使用刪除的字段,則新建Hive臨時中間表並將數據回填到Hive表中,Hive表結構不變,被刪除字段做置空處理。
3.1.3 數據來源表字段修改(字段名稱或類型發生變化、數據錯位且字段不一致)
數據來源表的字段名稱或類型發生變化,如果Hive表的下游加工需要用到修改的字段,則需要提前通知下游評估影響並反饋解決方案;數據來源表的字段發生數據錯位且字段不一致這種情況比較復雜,需要先將舊數據與新數據的字段名和幾條數據放到同一張Excel表進行比對,再參考完整數據按照舊表字段名來確定新表字段名,盡量保證2種表的共有字段的字段名一致,如果舊表中的字段沒有完全體現在新表中,則需要提前通知下游評估影響並反饋解決方案,如果沒有使用的話在將Hive臨時中間表回填到Hive表的時候將沒用到的字段做置空處理。
3.2 數據分割符發生變化情況下的修復思路
切換數據來源之后數據的分隔符前后不一致的情況,在情況允許的情況下可以先對分隔符進行轉換,然后上傳數據,和上游溝通格式要求。
某些字段中包含了分隔符,如CSV格式文件的部分字段中出現了',' ,這種情況是比較復雜且不合理的,如果還是用英文的逗號的話必然會導致數據錯位,這個需要和上游數據提供方共同約定將分隔符改為其他不常用的字符如 '\t' 或其他不會出現在字段內容中的特殊符號。
4. demo
通過一個數據來源表字段修改的案例來了解怎么進行Hive數據錯位修復,實際情況有時候會非常復雜,但是思路是一致的。
4.1 查看表結構與新舊數據源
Hive表app.student的表結構
app.student 表結構 |
||
字段英文名 |
字段中文名 |
字段類型 |
no |
學號 |
int |
name |
姓名 |
string |
age |
年齡 |
int |
舊數據來源student.dat ,字段分隔符為 '\t'
新數據來源student2.dat ,字段分隔符為 '\t'
4.2 比對新舊數據源字段差異
確認新舊數據源的字段差異,最重要的是判斷舊數據源的字段在新數據源中是否存在且格式是否一致。
4.3 新建Hive臨時中間表
根據新數據來源student2.dat的結構新建Hive臨時中間表
app.student_tmp 表結構 |
||
字段英文名 |
字段中文名 |
字段類型 |
no |
學號 |
int |
name |
姓名 |
string |
gender |
性別 |
string |
age |
年齡 |
int |
hobby |
愛好 |
string |
新建Hive臨時中間表 app.student_tmp 在建表時指定字段分隔符為 '\t',和數據來源的分隔符一致
CREATE TABLE `app.student_tmp`( `no` int, `name` string, `gender` string, `age` int, `hobby` string) ROW FORMAT SERDE 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' WITH SERDEPROPERTIES ( 'field.delim'='\t', 'serialization.format'='\t');
4.4 加載本地數據到Hive臨時中間表
在Hive命令行下執行以上命令將本地數據加載到Hive臨時中間表 app.student_tmp 中。
hive> load data local inpath '/home/share/data/student2.dat' into table app.student_tmp;
4.5 回填數據到Hive表
將數據從Hive臨時中間表回填到Hive表
hive> insert into table app.student select no,name,age from app.student_tmp;
4.6 檢查Hive表數據狀態
查看Hive表數據,已經將數據回填到Hive表中。
5.總結
在進行大數據開發過程中,難免會遇到Hive數據錯位問題,出現問題的原因包含了數據調研不充分和上下游溝通不到位,問題發生之后先讓自己靜下來整理思路,然后再進行修復,最終的目標是為了保證數據質量而不影響下游的加工。