Amazon Redshift

DC2, RA3, Serverless, Spectrum
maro's avatar
Oct 25, 2024
Amazon Redshift
Amazon Redshift의 구조와 특징에 대해 알아보고, 실제 사용 시 고려할 점을 따져봅니다.
Amazon Redshift는 일반적인 RDBMS와 처음 설계 목적부터 다르기 때문에 잘못 사용하면 ‘성능도 안 좋은데 비용만 많이 나가는’ 애물단지로 전락할 수 있습니다. 이번에 Redshift의 구조와 특징에 대해 알아보고, 실제 사용 시 고려할 점을 알아보겠습니다.
 

데이터 웨어하우스 Redshift

Redshift는 AWS에서 제공하는 데이터 웨어하우스로 분석용 쿼리를 위해 설계되었습니다. 때문에 데이터를 다루는 방식 자체가 다릅니다. 이로 인한 특징이 어떤 것이 있는지 먼저 살펴보겠습니다.

OLTP vs OLAP

우선 OLTP와 OLAP의 개념을 알아야 합니다. OLTP는 Online Transaction Processing의 약자로 트랜잭션 처리에 초점이 맞춰저 있습니다. 반면, OLAP는 Online Analytical Processing의 약자로 복잡한 분석 쿼리를 효율적으로 처리하는 시스템을 의미합니다.
OLTP는 정확한 처리가 중요하기 때문에 데이터 정합성 확보를 위해 데이터 정규화를 수행합니다. 또, 개별 Row 데이터에 관심이 있으므로 Row를 기반으로 데이터를 다룹니다. 우리가 많이 사용하는 MySQL이나 PostgreSQL 같은 RDBMS들이 여기에 해당합니다.
OLAP는 전체 데이터에서 각각의 column 데이터에 관심이 있으므로 column을 기반으로 데이터를 다룹니다. Redshift는 OLAP용으로 설계된 데이터 웨어하우스입니다.
 

컬럼형 데이터 스토리지

컬럼을 기반으로 데이터를 다룬다는 것이 실제로 많은 차이를 만듭니다. 기존에 알던 OLTP용 열 기반 데이터 베이스에 대한 지식으로 쌓은 사고 방식을 아예 뜯어 고쳐야 할 정도이죠. 한 가지 예를 들자면 Redshift에는 index라는 개념이 없습니다. 그리고 생각해보면 index는 OLAP용 데이터베이스에 맞지 않는 방식입니다. 왜 그런지는 지금부터 행 기반 스토리지와 열 기반 스토리지를 비교하며 알아보도록 하겠습니다.
 
행 기반 스토리지
notion image
행 기반 스토리지에서는 블록에 전체 레코드를 저장합니다. 블록의 크기는 2KB ~ 32KB로 한 블록에 수십 개의 레코드가 들어갈 수 있는 크기로 구성합니다.
 
열 기반 스토리지
notion image
열 기반 스토리지에서는 블록에 컬럼 필드 값을 저장합니다. Redshift의 블록 크기는 1MB이기 때문에 한 블록에 저장되는 데이터 수는 행 기반 데이터베이스에 비해 훨씬 많습니다.
 
