실제 설계와 연습 읽기 및 쓰기 장면 HBase를

배경

이 프로젝트는 체크를 해결하고 장 역사 시트 opinion2 온라인 쿼리 (히스토리 데이터는 전체 공정 및 프로세스 데이터의 중간 결과 사업이 발생을 의미한다). 오라클은 데이터의 양이 증가, 스토리지 서비스를 제공하는 원래의 쿼리를 기반으로, 성능 문제는 비즈니스 문의는 쓰기와 읽기, 기록 데이터의 과정에서 직면하고 여기에서 시스템 구조의 실제 프로세스에 영향을주지 않습니다 배치 중쇄 업스트림. 다운 스트림 하둡 배치이 항목은이 요구 사항을 달성하기 위해 플랫폼을 처리하는 데이터를 배포했습니다. 일부 특정 수요 지표 아래에 나열된 :

  1. 데이터의 양은 다음 5천w + 라인 11기가바이트 데이터 검사 테이블의 현재의 총량 300 만 100기가바이트 대한 데이터 테이블 의견 +의 누적량. 만 삽입, 업데이트하지 + 테이블 행 당 000 (500)에 대해 매일 증가.
  2. 검색 : 기본 키 검사 테이블 (오라클 글로벌 ID)의 필요성이 해당 레코드를 목록으로 돌아가려면, 그래서 쿼리 키가 check_id는, 여러 레코드에 해당하는 check_id입니다 ID입니다, 기본 키의 의견 테이블 ID입니다, 문의 키와, bussiness_no 및 buss_type입니다 리 목록을 반환했습니다. 목록 단일 쿼리 반환 약 50 이하의 크기, 약 100 T / 일, 질의 응답 시간 2 초의 질의 주파수.

기술 선택

데이터 쿼리의 양은 분산 플랫폼에 저장된 대량의 데이터와보기를 요구하고, HBase를위한 선택의 구성 요소의 실시간 쿼리 기능을 제공합니다. 예비 조사 및 평가 이후의 요구에 따라, 거의 차 저장 성분으로서 HBase와를 결정한다. 작성 및 HBase를 두 부분을 읽기의 해체에 대한 수요.

HBase를 비교 프로그램은 비교적 기본적인 디자인의 요구에 따라 결정될 RowKey 판독하고, HBase를 제공 ​​(주사 얻을 등) 리치 API에 따라 상기 데이터를 판독하는 성능 요건을 충족.

HBase를 다음이 일반적으로 작성하는 방법입니다 :

  1. 자바는 HBase를 네이티브 API, HTable.add (목록 (넣어))를 호출합니다.
  2. MapReduce의 작업은, TableOutputFormat 출력으로 사용된다.
  3. 벌크 지속성 HFILE HBase를 내부 데이터 포맷에 따라 제 1 데이터 파일을 생성하는로드, 다음 적절한 위치에 복사 통지 RegionServer는 대량 데이터 저장이 완료된다. HFILE를 생성하는이 단계의 MapReduce 또는 스파크를 선택할 수있다.

본 논문에서는 세 번째 방법, 스파크 + 대량로드 쓰기 HBase를합니다. 이 방법은 다른 두 가지 방법은 다음과 같은 장점이 상대적입니다 :

  1. 벌크로드는 WAL를 작성하지, 그것은 플러시 및 분할을 생성하지 않습니다.
  2. 우리는 데이터를 삽입 할 PUT 인터페이스의 큰 번호로 전화를 걸 경우, GC 작업의 큰 숫자가 발생할 수 있습니다. 성능에 영향을 미치는뿐만 아니라, 시간이 심각한을 가질 수 심지어 그러한 우려를 벌크로드를 사용하여, HBase를 노드의 안정성에 영향을 미치지 않습니다.
  3. 인터페이스의 많은없이 프로세스 소비 성능을 호출합니다.
  4. 스파크는 컴퓨팅 파워를 활용할 수 있습니다.

다음과 같이 설명 :

빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase

디자인

환경 정보

하둡 2.5 - 2.7 
HBase를 0.98 . 6 
스파크 2.0 . 0 - 2.1 . 1 
Sqoop을 1.4 . 6

