https://issues.apache.org/jira/browse/HIVE-4867

RS operator 를 사용하게 되는 SQL 중에 GBY 를 제외한 나머지 경우에 대해서 발생하는 것으로 RS 의 KEY/VALUE 파트에 데이터가 중복으로 들어가는 문제가 있다. 예를 들어 아래와 같은 쿼리를 돌려보면,

explain select * from src order by key;

TableScan alias: src Select Operator expressions: key (type: string), value (type: string) Reduce Output Operator key expressions: _col0 (type: string) value expressions: _col0 (type: string), _col1 (type: string) Extract

RS 의 key expression 와 value expression 에 동일한 컬럼 _col0 이 각각 들어 있는 것을 확인 할 수 있다. 이는 JOIN 도 마찬가지이다.

explain select * from src a join src b on a.key=b.key;

TableScan alias: b Reduce Output Operator key expressions: key (type: string) value expressions: key (type: string), value (type: string) TableScan alias: a Reduce Output Operator key expressions: key (type: string) value expressions: key (type: string), value (type: string)


이 이슈의 목적은 이렇게 두번씩 중복되어 들어가는 column 을 (KEY 에) 한번만 사용하여 shuffling 데이터를 줄이는 것이다. 

ORDER-BY 는 원래 EXT operator 를 사용하여 VALUE 부분을 꺼내 포워딩 하였지만, 이를 SELECT operator 로 치환하여 KEY,VALUE 에서 값을 꺼내도록 수정하면 된다. 간단해 보이지만 하이브의 X 같은 코드에서는 이런것도 엄청 복잡하다. 아래는 수정된 코드의 일부분.

RowResolver selectRR = new RowResolver(); ArrayList<ExprNodeDesc> selCols = new ArrayList<ExprNodeDesc>(); ArrayList<String> selOutputCols = new ArrayList<String>(); Map<String, ExprNodeDesc> selColExprMap = new HashMap<String, ExprNodeDesc>(); for (int i = 0; i < index.length; i++) { ExprNodeColumnDesc desc; ColumnInfo prev = columnInfos.get(i); String[] nm = inputRR.reverseLookup(prev.getInternalName()); ColumnInfo info = new ColumnInfo(prev); String field; if (index[i] >= 0) { field = Utilities.ReduceField.KEY + "." + keyColNames.get(index[i]); } else { field = Utilities.ReduceField.VALUE + "." + valueColNames.get(-index[i] - 1); } info.setInternalName(field); desc = new ExprNodeColumnDesc(info.getType(), info.getInternalName(), info.getTabAlias(), info.getIsVirtualCol()); selCols.add(desc); selectRR.put(nm[0], nm[1], info); selOutputCols.add(getColumnInternalName(i)); selColExprMap.put(getColumnInternalName(i), desc); } SelectDesc select = new SelectDesc(); select.setColList(selCols); select.setOutputColumnNames(selOutputCols); Operator output = putOpInsertMap(OperatorFactory.getAndMakeChild(select, new RowSchema(selectRR.getColumnInfos()), interim), selectRR); output.setColumnExprMap(selColExprMap);

아래는 이러한 삽질의 결과가 만들어 내는 새로운 plan 이다.EXT 대신 SELECT 가 사용되었다.

TableScan alias: src Select Operator expressions: key (type: string), value (type: string) Reduce Output Operator key expressions: _col0 (type: string) value expressions: col1 (type: string) Select Operator expressions: KEY.reducesinkkey0 (type: string), VALUE._col1 (type: string)

JOIN 은 아직 진행중.
------

SORT BY 의 경우 OP-RR-EXT 가 한 메쏘드 안에서 이루어 져서 상관이 없는데, JOIN 의 경우 각 tag 에 대해 RS 를 다 만든 다음 JOIN 을 만들게 되어 필요한 정보가 누락된다. 즉 KEY.xx 에 대한 column info 를 참조할 수가 없다. 이걸 RR 에 넣자니 schema 도 같이 변경되어 optimizer 에 영향을 줄 것 같고, 그냥 만들자니 alias 정보들이 없어지는데, 이걸 쓰는 데는 없겠지만 무척 찜찜하다.

여튼 고민이 많아지네.
------

parent operator 의 column info 를 참조하도록 수정. 그러나 column expr map 이 문제가 된다. JOIN 의 value 값은 condition expression 에 ExprNodeDesc 형태로 존재하는데, 예전에는 부조건 VALUE 부분을 참조하면 되었지만 이제 KEY 부분도 참조 해야 하므로 관련 코드를 왕창 수정해야 하는 일이 발생. 게다가 column RS 의 expr map 에 들어가는 column name 은 경우에 따라 필드 태그(KEY,VALUE) 가 붙기도 하고(PTF, GBY) 안 붙기도 하는데(JOIN, OBY), 이 column name 값으로 CP 를 수행하므로.. 이하 생략..

----
CP, PPD, Lineage 는 어떻게 해결했지만 (addMappingOnly 로 mapping 만 있고 schema 에는 포함되지 않는 정보를 RowResolver 에 포함시켰음), ReduceSinkDedup, CorrelationOptimizer, SubqueryRewrite 와 같은 무시무시한 부분들이 고장..

----
드디어 완료. 멋짐ㅋ

TableScan alias: b Reduce Output Operator key expressions: key (type: string) sort order: + Map-reduce partition columns: key (type: string) value expressions: value (type: string) TableScan alias: a Reduce Output Operator key expressions: key (type: string) sort order: + Map-reduce partition columns: key (type: string) value expressions: value (type: string) Join Operator condition map: Inner Join 0 to 1 condition expressions: 0 {KEY.reducesinkkey0} {VALUE._col0} 1 {KEY.reducesinkkey0} {VALUE._col0} outputColumnNames: _col0, _col1, _col4, _col5



신고
Posted by navis94

카테고리

분류 전체보기 (31)
Apache Hive (29)

최근에 달린 댓글

최근에 받은 트랙백

태그목록

달력

«   2017/09   »
          1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

티스토리 툴바