zz Hive 프로그램의 다섯 가지 힌트를 적으세요.
7266 단어 hive
몇몇 사람들에게 익숙한 최적화 약속은 다음과 같다. Join은 큰 시계를 오른쪽에 써야 한다.transfrom 대신 UDF를 사용하십시오.다음은 5가지 성능과 논리에 관한 문제를 토론하여 더 좋은 Hive 프로그램을 작성하는 데 도움을 드리겠습니다.
전체 정렬
Hive의 정렬 키워드는 SORT BY입니다. 기존 데이터베이스의 ORDER BY와 의도적으로 구별되는 것도 이들의 차이점을 강조하기 위해서입니다. SORT BY는 단일 기기에서만 정렬할 수 있습니다.다음 테이블 정의를 고려하십시오.
CREATE TABLE if not exists t_order( id int, -- sale_id int, -- ID customer_id int, -- ID product _id int, -- ID amount int -- ) PARTITIONED BY (ds STRING);
테이블에서 모든 판매 기록을 조회하고 판매 ID와 수량에 따라 순서를 정합니다.
set mapred.reduce.tasks=2; Select sale_id, amount from t_order Sort by sale_id, amount;
이 검색은 기대하지 않은 정렬을 얻을 수 있습니다.지정한 2개의 Reducer가 배포한 데이터는 (각각의 정렬)일 수 있습니다.
Reducer1:
Sale_id | amount 0 | 100 1 | 30 1 | 50 2 | 20
Reducer2:
Sale_id | amount 0 | 110 0 | 120 3 | 50 4 | 20
상기 검색에 Reduce 키가 없기 때문에,hive는 무작위 수를 Reduce 키로 생성합니다.이렇게 되면 입력 기록도 랜덤으로 다른 Reducer 기계에 분배된다.Reducer 사이에 중복되지 않는saleid 레코드, DISTRIBUTE BY 키워드를 사용하여 배포 키를 sale 로 지정할 수 있음id.개조된 HQL은 다음과 같습니다.
set mapred.reduce.tasks=2; Select sale_id, amount from t_order Distribute by sale_id Sort by sale_id, amount;
이렇게 하면 조회된 판매 기록 집합에서 판매 ID에 대응하는 수량이 정확하게 정렬되지만 판매 ID가 정확하게 정렬되지 못한다. 왜냐하면 Hive는hadoop의 기본적인HashPartitioner로 데이터를 나누어 주기 때문이다.
이것은 전체 순서의 문제와 관련된다.해결 방법은 두 가지에 불과하다.
1) 데이터를 배포하지 않고 단일 Reducer를 사용합니다.
set mapred.reduce.tasks=1;
이 방법의 결함은 리듀스 측이 성능의 병목이 되었고 데이터 양이 많은 상황에서 일반적으로 결과를 얻지 못한다는 데 있다.그러나 실천에서 이것은 여전히 가장 자주 사용하는 방법이다. 왜냐하면 통상적으로 정렬된 조회는 상위권의 약간의 결과를 얻기 위해서이기 때문에limit 자구로 데이터량을 크게 줄일 수 있다.limit n을 사용하면 리듀스 단말기(단기)로 전송되는 데이터 기록 수가 n*(map 개수)로 감소합니다.
2) 전체 정렬이 가능하도록 Partitioner를 수정합니다.Hadoop이 자체로 가지고 있는 Total Order Partitioner (Yahoo!의 Tera Sort 프로젝트) 를 사용할 수 있습니다. 이것은 Reducer에서 질서정연한 데이터를 나누어 주는 개발을 지원하기 위한Partitioner입니다. Sequence File 형식의 파일이 나누어 주는 데이터 구간을 지정해야 합니다.만약 우리가 이 파일을 생성했다면 (/tmp/range key list에 저장되어 있으며 100개의 Reducer로 나뉘어 있음) 상기 검색을
set mapred.reduce.tasks=100; set hive.mapred.partitioner=org.apache.hadoop.mapred.lib.TotalOrderPartitioner; set total.order.partitioner.path=/tmp/ range_key_list; Select sale_id, amount from t_order Cluster by sale_id Sort by amount;
이 구간 파일을 만드는 방법은 여러 가지가 있습니다. (예를 들어hadoop이 자체로 가지고 있는 o.a.h.mapreduce.lib.partition.InputSampler 도구)여기에 Hive로 생성하는 방법을 소개합니다. 예를 들어 id에 따라 질서정연한 t 가 있습니다.sale 표:
CREATE TABLE if not exists t_sale ( id int, name string, loc string );
Saleid로 나누어 주는 구간 파일의 방법은 다음과 같습니다.
create external table range_keys(sale_id int) row format serde 'org.apache.hadoop.hive.serde2.binarysortable.BinarySortableSerDe' stored as inputformat 'org.apache.hadoop.mapred.TextInputFormat' outputformat 'org.apache.hadoop.hive.ql.io.HiveNullValueSequenceFileOutputFormat' location '/tmp/range_key_list'; insert overwrite table range_keys select distinct sale_id from source t_sale sampletable(BUCKET 100 OUT OF 100 ON rand()) s sort by sale_id;
생성된 파일(/tmp/range key list 디렉토리 아래)에서 TotalOrderPartitioner가sale 을 누를 수 있습니다.id는 Reduce 처리 데이터를 질서정연하게 나누어 줍니다.구간 파일이 고려해야 할 주요 문제는 데이터 분배의 균형성이다. 이는 데이터에 대한 깊은 이해에 달려 있다.
피리칼적을 어떻게 만듭니까?
Hive가 엄격한 모드(hive.mapred.mode=strict)로 설정되었을 때 HQL 문장에 피리칼 축적이 나타나는 것을 허용하지 않는다. 이것은 실제적으로 피리칼 축적에 대한 Hive의 지원이 약하다는 것을 설명한다.Join key를 찾을 수 없기 때문에 Hive는 피리칼 부피를 완성하기 위해 1개의 Reducer만 사용할 수 있습니다.
물론 위에서 말한 limit의 방법으로 특정한 시계가join에 참여하는 데이터량을 줄일 수 있지만 피리칼의 의미를 축적해야 하는 수요에 있어 큰 시계와 작은 시계의Join이 조작을 하는데 결과는 여전히 매우 크다. 이때 MapJoin이 가장 좋은 해결 방법이다.
MapJoin은 말 그대로 Map에서 Join 작업을 수행합니다.Join이 작업하는 하나 이상의 테이블을 메모리에 완전히 읽어야 합니다.
MapJoin의 사용법은 조회/하위 조회의 SELECT 키워드 뒤에/*+ MAPJOIN(tablelist)*/알림 최적화기가 MapJoin으로 전환하는 것이다. (현재 Hive의 최적화기는 MapJoin을 자동으로 최적화할 수 없다).그중tablelist는 하나의 표나 쉼표로 연결된 표의 목록일 수 있습니다.tablelist의 시계는 메모리에 읽어들여서 작은 시계를 여기에 써야 합니다.
PS: 어떤 사용자는 MapJoin이 하위 질의에 알 수 없는 BUG가 나타날 수 있다고 말합니다.큰 시계와 작은 시계가 피리 칼의 축적을 할 때 피리 칼의 축적을 피하는 방법은 Join에게 Join 키를 추가하는 것이다. 원리는 매우 간단하다. 작은 시계를 한 열의join 키로 확대하고 작은 시계의 항목을 몇 배로 복제하면 Join 키는 각각 다르다.큰 시계를 무작위로 한 열로 확장합니다.
exist in 자구는 어떻게 씁니까?
Hive는where 자구의 하위 조회를 지원하지 않습니다. SQL에서 자주 사용하는exist in 자구는 고쳐야 합니다.이 개작은 상대적으로 간단하다.다음 SQL 질의 문을 고려하십시오.
SELECT a.key, a.value FROM a WHERE a.key in (SELECT b.key FROM B);
다음으로 덮어쓰기 가능
SELECT a.key, a.value FROM a LEFT OUTER JOIN b ON (a.key = b.key) WHERE b.key <> NULL;
더욱 효율적인 실현은 left semi join을 이용하여 다음과 같이 바꾸는 것이다.
SELECT a.key, a.val FROM a LEFT SEMI JOIN b on (a.key = b.key);
left semi join은 0.5.0 이상 버전의 특성입니다.
Hive에서 Reducer 개수를 어떻게 결정합니까?
Hadoop Map Reduce 프로그램에서 Reducer 개수의 설정은 실행 효율에 큰 영향을 미치기 때문에 Hive가 Reducer 개수를 어떻게 결정하는가가 관건적인 문제가 되었다.유감스럽게도 Hive의 추정 메커니즘이 매우 약하다. Reducer 개수를 지정하지 않은 상황에서 Hive는 하나의 Reducer 개수를 확정하고 다음과 같은 두 가지 설정을 바탕으로 한다.
1. hive.exec.reducers.bytes.per.reducer(기본값은 1000^3)
2. hive.exec.reducers.max(기본값은 999)
Reducer 수를 계산하는 공식은 매우 간단하다.
N=min( 2, / 1)
일반적인 경우, 수동으로 Reducer 개수를 지정할 필요가 있습니다.맵 단계의 출력 데이터량이 입력보다 크게 줄어들 수 있음을 감안하여 Reducer 개수를 설정하지 않아도 매개 변수 2를 재설정하는 것이 필요합니다.Hadoop의 경험에 따라 매개변수 2를 0.95*(클러스터의 TaskTracker 개수)로 설정할 수 있습니다.
MapReduce 작업 병합
Multi-group by
Multi-group by는 Hive의 매우 좋은 특성으로 Hive에서 중간 결과를 활용하는 데 매우 편리하다.예를 들어,
FROM (SELECT a.status, b.school, b.gender FROM status_updates a JOIN profiles b ON (a.userid = b.userid and a.ds='2009-03-20' ) ) subq1 INSERT OVERWRITE TABLE gender_summary PARTITION(ds='2009-03-20') SELECT subq1.gender, COUNT(1) GROUP BY subq1.gender INSERT OVERWRITE TABLE school_summary PARTITION(ds='2009-03-20') SELECT subq1.school, COUNT(1) GROUP BY subq1.school
상기 조회문은 Multi-group by 특성을 사용하여 그룹 by를 연속으로 두 번 데이터를 사용했고 서로 다른 그룹 by 키를 사용했다.이 기능을 사용하면 MapReduce 작업을 한 번 줄일 수 있습니다.
Multi-distinct
멀티-distinct는 타오바오가 개발한 또 다른 멀티-xxx 특성이다. 멀티-distinct를 사용하면 같은 검색/하위 검색에서 여러 개의 distinct를 사용할 수 있는데 이 역시 여러 번의MapReduce 조작을 줄일 수 있다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Spark + HWC로 Hive 테이블을 만들고 자동으로 Metadata를 Atlas에 반영합니다.HDP 3.1.x의 경우 Spark + HWC에서 Hive 테이블을 만들고 자동으로 Metadata를 Atlas에 반영하는 방법이 있습니다. 방법: 전제조건: Hive Warehouse Connector (HWC) ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.