테이블 디자인

이 세그먼트는 RowKey 가장 중요한 부분 인 디자인 HBase를 테이블 토론에 초점을 맞추고 있습니다. 그림의 편의를 위해의 데이터 형식을 살펴 보자. 다음 예제, 의견 공감을 확인합니다.

검사 테이블 (원래 테이블 필드 (18)는 설명의 편의를 위하여, 본원에 5 개 개의 필드는 한 개략 단면도로부터 선택된다)

빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase

상술 한 바와 같이, 기본 키가 ID 32 개 문자 및 임의 성분의 수이고, 서비스 쿼리 필드 check_id는 가변 길이 필드 (이상 32), 문자 및 숫자 같은 check_id는 복수의 레코드, 다른 관련 사업 분야에 해당 할 수있다 . 우리 모두 알다시피, HBase를 기반으로 RowKey가에 대한 액세스를 제공하고, RowKey가 고유해야합니다. 주요 고려 사항을 설계 RowKey하면 데이터에 액세스 할 방법입니다. 예비보기, 우리는 디자인의 두 가지 종류가 있습니다.

  1. 다른 테이블에 인덱스 테이블의 RowKey의 check_id 같이, 각각의 열 번호를위한 하나의 상기 표에 대응하는 체크 열로 두 테이블은 RowKey 같은 테이블 ID로 분할. 쿼리는 먼저 ID 목록이 해당 check_id 찾은 다음 ID를 기반으로 해당 기록을 발견했다. HBase와는 GET 작업입니다.
  2. 이 수요는 다양한 쿼리보다는 하나의 쿼리로 볼 수 있습니다. 접두사로 check_id RowKey는 ID로 하였다. 검사에게 startRow 및 stopRow 쿼리를 설정, 해당 레코드 목록을 찾을 수 있습니다.

첫 번째 방법은 RowKey의 결점은 1) 데이터 기록은 하나의 라인에 2 개 테이블을 기록 할 수있는 원래의 데이터 요구 인 설계 쉽고 단순한 테이블 구조의 장점은, 상기 인덱스 테이블이 존재하는 경우, 존재 RowKey를 기록하기 전에 요구되는 검사 읽을 때 다음 그렇지 않으면 새 행을 만들 추가, 2), 목록의 경우에도 사용, 또한 적어도 두 번 테이블을 읽을 필요가있다. 두번째 설계 방법은 RowKey 설계는 더 복잡하지만, 기록 및 판독은 일회용이다. 함께 찍은, 우리는 두 번째 디자인을 사용합니다.

RowKey 디자인

핫 이슈

HBase를 줄에 일반적으로 뜨거운 이슈 클라이언트 직접 클러스터 노드에 접근, 또는 거의 많은 수의 발생 RowKey의 사전 편찬 종류입니다. 기본적으로 테이블의 건설의 시작에, 테이블은 하나의 지역이 될 것이며, 부하 공유 있도록 많은 지역에 지역 분할로 증가,이 지역은 여러 regionserver에 분산 될 수있다. 우리의 비즈니스 요구를 들어, 데이터의 큰 주식을 가지고, 그것은 각 regionserver에 처음의 HBase와 부하 동일한 주에서 필요하며, 사전 분할을 할 수 있습니다. 식염은 포커스 제어 해시 해시 방법 인, 자기 통전 부분 (예를 들어, 타임 스탬프)를 튀긴다.

RowKey 디자인

1 단계는 : HBase를 표를 작성, 사전 파티션의 수를 결정

다른 비즈니스 시나리오는 개인적으로 우리는 데이터 크기 및 클러스터 크기 및 기타 요인의 양을 고려해야한다고 생각합니다, 데이터의 수와 특성이 다른 방법을 결정합니다. 11G 검사 테이블 크기, 10 테스트 시스템의 클러스터 크기에 대해 예를 들어, hbase.hregion.max.filesize은 3G (이 수가 2로 영역의 크기, 분할을 초과하는 경우)이있다 = 해당 영역 초기화 (하지 최대 스플릿) 1 ~ 2G의 크기는, 11G / 2G = 6 일이지만 위해 할당 영역 데이터는하기 표 10 개로 분할 확인 클러스터 자원을 최대한 활용한다. 데이터 (100G)의 양이 증가하는 경우와, 100G / 2G = 50 이상에 해당하는 영역의 수를 증가 변하지 클러스터링. 다음과 같이 테이블 문 내장 HBase를 체크 테이블 :