OLAP용 데이터베이스에서 열 기반 스토리지가 가지는 특장점은 다음과 같습니다.
  • I/O 횟수가 줄어듭니다.
    • 데이터베이스의 I/O는 블록 단위로 이루어집니다. 분석용 쿼리는 특정 컬럼의 대랑 데이터를 처리해야 하는데 컬럼 별로 블록이 데이터를 관리하면 적은 블록으로도 원하는 데이터를 얻을 수 있습니다.
    • 하지만 특정 레코드의 데이터가 필요한 경우에는 하나의 레코드 값을 위해 여러 블록을 가져와야 하며, 블록의 크기가 클 경우 불필요한 메모리 낭비가 생깁니다. 따라서 OLTP용 데이터베이스에는 적합하지 않습니다.
    • 결국 Redshift의 블록 크기가 일반적인 데이터베이스에 비해 훨씬 큰 것도 이런 특징 때문이라고 볼 수 있습니다.
  • 데이터를 효율적으로 압축할 수 있습니다.
    • 각 블록이 동일한 유형의 데이터를 보유하므로 블록 데이터는 컬럼의 데이터 타입에 맞게 특별히 선택된 압축 체계를 사용할 수 있습니다. 이로 인해 디스크 공간과 I/O를 더욱 줄일 수 있습니다.
  • SortKey가 존재합니다.
    • Redshift는 Index가 아닌 SortKey를 사용합니다.
    • Index는 PK를 기반으로 원하는 데이터를 빠르게 조회(InnoDB 기준)합니다. 하지만 열 기반 스토리지에서는 행 단위로 데이터를 저장하지 않기 때문에 PK를 기반으로 데이터를 찾는다는 것은 여러 블록을 조회해야 한다는 것이기 때문에 원래 목적대로 좋은 성능을 발휘할 수 없습니다.
    • RedShift에서 SortKey를 지정하면 SortKey를 기준으로 데이터를 정렬하여 저장합니다.
      • 각 블록의 최소값과 최대값이 메타데이터로 저장되어 있기 때문에 SortKey를 기준으로 데이터 프루닝할 수 있습니다.
  • Insert가 상대적으로 느립니다.
    • 하나의 로우를 저장할 때도 여러 블록에 접근해야 하기 때문에 I/O가 그만큼 많이 발생합니다. 때문에 행 기반 스토리지에 비해 Insert 성능이 낮을 수 밖에 없습니다.
    • AWS에서는 Insert 대신 COPY 구문을 사용할 것을 권장하고 있습니다.
    • 따라서 Redshift에서 데이터를 로드할 때는 S3나 다른 데이터베이스에 저장된 데이터를 가져오는 것이 바람직합니다. [관련 AWS 문서]
 
확인한 것처럼 Redshift는 분석 성능을 위해 설계되어 있기 때문에 이에 맞춰 사용해야 합니다.
 

Redshift의 성능

Redshfit는 성능 향상을 위해 다양한 기술들을 적용하였습니다. 어떤 기술들이 있는지 확인해보겠습니다.

대용량 병렬 처리(MPP, Massive Parallel Processing)

Redshift의 클러스터는 쿼리를 수신하여 구문 분석하고 실행 계획을 작성하는 리더노드와 이러한 계획을 실행하는 컴퓨팅 노드로 나뉘어져 있습니다.
각 컴퓨팅 노드에는 테이블의 행이 분산 배포되어 있습니다. 분산 배포된 데이터를 각 노드가 쿼리 실행 계획대로 병렬로 처리하고 이를 리더 노드에서 집계하기 때문에 빠른 속도로 대용량 데이터를 처리할 수 있습니다.
데이터 분산을 최적화하기 위해서는 각 테이블마다 적절한 배포키를 설정해야 합니다.
 

데이터 압축

쿼리를 실행하면 압축된 데이터가 메모리에 올라갑니다. 메모리에 올라간 데이터가 적으면 Redshift가 데이터 분석에 더 많은 메모리를 할당할 수 있으므로 데이터 압축이 효율적일수록 좋습니다.
Redshift에서는 AWS의 독점 압축 인코딩 알고리즘인 AZ64를 지원합니다. AZ64는 ZSTD와 비슷한 압축률을 달성하지만 압축 해제 속도가 더 빠릅니다. Redshift에서 실제로 추천하는 압축 인코딩을 보면 문자열을 제외한 대부분의 경우에 AZ64를 추천하는 것을 볼 수 있습니다.
그외 다른 인코딩은 문서에서 확인하실 수 있습니다.
 

쿼리 최적화 프로그램

notion image
Redshift에서는 자동 쿼리 최적화 기술을 제공합니다. 쿼리 실행 엔진에 MPP를 인식하고, 열 중심의 데이터 저장소를 활용하는 쿼리 최적화 도구가 통합되어 있습니다.
 

컴파일 코드

notion image
리더 노드가 쿼리 최적화 프로그램을 통해 최적화된 코드를 컴파일하여 모든 노드에 배포합니다. 쿼리는 C++와 유사한 저수준 언어로 작성되며 컴파일된 각 파일은 세그먼트라고 합니다. 쿼리를 컴파일하면 인터프리터와 관련된 오버헤드가 줄어 런타임 속도가 빨라집니다.
컴파일된 코드는 캐시되어 클러스터의 세션 간에 공유됩니다. 따라서 동일하거나 유사한 쿼리가 실행되면, 컴파일된 세그먼트는 클러스터 코드 컴파일 캐시에서 재사용됩니다.
 
