15
아꿈사 HADOOP I/O

Hadoop io

  • Upload
    kidoki

  • View
    804

  • Download
    9

Embed Size (px)

DESCRIPTION

Hadoop Chapter 4. I/O

Citation preview

Page 1: Hadoop io

아꿈사 박 기 덕

HADOOP I/O

Page 2: Hadoop io

데이터 무결성 – CRC-32

• CRC-32(순환 중복 검사, Cyclic Redundancy Check)

• 데이터가 처음에 유입되었을 때와 통신 채널로 데이터를 전송할 때 체크섬 계산

• CRC-32 체크섬은 4바이트 long Type이고, 기본 Data는 512바이트 이기 때문에 스토리지 오버헤드는 1% 미만

• 에러가 검출되면 ChecksumException을 발생, 연산 재시도와 같은 예외 처리 필요

• 네임노드에서 손상된 블록 관리, 해당 블록을 다른 클라이언트에게 제공하지 않으며 새로운 복제본을 생성

• LocalFileSystem에서는 클라이언트 측 체크섬을 수행

Page 3: Hadoop io

압축

• 파일 압축은 파일 저장 공간 감소, 데이터 전송 고속화

압축 포맷 도구 알고리즘 파일 확장명 분할 가능 압축 특성 코덱

DEFLATE N/A DEFLATE .deflate No 균등 .DefaultCodec

gzip gzip DEFLATE .gz No 균등 .GzipCodec

bzip2 bzip2 bzip2 .bz2 Yes 공간 최적화 .Bzip2Codec

LZO lzop LZO .lzo Yes/No 속도 최적화 .LzopCodec

LZ4 N/A LZ4 .lz4 No 속도 최적화 .Lz4Codec

Snappy N/A Snappy .snappy No 속도 최적화 .SnappyCodec

Page 4: Hadoop io

압축 - 코덱

• CompressionCodec – createOutputStream(압축), createInputStream(압축 해제)

• 파일 확장명으로 코덱 추론 [예제 4-2]

• 하둡은 lib/native 디렉토리에서 미리 빌드된 32/64비트 리눅스용 원시 압축 라이브러리 제공

• 원시 라이브러리를 사용중이고, 다수의 압축/해제를 수행 중이면 도구를 재사용해 객체 생성 비용을 부분상환하는 CodecPool

사용 고려 [예제 4-3]

Page 5: Hadoop io

압축 – 압축과 입력 분할

• 맵리듀스가 처리할 데이터를 압축하는 방법을 고려할 때, 분할 지원 여부 중요

• HDFS에 1GB의 압축 파일 저장 시 분할 지원하지 않는 gzip의 경우 동작 불가

• 이 경우 맵리듀스에서 확장자명으로 압축방법을 파악하여 파일 분할 진행 하지 않음, 단 지역성 비용 발생

• LZO 파일이라면 색인 도구를 이용 전처리하여 분할 가능

• 분할을 지원하는 압축 포맷 사용 or 비압축 파일 사용

Page 6: Hadoop io

압축 - 맵리듀스

• mapred.output.compress 속성 = true, mapred.output.compression.codec 속성 지정 [예제 4-4]

• SequenceFile 출력 시 mapred.output.compression.type 속성 = 기본값은 RECORD, 레코드를 그룹 방식으로 압축하는 BLOCK 추천

• 비압축 데이터를 읽고 쓸 경우에도 중간 출력을 압축 하는 것이 유리, LZO/Snappy 같은 속도 위주 압축 사용

Page 7: Hadoop io

직렬화

• 직렬화 : 네트워크 전송을 위해 구조화된 객체를 바이트 스트림으로 전환하는 과정

• 역직렬화 : 바이트 스트림을 일련의 구조화된 객체로 역전환하는 과정

• RPC 직렬화 포맷

• 간결성 : 데이터 센터의 가장 희소성이 높은 네트워크 대역폭을 절약하귀 위한 간결한 포맷

• 고속화 : 프로세스 간 통신은 분산 시스템을 위한 백본을 형성하기 때문에 오버헤드가 작아야 함

• 확장성 : 프로토콜은 시간이 지날수록 변경되기 때문에 직관적으로 발전

• 상호운용성 : 다양한 언어로 작성된 클라이언트 지원

Page 8: Hadoop io

직렬화 - Writable

• DataOutput 바이너리 스트림을 쓰기 위한 write(), DataInput 바이너리 스트림을 읽기 위한 readFields() 정의

• 맵리듀스의 타입 비교는 키를 서로 비교하는 정렬 과정이 수반되어 중요

• 하둡은 자바의 Comparator를 확장한 RawComparator 제공

• RawComparator는 객체를 역질렬화하지 않고 스트림으로부터 읽힌 레코드를 구현자의 직접 비교 지원

• WritableComaprator는 스트림으로부터 객체를 역질렬화하고, 객체의 compare() 제공,

Rawcomparator 인스턴스를 위한 팩토리 처럼 동작

Page 9: Hadoop io

직렬화 - Writable

• 자바 프리미티브(가장 기본적인 단위)를 위한 Writable 래퍼 클래스

자바 프리미티브 Writable 구현 직렬화된 크기(bytes)