생성 ' tinawang : 체크 ' , 
{NAME => ' F를 ' , COMPRESSION => ' 푸석 푸석한 ' , DATA_BLOCK_ENCODING => ' FAST_DIFF ' , 블룸 필터 => ' ' }, 
{스플릿 => [ ' 1 ' , ' 2 ' , ' 3 ' , ' 4 ' , ' 5 ' , ' 6 ' , '7 ' ,' 8 ' , ' 9 ' ]}

상기 식에서, 열 가족 = 'F', 더 짧은.

COMPRESSION => '푸석 푸석한'는 HBase를 세 압축 LZO, GZIP 기운찬을 지원한다. GZIP 압축 속도하지만 CPU를 소비한다. 거의 2 후, 뭐 이따위가 거의 CPU의 GZIP보다 적은 것을 소비하는 승리. 일반 IO 및 CPU의 균형, 뭐 이따위을 선택합니다.

DATA_BLOCK_ENCODING는 => 'FAST_DIFF'RowKey 가까이이 경우는, 키의 길이는 다음의 명령을 사용하여 상대적으로 긴 값을 참조한다.

./hbase org.apache.hadoop.hbase.io.hfile.HFile -m -f / 애플리케이션 / HBase를 / 데이터 / 데이터 / tinawang / 체크인 / a661f0f95598662a53b3d8b1ae469fdf / F / a5fefc880f87492d908672e1634f2eed_SeqId_2_

 

 

2 단계 : RowKey 구성

소금

그래서 분할 전, check_id 키와 함께 각 지역에 대한 데이터의 균형 분포, 우리 쿼리 테이블 패딩 데이터 그 해시 코드의 접두사와 같은 값, 다음 계수 (numRegions), 메모를 추구하는지 확인하기 위해.

StringUtils.leftPad (Integer.toString를 (Math.abs (check_id.hashCode () %의 numRegion)), 1 , ' 0 ')

참고 : 데이터가 2 자리, 소금 또한 2 개 이상의 백 G, 자연 numRegions에 달했다합니다.

해시 해시

check_id 자체가 데이터의 해시와 같은 숫자의 가변 길이의 문자열, 비교적 용이 RowKey 문의하므로, 우리는 check_id로 SHA1 해시를 사용하고 32 비트의 고정 길이의 기술.

MD5Hash.getMD5AsHex (Bytes.toBytes (check_id))

고유성

위의 소금 + 해시 RowKey 접두사 플러스 보증 고유성에 대한 기본 키 테이블 ID 체크 RowKey으로. 다음과 같이 요약하면, RowKey 디자인 체크 테이블은 다음과 같습니다 (check_id = A208849559)

빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase

'|'와 같은 가독성을 향상시키기 위해, 중간은 또한 '+'로, 사용자 정의 구분 기호를 추가 할 수 있습니다.

7 + + 7c9498b4a83974da56b252122b9752bf 56B63AB98C2E00B4E053C501380709AD

추가의 염 + 해시 프리픽스 값이 결정되고, 각각의 질의를 위해 설계된, 동일한 영역에 속한다. 주 검사 테이블의 각 열은 각 열에 저장 Oracle 테이블에서 동일한 검사 데이터 소스 HBase를 것이다.

웹 쿼리 디자인

RowKey 디자인과 밀접하게 관련 쿼리는 쿼리 스캔을 완료, 스캔 [startRow, stopRow]에 쿼리를 제공함으로써 RowKey 디자인, 상기 내용을 토대로 반대로 RowKey을 결정했다. 프리픽스도 그 염 + 해시 계산의 원리 RowKey 설계에있어서, check_id = A208849559 예를 확인한다.

startRow = 7 + 7c9498b4a83974da56b252122b9752bf 
stopRow = 7 + 7c9498b4a83974da56b252122b9752bg

 