서버리스에서는 더 뛰어난 성능의 새로운 컴파일 기능을 제공합니다. [AWS Blog]
  • 새로운 서버리스 컴파일 기능은 쿼리 컴파일 시간을 2~3배 개선한다.
  • 무제한 캐시를 제공하여 컴파일 코드 캐시 적중률을 99.60%에서 99.95%로 높인다.
  • 컴파일해야 하는 경우에는 확장형 컴파일 팜이 코드를 동시에 컴파일하여 워크로드 처리 속도를 빠르게 한다.
  • 87%의 경우 클러스터의 로컬 코드 캐시에 없는 오브젝트 파일이 외부 코드 캐시에서 발견된다.
 

결과 캐싱

Redshift에서는 특정 유형의 쿼리 결과를 리더 노드의 메모리에 캐시합니다. 따라서 사용자가 쿼리를 제출하면 먼저 결과 캐시에서 유효한 쿼리 결과 사본이 있는지 확인합니다.
캐시 사용 여부를 확인하려면 SVL_QLOG 시스템 보기를 쿼리하면 됩니다. SVL_QLOG 뷰에는 데이터 베이스에 대해 실행한 모든 쿼리의 로그가 포함되어 있습니다.
 

AQUA

notion image
AQUA는 2021년에 정식 출시된 기능으로 저장 레이어에서 데이터를 처리하여 네트워크 트래픽을 줄이고 성능을 향상시키는 기능입니다. Redshift Managed Storage(RMS)에 고속 캐시를 더하여 여러 AQUA 노드에서 병렬로 데이터를 처리한 후 클러스터로 데이터를 전송하는데 이로 인해 전송하는 데이터 양이 훨씬 줄어들게 됩니다.
우선적으로 LIKE와 SIMILAR TO 연산에 대하여 데이터 처리를 지원하며 이에 대해 최대 10배의 성능을 제공합니다.
 

배포 스타일과 정렬키

notion image
AWS에서는 테이블 설계 모범 사례에서 정렬키와 배포 스타일을 최적화해야 한다고 설명합니다.
배포 스타일은 테이블의 데이터가 클러스터 전체에 분산되는 방식을 나타내는 테이블 속성으로, 시스템에서 병렬 처리 리소스를 효율적으로 할당하는 데 도움이 됩니다. 분산 스타일은 다음과 같습니다.
  • EVEN
    • 리더 노드는 특정 열 값에 상관없이 행을 라운드 로빈 방식으로 조각에 분산시킵니다. EVEN 배포는 테이블이 조인에 참여하지 않는 경우 적합하며, KEY 배포와 ALL 배포 사이에 명확한 선택이 없는 경우에도 적합합니다.
  • KEY
    • 행이 열 1개의 값에 따라 분산됩니다. 리더 노드는 일치하는 값을 동일한 노드 조각에 할당합니다. 조인 키를 기준으로 테이블 페어를 분산시키면 리더 노드가 조인 열의 값에 따라 행을 조각에 공동 배치하기 때문에 공통 열에서 일치하는 값은 물리적으로 함께 저장됩니다. 이렇게 하면 공통 열의 일치하는 값이 물리적으로 함께 저장됩니다.
  • ALL
    • 전체 테이블의 복사본이 모든 노드로 분산됩니다. EVEN 분산이나 KEY 분산은 테이블 행의 일부를 각 노드에 할당하는 반면 ALL 분산은 테이블이 참여하는 조인마다 모든 행을 공동 배치합니다.
정렬 키는 영역 맵 인덱싱을 활용하기 위해 하나 이상의 열을 기반으로 데이터를 구성합니다. 영역 맵은 데이터 단위의 최소값과 최대값을 저장하는 인덱싱 구조로, 불필요한 데이터를 건너뛰는 데 매우 유용하며, 데이터를 정렬하면 영역 맵을 효율적으로 활용할 수 있습니다.
과거에는 이러한 키를 사용자가 명시해야 했지만 이제는 자동 테이블 최적화(ATO)를 통해 자동으로 설정을 최적화할 수 있습니다. ATO는 머신 러닝으로 정렬 및 배포 키를 선택하여 클러스터의 워크로드에 대한 성능을 최적화 합니다.
예를 들어 AUTO 배포 스타일을 지정하면 처음 데이터가 적을 때는 ALL 배포 스타일을 할당합니다. 이후 데이터가 많아지면 기본키를 배포 키로 선택하여 배포 스타일을 KEY로 변경합니다. 혹 배포키로 적합한 컬럼이 없다면 배포 스타일을 EVEN으로 변경합니다.
분산 스타일을 AUTO로 설정해도 괜찮지만 JOIN 등에 사용되는 컬럼이 있다면 분산키로 지정하는 것도 좋습니다. 일반적인 데이터베이스처럼 PK를 설정한다면 전혀 성능 개선에 의미없는 컬럼이 분산키로 설정될 수 있습니다. 문서의 예시를 참고하시면 좋습니다.
 

