0754-5.16.2-Hive中使用Substr拆分含中文亂碼字符串報錯異常分析

2021-02-19 Hadoop實操

從上遊Oracle資料庫中導出的攜帶中文亂碼且編碼集為ISO-8859-1的數據文件,將導出的數據文件導入到Hive表,在原始表的基礎上通過創建視圖,按照與上遊接口約定的定長的方式拆分欄位時報錯,異常內容如下:

java.lang.RuntimeException: org.apache.hadoop.hive.ql.metadata.HiveException: Hive Runtime Error while processing row {"col":"0000004287|6413|....
Caused by: org.apache.hadoop.hive.ql.metadata.HiveException: java.nio.charset.UnmappableCharacterException: Input length = 1

1.使用如下SQL語句創建外部表

CREATE EXTERNAL TABLE `test_error_S24`(`col` string COMMENT 'from deserializer')
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
WITH SERDEPROPERTIES ( 'field.delim'='|@|','serialization.encoding'='GBK')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';

2.將異常數據文件加載到創建的外部表中

hadoop fs -put S24_ACCT20200107_error.txt /tmp

執行SQL語句將數據加載到test_error_S24表中

load data inpath '/tmp/S24_ACCT20200107_error.txt' into test_error_s24;

查看數據是否導入表中

3.使用如下SQL語句創建視圖並使用定長方式拆分原始數據

CREATE VIEW `view_error_S24` AS 
select trim(decode(substr(encode(`test_error_S24`.`col`,'GBK'),1,10),'GBK')) as `XACCOUNT`,
trim(decode(substr(encode(`test_error_S24`.`col`,'GBK'),12,4),'GBK')) as `BANK`,
trim(decode(substr(encode(`test_error_S24`.`col`,'GBK'),17,20),'GBK')) as `BUSINESS`,
trim(decode(substr(encode(`test_error_S24`.`col`,'GBK'),38,4),'GBK')) as `CATEGORY`,
...
trim(decode(substr(encode(`test_error_S24`.`col`,'GBK'),2318,11),'GBK')) as `PAYTDY_LMT` from `test_error_S24`;

4.執行Select語句查看數據是否正常拆分時報錯

查看Yarn上詳細日誌如下顯示與第一章節問題描述一致

1.Yarn作業的詳細日誌中有異常 「java.nio.charset.UnmappableCharacterException: Input length = 1」,引起該類異常的主要原因是處理了半個中文導致。

2.為什麼會出現處理半個中文的問題?主要是由於在SQL語句中是通過定長的方式拆分欄位,拆分欄位是通過GBK編碼集的方式進行定長拆分。

3.為什麼拆分字符串會拆出半個中文?通過使用Java代碼讀取異常數據計算每條數據的length進行驗證分析,結果如下:

GBK編碼讀取正常數據,顯示每條數據的長度固定且中文字符未出現亂碼

UTF-8編碼讀取正常數據,顯示每條數據的長度發生變化且中文出現亂碼

通過上述測試發現,主要是由於編碼集原因導致拆分出半個中文的現象。因此在這個場景下要想正確的通過定長的方式解決數據拆分問題,只能以正確的中文編碼集方式處理原始數據。

4.處理中文字符的編碼有GB2312/GBK/GB18030等,常用的GBK和GB2312在這個時候並不能滿足數據的正常解析,在這裡嘗試使用GB18030編碼來對字符解析編碼拆分測試

經過測試發現使用GB18030編碼讀取異常數據文件時,能正確的讀取所有數據且不會出現中文亂碼,通過上述的測試分析這裡考慮在Hive建表及數據拆分時使用GB18030編碼,接下來為問題解決及驗證過程。

1.修改建表語句將編碼集調整為GB18030

CREATE EXTERNAL TABLE `test_gb18030`(`col` string COMMENT 'from deserializer')
ROW FORMAT SERDE 'org.apache.hadoop.hive.contrib.serde2.MultiDelimitSerDe'
WITH SERDEPROPERTIES ( 'field.delim'='|@|','serialization.encoding'='GB18030')
STORED AS INPUTFORMAT 'org.apache.hadoop.mapred.TextInputFormat'
OUTPUTFORMAT 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat';

2.重建視圖,將視圖中的編碼類型修改為GB18030

CREATE VIEW `view_gb18030` AS select trim(decode(substr(encode(`test_gb18030`.`col`,'GB18030'),1,10),'GB18030')) as `XACCOUNT`,
trim(decode(substr(encode(`test_gb18030`.`col`,'GB18030'),12,4),'GB18030')) as `BANK`,
...
trim(decode(substr(encode(`test_gb18030`.`col`,'GB18030'),75,30),'GB18030')) as `ACC_NAME1`,
...
trim(decode(substr(encode(`test_gb18030`.`col`,'GB18030'),2318,11),'GB18030')) as `PAYTDY_LMT` from `test_gb18030`;

3.再次執行Select語句查看視圖已可以正常拆分欄位

1.Hive建表時默認使用UTF-8編碼,在處理中文編碼的數據文件時,需要在建表語句中指定編碼集,否則查詢出來的數據會顯示亂碼。

2.對於通過定長方式拆分字符串的業務,必須知道上遊業務系統的拆分規則,是以UTF-8編碼拆分?還是GBK編碼拆分?還是GB18030編碼拆分?不同的編碼方式計算出來的字符串長度也會有一定的差異。

3.處理中文字符編碼方式有GB2312/GBK/GB1803等,GB18030兼容GBK,GBK兼容GB2312,因此在針對中文的解析時如果出錯,可以使用最新的GB18030編碼集進行解析。

相關焦點

  • PHP中文字符串反轉編碼錯誤解決方式
    在使用PHP處理字符串反轉的時候,我們第一反應是使用PHP的內置函數strrev來處理,思維上是沒有問題的,但是我們需要知道一個問題,函數strrev是否可以處理中文漢字的字符串呢?帶著疑問我們一起來看一下。
  • Hive SQL基本使用詳解
    ", "state3", "zip", 3)) from employeelimit 1;執行insert into select的時候可能會報錯,在hive-site.xml中配置以下兩個參數。hive3.1.2中自己使用insert into values這種語法沒有插入成功。
  • 常用Hive函數的學習和總結
    今天來小結一下工作中經常會使用到的一些Hive函數。關於Hive函數的總結,網上早有十分全面的版本。參考:https://blog.csdn.net/doveyoung8/article/details/80014442。本文主要從最常用和實用的角度出發,說明幾個使用頻率較高的函數,更注重使用函數組合來解決實際問題而不局限於單個函數的使用。
  • hive函數
    以上是小編自己整理分類的,網上也有很多不同分類的版本,下圖就是在別人博客中我覺得比較好的分類方法。rtrim(string1):去右空格reverse(string1):字符串逆置rpad(string1,len1,pad1):字符右填充。lpad():左填充split(string1,pat1):分隔字符串返回數組。如split('a,b,c',',')返回["a","b","c"]substr():截取。
  • Hive(七) ----函數
    substrSELECT substr('www.lagou.com', 5); SELECT substr('www.lagou.com', -5); SELECT substr('www.lagou.com', 5, 5);-- 字符串切分。split,注意 '.' 要轉義select split("www.lagou.com", "\\.")
  • 【乾貨】Hive常用函數大全
    結果的數值類型為double舉例:hive> select40 / 5 from lxw_dual;8.0注意:hive中最高精度的數據類型是double,只精確到小數點後16位,在做除法運算的時候要特別注意hive>select ceil(28.0/6.999999999999999999999) from lxw_duallimit
  • Perl Substr()函數處理字符串
    substr函數隻處理較長字符串中的一小部分內容,它需要三個參數:一個原始字符串、一個從零起算的起始位置,以及子字符串的長度。
  • php中常用的截取整理字符串的幾種方式
    在php代碼中字符串函數是PHP的核心組成部分,有著許多類型對各種字符串處理的一些函數.
  • 【每日一題】php截取字符串幾個實用的函數
    php$str ="phpddt.com";echo substr($str,2);echo substr($str,2,3);echo substr($str,-2);?>但是當你截取中文字符串的時候很容易出現亂碼,因為一個漢字是兩個字節,而一個英文字母是一個字節。
  • HiveSql基礎函數使用(一)
    一、hive函數1、關係函數2、日期函數3、條件函數4、字符串函數5、統計函數二、hiveQL返回輸入字符串連接後的結果,SEP表示各個字符串間的分隔符舉例:select concat_ws(',','abc','def','gh') from dual; ##返回值為abc,def,gh字符串截取函數:substr,substring
  • Hive函數大全(含例子)之字符串函數(String Functions)
    ,未找到或者str中包含逗號則返回0(strList是一個用逗號隔開的字符串)返回類型: intselect find_in_set('and', 'Melon,and,fruit,fields'); -- 結果為 2select find_in_set
  • 工作中使用Hive SQL的幾個知識點(建議收藏)
    hive是基於Hadoop的一個數據倉庫工具,用來進行數據的ETL,這是一種可以存儲、查詢和分析存儲在Hadoop中的大規模數據的機制。hive能將結構化的數據文件映射為一張資料庫表,並提供SQL查詢功能。Hive SQL是一種類SQL語言,與關係型資料庫所支持的SQL語法存在微小的差異。
  • python筆記5-python2寫csv文件中文亂碼問題
    前言python2最大的坑在於中文編碼問題,遇到中文報錯首先加u,再各種encode、decode。
  • awk命指定分隔符輸出字符串///使用bgzip遇到的一個報錯
    awk指定字符分割字符串、指定分隔符輸出字符串遇到的問題使用blasr軟體將三代測序數據比對到參考序列
  • 實例解析Perl substr函數應用
    函數應用,在編寫perl程序的時候,我們有時需要截取一個字符串中的部分內容,這個時候通常會使用substr函數實現這個功能。Perl substr函數應用在編寫perl程序的時候,我們有時需要截取一個字符串中的部分內容,這個時候通常會使用Perl substr函數實現這個功能。viewplaincopytoclipboardprint?
  • Hive與Impala對VARCHAR/CHAR存放中文字符解析不一致問題分析
    Fayson的github:https://github.com/fayson/cdhproject提示:代碼塊部分可以左右滑動查看噢1.異常描述首先我們在hive中創建一個表1create2.異常解決我們擴大CHAR/VARCHAR的長度定義,並引入一個String類型方便比較,再次在Hive中創建一張測試表進行測試。
  • Hive SQL 第一篇:常用的內置函數
    ❝最近使用 hive sql比較多,碰到了很多函數操作,所以想簡單總結一下 hive sql 常用的函數用法,沉澱一下以便之後查閱,希望也能給大家提供一些參考。>字符串反轉函數-- 獲取字符串反轉後的結果,返回string類型-- 用法reverse(string a)-- 示例 & 結果select reverse('abcd');dcba字符串截取函數-- 獲取字符串中的部分子串,返回string類型-- 用法
  • Hive SQL插入動態分區的異常分析
    FAILED: Execution Error, return code 2 from org.apache.hadoop.hive.ql.exec.mr.MapRedTaskMapReduce Jobs Launched:Stage-Stage-1: Map: 1 HDFS Read: 0 HDFS Write: 0 FAILTotal MapReduce CPU
  • 0576-6.1.0-Hive Comment中文亂碼補充
    中如何解決表欄位中文注釋亂碼的問題,為了完善上篇文檔,本文整理Hive表所有與中文注釋相關的屬性項,包括表欄位、分區、表名、視圖中文亂碼,同時包括對該問題的分析。1.CM和CDH版本為6.1.02.Hive的版本為2.1.13.集群已啟用Kerberos4.RedHat7.4在Hive中創建有中文注釋的表時,默認情況下無論是在beeline還是Hue中該注釋顯示都會是亂碼。
  • 一文學會Hive解析Json數組(好文收藏)
    一列中複雜的array或者map結構拆分成多行顯示,也被稱為列轉行函數。注意,在有些情況下要使用轉義字符,類似oracle中的regexp_replace函數。,執行結果如下:www.baidu.com   百度google.com      谷歌二 使用 lateral view 解析json數組hive表中 goods_id 和 json_str 欄位的內容如下:goods_idjson_str1,2,3[