핵심 프로세스의 코드 구현

HBase와에 스파크 쓰기

Step0 : 작업 준비

데이터 상류 트래픽을 수신 시스템 때문에, Sqoop을을 사용하여 재고 데이터는 HDFS를 펌핑, 매일 ftp 사이트 파일에서 얻은 증분 데이터의 형태로. 트래픽 데이터 필드 개행 sqoop1.4.6들을 포함하기 때문에 현재는 단일 바이트를 지원하는 라인 구분자로 컬럼 분리 등이 선택 '하는 0x01', '0x10을'그래서.

1 단계 : 스파크는 HDFS 텍스트 파일을 읽을

빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase

SparkContext.textfile () 기본 라인의 구분은 "\ n", 우리가, 당신은 구성에서 구성해야 "을 0x10"를 사용 곳입니다. 응용 프로그램 구성, 우리는 그들이 네트워크 순서에 대한 것을 제외하고 LongWritable 및 텍스트 하둡 긴 문자열 유형과 유형에 JavaPairRDD을 반환, (모든 하둡 데이터 유형 및 자바 데이터 유형이 매우 유사하다을 파일을 읽을 수 newAPIHadoopFile HDFS 메소드를 호출 등) 특수의 최적화를 수행합니다. 우리는 텍스트를 참조 값의 pairRDD의 데이터 파일을해야합니다. 처리 이후의 편의를 위해 JavaPairRDD JavaRDD <문자열>로 변환 할 수 있습니다.

2 단계 : 이전 및 종류 RDD

① 변환 avaRDD <문자열>에 JavaPairRDD <tuple2 문자열>의 파라미터 RowKey, (COL) 값으로 표현 된 것을 특징으로한다. 기본적인 원리는 HBase를 RowKey 주문 및 기초하기 때문에 전환이 그렇게하고, 각 파티션 스파크 필요한 데이터 파티션 (지역)에 사전 기록 데이터를 복수 이용하여 대량로드 모드가 정렬 될 때, RowKey 열 가족 ( CF), COL 이름은 질서가 필요합니다. 이 경우, 하나 개의 열 클러스터 때문에, 그래서 키 Tuple2 형식으로 외부 조직 RowKey 및 COL 이름입니다. 참고 원래 데이터베이스의 행 (N 필드)은, 다음에 n 행으로 분할되어있다.

② 보조 정렬 RowKey, COL 기반 JavaPairRDD <tuple2, 문자열>. 당신은 정렬을하지 않으면, 그것은 다음과 같은 예외를보고됩니다 :

때 java.io.IOException가 : 이전 키보다 더 notlexically 큰 키를 추가

JavaPairRDDhfileRDD HFILE 요구 사항에 데이터를 구성 ③.

3 단계는 : HBase를에 HFILE 및 대량로드를 생성

saveAsNewAPIHadoopFile 주요 메소드를 호출 ① :

hfileRdd.saveAsNewAPIHadoopFile (hfilePath, ImmutableBytesWritable.class, 
KeyValue.class, HFileOutputFormat2.class, 구성);

HBase를에 ② hfilebulk로드

최종 작업 작업 = Job.getInstance를 (); 
job.setMapOutputKeyClass (ImmutableBytesWritable.class); 
job.setMapOutputValueClass (KeyValue.class); 
HFileOutputFormat2.configureIncrementalLoad (작업, htable); 
LoadIncrementalHFiles bulkLoader = newLoadIncrementalHFiles (구성); 
bulkLoader.doBulkLoad (newpath을 (hfilePath) htable);

참고 : 클러스터가 Kerberos를 설정 한 경우, STEP4 필요가 ugi.doAs을 배치하기 () 메소드는, 다음과 같은 검증을 수행 한 후 구현

또한 UserGroupInformation = UserGroupInformation.loginUserFromKeytabAndReturnUGI (keyUser, keytabPath); 
UserGroupInformation.setLoginUser (도);

60010 포트 액세스 HBase를 클러스터 웹, 당신은이 지역의 분포를 볼 수 있습니다.

 

 

HBase를에서 읽기