Redshift 유형

사실 Redshift의 성능 파트는 Redshift 내부에서 동작하는 부분이라 사용자가 개입할 요소가 거의 없습니다. 배포 스타일이나 정렬키, 데이터 압축 인코딩 같은 부분도 머신 러닝을 통해 자동으로 최적화가 잘 되기 때문에 AWS에서도 AUTO로 설정하는 것을 권장하고 있습니다.
지금부터는 실제 사용할 때 선택에 있어서 큰 영향을 줄 수 있는 요소들을 알아보겠습니다. 실제로 성능과 비용, 제공하는 기능에서 차이가 생기기 때문에 이 부분을 잘 고려해야 합니다.
Redshift는 유형별로 3가지로 나눌 수 있습니다.
  • DC2, RA3
  • Redshift Serverless
  • Redshift Spectrum
그럼 하나씩 살펴 보겠습니다.
 

DC2, RA3

프로비저닝 된 노드에는 DC2와 RA3가 있습니다. 초기에는 DC1이 사용되었는데 2017년부터 DC1의 두 배의 성능을 제공한다는 DC2가 서비스되었습니다. 그리고 2019년부터 RA3를 정식 출시하며 훨씬 다양한 옵션과 기능을 사용할 수 있게 되었습니다.
 
  • RMS
notion image
Redshift의 데이터는 별도의 스토리지 계층인 RMS에 저장됩니다. 데이터가 컴퓨팅 노드 외부에 저장되므로 고객이 컴퓨팅과 스토리지에 대해 독립적으로 확장하고 비용을 지불할 수 있습니다. 따라서 용량이 부족한 경우에도 이 때문에 더 비싼 타입의 노드를 쓸 필요가 없습니다. 데이터 저장은 기본적으로 S3를 활용하고 로컬 메모리와 SSD를 캐시로 사용하여 성능과 확장성을 모두 보장한다고 합니다.
그런데 여기서 주의할 점이 있습니다.
  • RMS를 사용하는 노드는 인스턴스 비용과 RMS 비용을 별도로 청구합니다.
  • RMS는 RA3 클러스터 유형과 서버리스 Redshift 서비스에서만 사용할 수 있습니다. DC2 유형은 데이터를 컴퓨팅 노드에 직접 저장합니다.
즉, 비용 계산을 할 때는 노드 유형과 사용 데이터량을 꼭 확인해야합니다. 만약, RA3 유형의 노드를 사용할 때 인스턴스 비용만 생각한다면 예상 밖의 비용 폭탄을 받을 수 있습니다.
 
  • Elastic Resize
notion image
위와 같이 DC2와 RA3는 설계부터 다른 모델입니다. 이로 인해 수평 확장을 할 때도 차이가 생깁니다.
기존 DC 유형의 클러스터들은 노드를 늘릴때 일정 시간 read-only 상태가 되었습니다. 이는 데이터가 노드 내부에 저장되어 있기 때문에 데이터를 복사 혹은 재분배하기 때문입니다.
RA3부터는 RMS를 도입하면서 스토리지 계층과 컴퓨팅 계층이 구분되었기 때문에 위와 같은 문제가 사라졌습니다. 클러스터에 노드가 추가되면 그저 RMS에 연결해주고 새로운 노드는 RMS에서 데이터를 가져오기 때문에 이전 노드들은 아무런 영향 없이 사용할 수 있습니다.
 
  • AQUA
이전에 AQUA 항목에도 설명했듯 AQUA는 RMS에 고속 캐시를 붙여서 스토리지 계층에서 병렬로 데이터를 전처리합니다. 즉, RMS가 필요한 것입니다. 추가 비용없이 지원해주는 기능이지만 RA3.4xl 및 RA3.16xl 노드에서만 사용 가능합니다.
 

Redshift Serverless

