데이터 블로그

AMAZON REDSHIFT. 데이터 압축1 - 압축 유형

AWS


데이터 압축은 저장 공간과 읽어야 할 데이터를 줄여준다. 따라서 특별한 이유가 없다면 데이터를 압축하도록 구성하는 것이 일반적이다.  Amazon Redshift에서는 열 단위로 압축 유형(인코딩)을 지정하기 때문에 열에 포함된 데이터의 특성에 맞게 압축 유형을 지정해야 한다. 그러기 위해 Amazon Redshift의 압축 유형을 먼저 정리해 본다.



Raw

데이터를 압축하지 않고 원본 그대로 저장한다. 정렬 키(SORTKEY) 및 BOOLEAN, REAL, DOUBLE PRECISION 데이터 형식의 열에서 압축 인코딩 유형을 지정하지 않으면 기본적으로 Raw 인코딩이 선택된다.


  • CREATE TABLE 키워드: raw

  • 적용 가능한 데이터 형식: 모든 데이터 형식



Byte Dictionary

256개의 사전을 만들어, 원래 값을 사전(딕셔너리)의 순번(인덱스)으로 대체하여 저장한다. 사전의 순번은 1바이트를 차지한다. 따라서 반복적으로 나타나는 값이 적을 때 유리하다. 예를 들어, 다음과 같이 시도를 나타내는 열이 있을 때 압축전후 크기를 비교해 보자.


열 값

원본 크기

인덱스

압축된 크기

서울특별시

15

0

1

서울특별시

15

0

1

서울특별시

15

0

1

경기도

9

1

1

경기도

9

1

1

전라북도

12

2

1

전라북도

12

2

1

전라북도

12

2

1

제주도

9

3

1

제주도

9

3

1

제주도

9

3

1

제주도

9

3

1

135


12


데이터를 압축하지 않았을 때는 원본 크기 항목의 총 합인 135 바이트를 차지한다. 하지만 Byte Dictionary 압축을 하게되면 데이터의 크기가 사전의 크기 + (1바이트 x 행수)로 줄어든다. 위 예제에서 사전은 서울특별시(15), 경기도(9), 전라북도(12), 제주도(9)로 구성되어 크기가 45 바이트이다. 그리고 원래 데이터는 모두 사전의 순번으로 대체되므로 1바이트만 차지하게 된다. 따라서 최종 압축된 크기는 45 + (1 x 12) 이렇게 계산을 하여 57 바이트가 된다.


만약 단어의 수가 256개를 초과할 경우, 초과되는 값은 압축되지 않은 형태로 저장된다.


  • CREATE TABLE 키워드: bytedict

  • 적용 가능한 데이터 형식: BOOLEAN을 제외한 모든 형식



Delta

Delta 인코딩은 인접한 값의 차이만 저장하는 식으로 저장 공간을 줄인다. 큰 숫자인 1,000,000,000과 1,000,000,001이 있다고 할 때, 이 두 값을 압축하지 않고 저장하면 각각 4바이트가 필요하다.


여기서 첫 번째 값 1,000,000,000을 기준(플래그)이라고 할 때, 두 번째 값은 기준과의 차이(델타)인 1만 증시키면 얻을 수 있다. 그래서 두 번째 값은 큰 값 대신에 기준과 차이인 1만 저장하게 되고, 그 크기는 1바이트로 줄일 수 있게 된다. 그래서 Delta 인코딩은 날짜/시간 매우 유용하다고 한다. 절대 날짜/시간 값이 아닌, 이전과의 날짜/시간의 차이만 저장하면 되기 때문이다.


세부적으로는 Delta 인코딩은 차이의 크기를 1바이트로 저장하고, Delta32k  인코딩은 차이의 크기를 2바이트로 저장하는 것으로 구분할 수 있다.


AWS 공식 문서의 예제를 살펴보는 것도 이해에 도움이 된다.


  • CREATE TABLE 키워드: delta, delta32k

  • 적용 가능한 데이터 형식: SMALLINT, INTEGER, BIGINT, NUMERIC, DATE, TIMESTAMP



LZO