본 논문에서는 웹 클라이언트 액세스는 HBase를 봄 부트 프레임 워크를 기반으로 데이터를 개발.

사용 연결 풀 (연결 풀)

연결이 상대적으로 무거운 작업입니다 실제 HBase를 프로젝트에서, 우리는 캐시, 지역 서버와 마스터의 메타 정보를 연결, 공유 ZK에 연결 풀링을 소개 만듭니다.

HConnection 연결 = HConnectionManager.createConnection (구성); 
HTableInterface 테이블 connection.getTable (= " 표 1 " ); 
{시도 
    // 단일 작업 및 단일 스레드를 위해, 필요에 따라 사용 테이블을 
마지막으로 {} 
    table.close (); 
}

다음 방법은 기본 스레드 풀을 대체 할 수 있습니다

HConnection createConnection (org.apache.hadoop.conf.Configuration의 conf, ExecutorService를 풀);

공정 쿼리

1 단계는 : 쿼리에 따르면, 접두사는 결정 RowKey입니다

3.3 RowKey 디자인 프리젠 테이션, HBase를 쓰기에 따르면 및 설계 규칙을 따라 읽습니다. 여기에서 우리는 해당 RowKey 접두사로 변환 같은 방법 들어오는 호출자 웹 쿼리를 사용합니다. 예를 들어, 쿼리는 검사 테이블 check_id = A208849559 위에 생성 프리픽스 7 + 7c9498b4a83974da56b252122b9752bf 전송.

2 단계는 : 스캔 범위를 결정

질의 결과에 대응 RowKey A208849559 데이터, 즉 7 + 7c9498b4a83974da56b252122b9752bf 접두사 RowKey에 대응하는 값.

scan.setStartRow (Bytes.toBytes (rowkey_pre)); // 주사 7 + 7c9498b4a83974da56b252122b9752bf 
바이트 [] = stopRow Bytes.toBytes (rowkey_pre); 
stopRow [stopRow.length - 1 ] ++ ; 
scan.setStopRow (stopRow); // 7 + 7c9498b4a83974da56b252122b9752bg

3 단계는 : 쿼리 결과는 구성 객체를 반환

대상물을 이송 ResultScanner는 데이터의 각 행은 테이블 엔티티 반환리스트의 구성에 대응하는 캡슐화된다.

테스트

모의 시험을 위해, 세 개의 연속 요청은 에러율 제로, 2000 (200 동시 스레드, 10 사이클), 51ms의 평균 응답 시간을 개시하고, 원래의 랜덤 1,000 check_id로부터 데이터를 가져.

빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase

빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase빅 데이터 쿼리 디자인과 연습 읽기와 쓰기 --HBase

테스트의 상기 N 개의 회 누적 경험 한 후, 각 영역에 대한 요청의 수는 가까운 라인에 부하가 설계 시작 밸런싱된다.

기록은 구덩이를 강화

도 1은 인증 문제를 KERBEROS

클러스터가 보안 인증을 열면, 스파크 작업을 만들기 제출 될 때 액세스 HBase를, Kerberos 인증에 대한 필요성을 모두.

본 논문에서는 실 클러스터 모드는 일반 작업에 제출으로 다음과 같은 오류를보고 할 수있다.

오류의 startApp : 작업 실패, 
java.lang.NullPointerException이 
    com.tinawang.spark.hbase.utils.HbaseKerberos에서. <초기화> (HbaseKerberos.java : 18 ) 
    com.tinawang.spark.hbase.job.SparkWriteHbaseJob.run (SparkWriteHbaseJob.java 일 : 60 )

다음과 같이 HbaseKerberos.java:18 타겟팅, 코드는 다음과 같습니다

this.keytabPath = (.는 Thread.currentThread () getContextClassLoader ()의 getResource (prop.getProperty. ( " hbase.keytab " ))) getPath ().;

키 탭 파일이 --files 업로드하여 추가 인증이 필요하므로 HBase와의 연결을 집행 인은, 당신이 얻을 수 --keytab 업로드 tina.keytab하지 HBase를 인증 프로그램 블록에 의해 재 인증 할 필요가 있기 때문이다. 개략적으로 다음과

