zz Hive 프로그램의 다섯 가지 힌트를 적으세요.

7266 단어 hive
Hive를 사용하면 복잡한 MapReduce 쿼리 논리를 효율적이고 빠르게 작성할 수 있습니다.그러나 일부 경우 데이터 특성에 익숙하지 않거나 Hive의 최적화 약속을 따르지 않으면 Hive 계산 작업이 결과를 얻지 못할 정도로 비효율적으로 변할 수 있다."좋은"Hive 프로그램은 여전히 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 조작을 줄일 수 있다.

좋은 웹페이지 즐겨찾기