LZO 인코딩은 LZO 압축 알고리즘을 사용하여 문자열 형식인 CHAR 및 VARCHAR 열에서 유용하다. LZO는 정렬 키로 지정되는 열과 BOOLEAN, REAL 또는 DOUBLE PRECISION 데이터 형식으로 정의되는 열을 제외하고 기본 인코딩이다.


LZO 압축 알고리즘에 대한 추가 정보는 여기서 확인할 수 있다.


  • CREATE TABLE 키워드: lzo

  • 적용 가능한 데이터 형식: REAL, DOUBLE PRECISION, BOOLEAN을 제외한 모든 형식



Mostly

Mostly 인코딩은 정수형 데이터 형식에서 대부분의 값이 주어진 최대 크기보다 작은 값이 저장될때 유용하다. 만약 INT 형식의 열에 가끔 10억 단위의 큰 값이 들어오지만, 대부분 1~10 사이의 값이 저장되는 경우가 여기에 해당된다.


Mostly 인코딩은 범위에 따라 Mostly8, Mostly16, Mostly32로 나뉜다. 주어진 범위를 벗어나는 값은 원본 그대로 저장하고 범위 안의 값이라면 8비트(1바이트), 16비트(2바이트), 32비트(바이트) 중 하나의 크기로 저장된다.


예를 들어, INT 형식에 Mostly8 인코딩을 지정한 경우에서 12는 1바이트, 3000은 4바이트(Mostly8 인코딩의 범위를 벗어나기 때문에) 를 차지한다.


Mostly8, Mostly16, Mostly32 구체적 범위는 아래와 같다.

인코딩

크기

범위

MOSTLY8

1바이트(8비트)

-128~127

MOSTLY16

2바이트(16비트)

-32768~32767

MOSTLY32

4바이트(32비트)

4 bytes



  • CREATE TABLE 키워드: mostly8, mostly16, mostly32

  • 적용 가능한 데이터 형식:

    • Mostly8: SMALLINT, INTEGER, BIGINT, NUMERIC

    • Mostly16: INTEGER, BIGINT, NUMERIC

    • Mostly32: BIGINT, NUMERIC



Runlength

Runlength 인코딩은 연속적으로 나타나는 값을 그 값과 발생 횟수로 구성된 토큰 하나로 대체한다. 예를 들어, Blue, Blue, Blue, Blue, Red, Red, Green, Green, Green 이렇게 값이 연속적으로 나타난다면, 이 값은 (4, Blue), (2, Red), (3, Green) 이런 토큰으로 대체하여 공간을 절약할 수 있다. 여기서 (4, Blue) 토큰은 Blue가 4번 연속적으로 나타났음을 말한다.


  • CREATE TABLE 키워드: runlength

  • 적용 가능한 데이터 형식: 모든 데이터 형식



Text255 및 Text32k

Text255 및 Text32k 인코딩은 Byte Dictionary 인코딩과 유사하게 단어를 사전에 등록하고 원래 단어를 사전의 순번으로 대체하여 공간을 줄여준다. Byte Dictionary와 다른점은 열에 있는 값 전체를 하나로 사전에 등록하는 것이 아니라, 각 단어를 개별로 사전에 등록한다. Text255 인코딩은 디스크 블록마다 먼저 나타나는 단어 245개를 사전에 등록한다. Text32k 인코딩은 사전의 크기가 약 32k에 도달할 때까지 단어를 등록한다. 사전에 없는 나머지 단어는 원본 그대로 저장한다.


  • CREATE TABLE 키워드: text255, text32k

  • 적용 가능한 데이터 형식: VARCHAR



Zstandard

Zstandard 인코딩은 페이스북에서 Zip을 대체할 목적으로 공개한 Zstandard 압축  알고리즘이다. 개인적인 경험으로는 텍스트 형식 데이터의 경우 lzo 보다 압축률이 좋아 보였다. 알고리즘에 대한 자세한 내용은 ZDNet의 “페이스북, ZIP 대체할 압축기술 소스코드 공개” 기사를 참고하자.


  • CREATE TABLE 키워드: zstd

  • 적용 가능한 데이터 형식: 모든 데이터 형식