boolean BooleanWritable 1

byte ByteWritable 1

short ShortWritable 2

int IntWritable

VIntWritable

4

1-5

float FloatWritable 4

long LongWritable

VLongWritable

8

1-9

double DoubleWritable 8

Page 10: Hadoop io

직렬화 – Writable (정수, Bytes)

• 정수 인코딩 시 고정길이 포맷(IntWritalbe, LongWritable)과 가변길이 포맷(VIntWritalbe, VLongWritable)

• 가변길이 인코딩은 숫자값이 균일하지 않기 때문에 공간 절약면에서 좋으며, VIntWritalbe을 VLongWritable로 변환할 수 있다는 장점을 가짐

• BytesWritable의 직렬화된 포맷은 뒤 따르는 데이터의 바이트 길이를 지정하는 정수 필드(4bytes)와 해당 데이터가

뒤 따르는 구조

ex) 3, 5 값을 가지는 길이가 2인 바이트 배열

=> 000000020305

• BytesWritable은 가변적이고 set() 메소드를 호출해 변경 가능

Page 11: Hadoop io

직렬화 – Writable (Text)

• String과의 차이점은 Text는 가변적, Text 인스턴스는 set()를 호출해 재사용 가능

• Text는 String만큼 풍부한 문자열 조작 API가 없기 때문에 toString()을 이용해 String 변환 사용

• Text는 UTF-8 시퀀스를 위한 Writable 구현

• Text 클래스에 대한 참조(indexing)는 인코딩된 바이트 시쿼스에서의 위치관점, String과 같은 문자열 관점이 아님

• 한 바이트 이상을 인코딩하는 문자를 사용하려고 할때 Text와 String 사이의 차이점은 명백하다. [예제 4-5]

Page 12: Hadoop io

직렬화 – Writable (Null, Object, Generic)

• NullWritable은 특별한 타입으로 길이가 0인 직렬화, 즉 읽거나 쓸수 없다.

• 자리표시자로 사용, 맵리듀스에서 값이 사용될 필요가 없을 때 사용, SequenceFile에서 키-값 쌍이 아닌 값으로만 구성된 리스트에서 사용, 불변하는 싱글톤

• ObjectWritable은 하둡 RPC에서 메소드 인자의 반환 타입을 정렬화/역정렬화 하기 위해 사용

• ObjectWritable은 어떤 필드가 하나 이상의 타입을 가질 때 유용

• 타입 수가 적고 미리 알려진 경우에는 타입의 전역 배열을 갖고 배열 참조자를 그 타입에 대한 직렬화된 참조로 사용하며,

공간낭비를 줄임. 이러한 방법이 GenericWritable

Page 13: Hadoop io

직렬화 – Writable (Collection)

• ArrayWritable과 TwoDArrayWritable은 인스턴스 배열과 2차원 배열의 Writable 구현

• 배열의 얕은 복사를 생성하는 toArray() 메소드와 get(), set() 지원

• MapWritable과 SortedMapWritable은 java.util.Map<Writable, Writable>과

java.util.SortedMap<WritableComparable, Writable>의 구현

• 각 키와 값 필드의 타입은 해당 필드에 대한 직렬화 포맷

• 집합과 리스트에 대한 Writable 콜렉션은 없다.

• NullWritable과 MapWritable을 사용 해 집합 표현 가능, 열거형 타입의 집합을 위한 EnumSetWritable 지원

• 단일 타입의 리스트는 ArrayWritable로 표현 가능, 다양한 타입의 리스트는 ArrayWritable을 래핑하는

GenericWritable 적합

Page 14: Hadoop io

맞춤형 Writable 구현

• Writable은 맵리듀스의 데이터 경로의 핵심이고, 바이너리 표현을 튜닝하면 성능상 상당한 효과를 얻을 수 있기 때문에 구현하는 것이 더 이점으로 작용하는 경우가 많음 [예제 4-7]

• HashPartitioner(맵리듀스의 기본적인 파티셔너)는 리듀스 파티션을 선택하기 위해 hashCode() 메소드를 사용하고,

TextOutputFormat은 출력 표현을 위해 키와 값 위에서 toString()을 호출하므로 재정의 필요

• TextPair를 역직렬화 하지 않고, 직렬화된 표현으로 Compare 구현 [예제 4-8]

• TextPair의 첫 번째 문자열만 비교하는 FirstComparator 구현 [예제 4-9]

Page 15: Hadoop io

직렬화 프레임워크

• 맵리듀스 프로그램이 Writable을 사용하지만 의무사항은 아님, 유일한 요구 사항은 각 타입에 대한 바이너리의 표현의 변환

• 이것을 지원하기 위해 하둡에는 플러그인 가능한 직렬화 프레임워크 API 제공

• 하둡은 자바 객체 직렬화를 사용하는 JavaSerialization 클래스 포함하지만, 간결성, 고속화, 확장성, 상호운용성에 대해 만족시키지 못하므로 사용하지 않음

• 코드를 통해 타입을 정의하기보다는 IDL(Interface Description Language)을 사용하여 언어-중립적이고 선언적 방식으로 타입을 정의하는 방식을 사용하기도 한다.