--keytab / 경로 / tina.keytab \
 - 주요 [email protected] \
 --files " /path/tina.keytab.hbase "

Tina.keytab.hbase 복사 tina.keytab 및 이름을 바꿀 유도된다. 스파크 중복 업로드에게 같은 파일을 허용하지 않기 때문에.

2, 시퀀스

org.apache.spark.SparkException : 작업 직렬화하지 
    : org.apache.spark.util.ClosureCleaner $ .ensureSerializable (ClosureCleaner.scala에서 298 ) 
    org.apache.spark.util.ClosureCleaner $ .ORG $ 아파치 $ 스파크 $의 폴더의 유틸리티에서 : $ ClosureCleaner $$ 청소 (ClosureCleaner.scala 288 ) 
    : org.apache.spark.util.ClosureCleaner $ .clean에서 (ClosureCleaner.scala 108 ) 
    : org.apache.spark.SparkContext.clean에서 (SparkContext.scala 2101 ) 
    에서 org.apache.spark.rdd.RDD $$ anonfun $ $지도 1 : .apply (RDD.scala 370 ) 
    anonfun $ $지도 $$ org.apache.spark.rdd.RDD에서 1 .apply을 (RDD.scala : 369 ) 
    ...
org.apache.spark.deploy.yarn.ApplicationMaster $$ 곧 $ 2 .RUN은 (ApplicationMaster.scala : 637 ) 
: java.io.NotSerializableException :에 의한 org.apache.spark.api.java.JavaSparkContext 
직렬화 스택 :
     - 객체를 직렬화 할 수없는 (클래스 : org.apache.spark.api.java.JavaSparkContext, 값 : org.apache.spark.api.java.JavaSparkContext@24a16d8c)
     - 필드 (클래스 : com.tinawang.spark.hbase.processor.SparkReadFileRDD, 이름 : SC, 유형 : 클래스 org.apache.spark.api.java.JavaSparkContext)를 
...

해결 방법 1 :

멤버 변수로 SC 클래스 과정에서 참조하는 경우, 과도 키워드를 추가하지 않도록 직렬화 할 수 있습니다.

개인 과도 JavaSparkContext 사우스 캐롤라이나;

해결 방법 2 :

클래스가 직렬화 구현 RDD 동작 동안 관한 SC는, 매개 변수로 전달. 코드, 두 번째 방법. 코드를 참조하십시오.

(3) 시험 배치를 요청할

예외  스레드 " HTTP-NIO-8091-채택-0 " java.lang.NoClassDefFoundError가 : 조직 / 아파치 / 바람둥이 / 폴더의 유틸리티 / ExceptionUtils

또는

예외  스레드 " HTTP-NIO-8091-간부-34 " java.lang.NoClassDefFoundError가 : CH / QoS를 / logback / 클래식 / SPI / ThrowableProxy

다음 문제를 검토하고 열려있는 파일이 한계를 초과 할 수있는 프로세스의 문제를 해결.

https://github.com/spring-projects/spring-boot/issues/1106

http://mp.weixin.qq.com/s/34GVlaYDOdY1OQ9eZs-iXg

- ulimit를를 a를 사용하여 열려있는 파일의 각 사용자의 기본 번호는 1024입니다 볼 수 있습니다.

이 양의는 /etc/security/limits.conf 수정 시스템 파일, 당신은 문제를 해결할 수, 파일에 다음을 추가합니다.

  • 소프트 NOFILE 65536
  • 하드 NOFILE 65536

저자 소개

대규모 데이터 처리 및 스파크 HBase와 시스템 설계를 전문으로 왕 딸랑 딸랑, 중국 민생 은행 빅 데이터 개발 엔지니어.

참조

http://hbase.apache.org/book.html#perf.writing

http://www.opencore.com/blog/2016/10/efficient-bulk-load-of-hbase-using-spark/  http://hbasefly.com/2016/03/23/hbase_writer/  https : //로 github.com/spring-projects/spring-boot/issues/1106  http://mp.weixin.qq.com/s/34GVlaYDOdY1OQ9eZs-iXg

 

추천

출처www.cnblogs.com/zz-ksw/p/12522184.html