標籤:hive0.13 rows loaded
升級hive0.13之後發現job運行完成後Rows loaded的資訊沒有了。
rows loaded的資訊在hive0.11中由HiveHistory類的printRowCount輸出。HiveHistory類的主要用途是記錄job啟動並執行資訊,包括task的counter等。預設的目錄在/tmp/$user中。
hive0.11在SessionState 的start方法中會初始化HiveHistory的對象
if (startSs. hiveHist == null) { startSs. hiveHist = new HiveHistory(startSs); }
而在hive0.13中HiveHistory是一個抽象類別,其具體的實現在HiveHistoryImpl類中,其中初始化HiveHistoryImpl對象時增加了一層判斷,判斷hive.session.history.enabled的設定(預設為false),導致不會執行個體化HiveHistoryImpl類
if(startSs.hiveHist == null){ if (startSs.getConf().getBoolVar(HiveConf.ConfVars.HIVE_SESSION_HISTORY_ENABLED)) { startSs.hiveHist = new HiveHistoryImpl (startSs); }else { //Hive history is disabled, create a no-op proxy startSs.hiveHist = HiveHistoryProxyHandler .getNoOpHiveHistoryProxy(); } }
在fix這個配置之後,仍然沒有發現rows loaded的資訊,通過分析源碼
printRowCount方法的實現如下:
public void printRowCount(String queryId) { QueryInfo ji = queryInfoMap.get(queryId); if (ji == null) { // 如果ji為空白,則直接返回 return; } for (String tab : ji. rowCountMap.keySet()) { console.printInfo(ji. rowCountMap.get(tab) + " Rows loaded to " + tab); // 從hashmap中擷取資料 } }
在hive0.13中,這裡擷取的ji對象是空值。
近一步發現,是由於counter中沒有TABLE_ID_(\\d+)_ROWCOUNT,導致不能匹配ROW_COUNT_PATTERN的正則。就不能正常擷取的row count的值。
其中擷取tasker count的rows loaded資訊的getRowCountTableName方法內容如下:
private static final String ROW_COUNT_PATTERN = "TABLE_ID_(\\d+)_ROWCOUNT"; private static final Pattern rowCountPattern = Pattern.compile(ROW_COUNT_PATTERN);...... String getRowCountTableName(String name) { if (idToTableMap == null) { return null; } Matcher m = rowCountPattern.matcher(name); if (m.find()) { // //沒有和TABLE_ID_xxxx match的counter導致,即counter沒有列印出TABLE_ID_(\\d+)_ROWCOUNT導致。。 String tuple = m.group(1); return idToTableMap.get(tuple); } return null; }
而TABLE_ID_(\\d+)_ROWCOUNT是由FileSinkOperator類負責寫入的。hive0.11中相關的代碼如下:
protected void initializeOp(Configuration hconf) throws HiveException {.......... int id = conf.getDestTableId(); if ((id != 0) && (id <= TableIdEnum. values().length)) { String enumName = "TABLE_ID_" + String.valueOf(id) + "_ROWCOUNT"; tabIdEnum = TableIdEnum.valueOf(enumName); row_count = new LongWritable(); statsMap.put( tabIdEnum, row_count ); }
而在hive0.13中這部分代碼都被去掉了,找到了原因,fix也比較簡單,把這個counter加回去就可了。
patch如下:
diff --git a/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java b/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.javaindex 1dde78e..96860f7 100644--- a/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java+++ b/ql/src/java/org/apache/hadoop/hive/ql/exec/FileSinkOperator.java@@ -68,13 +68,16 @@import org.apache.hadoop.util.ReflectionUtils;import com.google.common.collect.Lists;+import org.apache.commons.logging.Log;+import org.apache.commons.logging.LogFactory;+/** * File Sink operator implementation. **/public class FileSinkOperator extends TerminalOperator<FileSinkDesc> implements Serializable {-+ public static Log LOG = LogFactory.getLog("FileSinkOperator.class"); protected transient HashMap<String, FSPaths> valToPaths; protected transient int numDynParts; protected transient List<String> dpColNames;@@ -214,6 +217,7 @@ public Stat getStat() { protected transient FileSystem fs; protected transient Serializer serializer; protected transient LongWritable row_count;+ protected transient TableIdEnum tabIdEnum = null; private transient boolean isNativeTable = true; /**@@ -241,6 +245,23 @@ public Stat getStat() { protected transient JobConf jc; Class<? extends Writable> outputClass; String taskId;+ public static enum TableIdEnum {+ TABLE_ID_1_ROWCOUNT,+ TABLE_ID_2_ROWCOUNT,+ TABLE_ID_3_ROWCOUNT,+ TABLE_ID_4_ROWCOUNT,+ TABLE_ID_5_ROWCOUNT,+ TABLE_ID_6_ROWCOUNT,+ TABLE_ID_7_ROWCOUNT,+ TABLE_ID_8_ROWCOUNT,+ TABLE_ID_9_ROWCOUNT,+ TABLE_ID_10_ROWCOUNT,+ TABLE_ID_11_ROWCOUNT,+ TABLE_ID_12_ROWCOUNT,+ TABLE_ID_13_ROWCOUNT,+ TABLE_ID_14_ROWCOUNT,+ TABLE_ID_15_ROWCOUNT;+ } protected boolean filesCreated = false;@@ -317,7 +338,15 @@ protected void initializeOp(Configuration hconf) throws HiveException { prtner = (HivePartitioner<HiveKey, Object>) ReflectionUtils.newInstance( jc.getPartitionerClass(), null); }- row_count = new LongWritable();+ //row_count = new LongWritable();+ int id = conf.getDestTableId();+ if ((id != 0) && (id <= TableIdEnum.values().length)) {+ String enumName = "TABLE_ID_" + String.valueOf(id) + "_ROWCOUNT"; + tabIdEnum = TableIdEnum.valueOf(enumName);+ row_count = new LongWritable();+ statsMap.put(tabIdEnum, row_count);+ }+ if (dpCtx != null) { dpSetup(); }
打完patch後,重新打包,替換線上的hive-exec-xxx.jar包之後測試,rows loaded的資料又回來了。
本文出自 “菜光光的部落格” 部落格,請務必保留此出處http://caiguangguang.blog.51cto.com/1652935/1528516
hive0.13 rows loaded為空白問題源碼分析及fix