프로비저닝된 클러스터와 달리 Redshift Serverless에는 Node나 클러스터의 개념이 없습니다. 자동으로 용량과 스케일링 관리가 되며 쿼리가 실행될 때만 비용을 지불합니다.
설명만 들으면 굉장히 합리적인 것 같지만 꼭 그렇지만은 않습니다. 서버리스의 비용 정책을 보면 서버리스는 RPU(Redshift 처리 단위)로 비용을 책정합니다. 그리고 RPU는 8의 단위(8, 16, 24, 32, 40, 48 등, 최대 512)로 8개 RPU에서 512개 RPU까지 기본 설정을 조정할 수 있습니다. 그러니까 아무리 작게 잡아도 8개는 써야한다는 겁니다.
서울리전이 RPU 하나에 시간당 0.438 달러이고, 쿼리는 최소 60초 요금 기반이기 때문에 아무리 짧은 시간이 걸리는 쿼리도 60초로 계산됩니다. 즉 쿼리 하나에 최소 80원($ 0.438*8/60) 정도 드는 셈입니다. 적은 비용이라고 생각할 수도 있지만 시각화된 대시보드 하나 볼 때마다 최소로 조회 금액 * 차트 수만큼 든다고 생각하면 절대 무시할 수 있는 금액은 아닐겁니다.
여기에 스토리지인 RMS 비용은 당연히 별도입니다.
 

Redshift Spectrum

Redshift에는 데이터를 Amazon Redshift 테이블에 로드하지 않고 Amazon S3의 파일에서 데이터를 쿼리할 수 있도록 해주는 Redshift Spectrum이란 것이 있습니다. Redshift Spectrum 역시 MPP를 채택해 큰 데이터 집합에 대해 매우 빠르게 실행됩니다. 대부분의 처리가 Redshift Spectrum 계층에서 이루어지며, 데이터가 대부분 Amazon S3에 그대로 남습니다. 또한 다수의 클러스터가 Amazon S3의 동일한 데이터 집합에 대해 동시에 쿼리를 실행할 수 있기 때문에 각 클러스터의 데이터를 일일이 복사할 필요가 없습니다.
 

Redshift 비용

DC2

  • 클러스터 비용
이전 세대인 DC2 유형에는 스토리지가 포함되어 있습니다. 따라서 인스턴스 비용만 계산하면 됩니다. 가장 작은 용량인 DC2.Large 인스턴스의 시간당 요금은 USD 0.3로 한달 기준 약 USD 219가 듭니다.

RA3

  • 클러스터 비용 + RMS 스토리지 비용
RA3 스토리지의 경우, ra3.large가 시간당 USD 0.639부터 시작합니다. 여기에 RMS 비용이 GB당 월 USD 0.0261가 듭니다.

S3 + Redshift Serverless

  • 서버리스 비용
Redshift Serverless에 Redshift Spectrum을 통하여 S3의 데이터를 조회하는 방법입니다. 일반적으로 Redshift에 데이터를 넣을 때는 바로 넣지 않고 S3를 거쳐서 넣기 때문에 어차피 필요한 데이터는 S3에 저장되어 있을 것이란 전제로 고려해볼만합니다.
Redshift Spectrum 비용은 Redshift Serverless 사용시 별도 청구되지 않기 때문에 Redshift Serverless 비용만 계산하면 됩니다.(서버리스 RPU 금액에 포함됨) S3에 Apache Parquet 같은 열 형식으로 데이터를 저장하면, Redshift Spectrum에서 쿼리에 필요한 열만 스캔하게 되므로 쿼리 성능을 개선하고 비용을 줄일 수 있습니다.
AWS Kinesis를 사용할 경우, Apache Parquet 형식으로 데이터를 변환하여 S3에 저장할 수 있습니다.

결론

지금까지 Redshift의 구조와 특징을 살펴보았습니다. 같은 Amazon Redshift라는 이름으로 묶여있지만 노드 유형과 서비스에 따라 동작과 비용에 많은 차이가 있었습니다. 확실히 최근 버전인 RA3 그리고 상위 인스턴스 유형인 경우, 다양한 최적화 기술을 통해 성능에 이점이 있지만 비용 구조를 제대로 따져볼 필요가 있었습니다.
Redshift Serverless나 Redshift Spectrum 같은 다양한 옵션도 존재하기 때문에 요구사항에 따라 잘 계산해보고 적절한 방법을 선택해야 하겠습니다.
 
참조
Share article

maro