728x90

Point

  • 트랜잭션 처리와 분석
  • OLTP와 OLAP
  • 분석용 데이터 웨어하우스
  • 분석에 용이한 칼럼지향 저장소

 

트랜잭션 처리 혹은 분석

  • 초창기 비즈니스 데이터 처리는 판매, 발주, 급여 발주와 같은 커머셜 트랜잭션 즉 상거래와 같은 데이터 쓰기가 대부분
  • 데이터베이스 처리가 확장되었어도 트랜잭션이란 용어는 그대로 사용되어 이제는 논리 단위 형태로서 읽기와 쓰기 그룹을 나타낸다.
트랜잭션이 반드시 ACID(원자성, 일관성, 격리성, 지속성)을 가질 필요는 없다. 트랜잭션 처리는 주기적으로 수행되는 일괄처리 작업과 달리 클라이언트가 지연시간이 낮은 읽기와 쓰기를 가능하게 한다는 의미이다.

즉 주기적으로 스케줄처리가 되는것과 달리 요청에 따른 응답을 최대한 빠르게(실시간에 가깝게)처리하는 것이 트랜잭션 처리이다.
ACID는 7장에서 일괄처리는 10장에서 다룰 예정이다

 

OLTP VS OLAP

이전에 OLTP와 OLAP에 대해 간단히 정리한 블로그글 : OLTP VS OLAP 기본비교

 

우선 OLTP와 OLAP는 데이터 처리 방식에 대한 개념이다.

OLTP : online transaction processing

  • 특정 사용자를 기준으로 해당 사용자에 대한 정보를 삽입/갱신하는 데이터 처리가 주로 이루어진다
  • 이런 데이터를 처리하는 애플리케이션은 주로 대화식이며, 이러한 접근 패턴을 OLTP라고 한다.
  • OLTP시스템은 실제 서비스 운영에 이용되므로, 높은 가용성과 낮은 지연시간의 트랜잭션 처리를 기대한다.
  • 이런 상황에서 대량의 데이터를 불러오는 분석질의는 OLTP의 성능을 저하한다.
  • OLTP는 로우지향방식으로 데이터를 배치한다. 테이블에서 특정 사용자 즉, pk key값을 기준으로 하나의 로우의 모든 값은 서로 인접하게 저장된다. 이점은 문서 데이터 베이스와 유사하다.

OLAP : online analytics processing

  • 최근 데이터 베이스를 분석용으로도 많이 사용하기 시작했다. 분석은 트랜잭션과는 접근 패턴이 매우 다르다.
  • 분석 시에는 많은 레코드를 한번에 집계해온다.
  • 분석 질의는 원시 데이터를 반환하는 것이 아니라 많은 수의 레코드를 스캔해서 레코드당 일부 칼럼만 읽어 집계통계를 계산해야 한다.
  • 예를 들어 1월의 매장의 총 수익은? 최근 프로모션 기간동안 얼마나 많은 바나나를 판매햇는가 같은 데이터를 추출할때
  • OLAP에서 사용되는 칼럼지향 방식은 모든 값을 하나의 로우에 저장하지 않는다. 각 칼럼별로 모든 값을 함께 저장한다. 각 칼럼을 개별 파일에 저장하면 질의에 사용되는 칼럼만 읽고 구분 분석하면 된다.

 

데이터 웨어하우징

기업에는 수십가지의 트랜잭션 처리 시스템을 필요로 한다. 고객대면 웹사이트 강화, 판매관리 시스템 등 다양한 종류의 데이터가 처리된다.

이렇듯 OLTP시스템은 대개 사업 운영에 중요하기 때문에 일반적으로 높은 가용성과 낮은 지연 시간의 트랜잭션 처리를 기대한다.

이때 OLTP 시스템에 분석가가 즉석 분석질의(adhoc analytic query)를 실행하게 되면 해당 쿼리는 매우 비싸기 때문에 중요한 트랜잭션 처리의 성능을 저하시킬 것이다.

 

따라서 분석가들이 OLPT 작업에 영향을 주지않고 마음껏 질의할 수 있도록 존재하는 개별 데이터 베이스가 데이터 웨어하우스이다.

데이터 웨어하우스는 회사 내의 모든 다양한 OLTP 시스템에 있는 데이터의 읽기전용 복사본이다.

데이터는 OLTP 데이터 베이스에서 (주기적인 덤프나 지속적인 갱신 스트림을 사용해) 추출(extract)하고 분석 친화적인 스키마로 변환(transform)하고 데이터 웨어하우스에 적재(load)한다.

 

이렇듯 데이터 웨어하우스로 데이터를 가져오는 이 과정을 ETL이라고 한다.

일반적으로 소규모 기업은 다양한 OLTP시스템을 가지고 있지 않고 적은 양의 데이터를 가지고 있으므로, 일반적인 SQL 데이터베이스에 질의를 하거나 스프레드 시트에서도 분석이 가능하여 별도의 데이터 웨어하우스가 없는 경우가 많다.

그러나 개별 데이터 웨어하우스를 사용한다면 분석 접근 패턴에 맞게 데이터베이스를 최적화할 수 있다.

가령, 색인 알고리즘은 OLTP에서 특정 키에 해당하는 특정 로우를 빠르게 읽는 것에 적합하지, 분석 질의의 응답에서는 그렇게 어울리지 않는다.

 

분석용 스키마 : star schema(별모양 스키마) & snowflake schema(눈꽃모양 스키마)

분석에서는 트랜잭션 처리영역과는 달리 데이터 모델이 그렇게 다양하지 않으며, 대부분의 데이터 웨어하우스는

star schema(차원 모델링 - dimension modeling)로 상당히 정형화된 방식을 사용한다.  

위의 예제가 star schema다.

 

스키마 중심에는 fact table이 있고 각 로우는 특정 시각에 발생한 이벤트에 해당한다.

가령 식료품점에서 a 고객의 b구매가 c 식료품 점에 있었다고 하면, 이러한 이벤트의 사실만 기록되어있는 것이다.

데이터베이스 기준으로 본다면 주요 데이터의 키값들이 각 관계에 맞게 하나의 로우에 위치해있다. 해당 키값에 대해 데이터가 자세하게 기재된 각각의 dimension table들이 존재한다.

그리고 각 특정 이벤트에 해당하는 상품 가격과 수수료가 기재되어있다.

fact table에서 가격과 수수료 등의 메인 정보를 제외한 주요 값들은 모두 dimension table의 외래키라고 보면된다.

 

위의 예시에서 31이라는 product_sk를 관련된 dimension table에서 찾으면 31 키를 가진 상품 데이터가 자세하게 나온다.

 

해당 스키마의 변형이 눈꽃송이 스키마다.

이는 star schema의 dimension table에서 더 하위 차원의 다양한 정보가 담긴 dimension table이 추가된 형태다.

가령 product 테이블을 브랜드와 상품으로 분리하여, 각 브랜드에 대한 정보를 담긴 하위 dimension table을 만들고 각 product는 brand는 키로 저장하는 것이다.

점점 더 중복된 데이터를 줄이고 정규화 할 수록 눈꽃송이 스키마에 가까워지고, 단순화하여 작업하기 용이할수록 star schema가 되며 분석가들은 후자를 선호한다.

 

칼럼 지향 저장소

분석 데이터 베이스에 담긴 테이블들은 보통 100개이상의 컬럼을 가지지만, 실제로 분석 시에는 한번에 4개 또는 5개 칼럼만 접근한다.

(분석용으로는 select *을 거의 필요하지 않다)

 

이러한 분석 질의를 효율적으로 실행할 수 있는 방법은 무엇일까?

대부분의 OLTP로 데이터를 처리하는 데이터베이스는 로우지향 방식으로 데이터를 배치한다.

이때 테이블에서 한 로우의 모든 값은 특정 키값을 기준으로 인접하게 저장된다.

따라서 특정 키를 기준으로 데이터를 조회할때 모든 칼럼에 대한 특정인의 정보를 빠르게 조회 및 수정할 수 있다.

 

이러한 로우지향저장소에서 적은 컬럼이지만 모든 로우의 데이터를 불러들이려면 비효율적이다. 

-> 메모리에 모든 로우의 데이터를 적재하고, 쿼리 구문에 기재된 조건에 따라 로우를 필터링하게 되는 것이다.

 

이에 대응해서 등장한 것이 칼럼 지향 저장소이다.

모든 값을 하나의 로우에 함께 저장하지 않는 대신 각 칼럼별로 모든 값을 함께 저장한다. 각 칼럼을 개별 파일에 저장하면 질의에 사용되는 칼럼만 읽고 구분 분석하면 된다.

→ 문서데이터 모델인 파케이가 칼럼 저장소 형식이다.

 

칼럼 압축

작업하고자 하는 데이터를 압축해버리면 디스크 처리량이 줄어들 수 있으며 칼럼 지향 저장소는 이러한 압축에 적합하다.

위의 예시를 보면 하나의 컬럼에 중복된 로우값들이 많다. 이 때 압축을 사용하면 매우 효율적인데 데이터 웨어하우스에서 특히 비트맵 부호화가 효과적이다.

 

n개의 고유값을 가진 n개의 개별 비트맵으로 변환하여, 고유값 하나가 하나의 비트맵이고 각 로우는 한 비트를 가진다.

위의 예시에서 고유값들을 가져와서 product_sk 칼럼에 29라는 값을 가진 로우는 1, 없으면 0을 주어 해당 고유값에 대한 하나의 비트맵을 만 들수 있다.

 

만약에 n이 더 큰 경우 즉 대부분의 비트맵에 0이 많은 경우, 아래 예시처럼 비트맵을 추가적으로 런 랭스 부호화할 수 있다.

 

비트맵 색인(참고링크)

데이터웨어하우스에서 적합한 색인 방식이다.
비트를 이용하여 컬럼값을 저장하고 이를 이용하여 ROWID를 자동으로 생성하는 인덱스의 한 방법이다. 

B트리 인덱스가 가지는 문제를 해결하기 위해 등장했다.
- B트리 인덱스는 실제 컬럼값을 인덱스에도 보관하고 있어야 한다는 점이 대용량 데이터를 관리할 때 부담이 된다.
- 또한 분포도도 좋아야한다. 
즉 저장공간의 장비가 B트리 인덱스의 가장 큰 문제이다. 

비트맵의 ​​각 비트는 가능한 ROWID에 해당하며, 비트가 설정된 경우 해당 ROWID가있는 행에 키 값이 포함되어 있음을 의미한다.
비트맵 인덱스는 ROWID와 일련의 비트만 저장하기 때문에 B-tree 인덱스보다 작다.

B-tree Index vs Bitmap Index
- 카디널리티 차이: 일반적으로 비트맵 인덱스는 중복이 많은(낮은 카디널리티) 열에 사용되는 반면 B-tree 인덱스는 중복이 적은(높은 카디널리티) 열에 가장 적합합니다.
예로, 성별 컬럼처럼 0, 1 두 개의 값으로만 이루어지는 Column의 경우 비트맵 인덱스가 이상적입니다.전화번호나 고객 이름과 같이 중복이 적은 경우엔 B-tree 인덱스가 이상적입니다.
- 내부 구조 차이 : 내부 구조가 상당히 다릅니다. B-tree 인덱스에는 인덱스 노드 (데이터 블록 크기 기준)가 있으며 트리 형식입니다.
- NULL 인덱싱: 일반적인 B-tree의 경우, 모든 열 값이 NULL인 경우 인덱스에서 제외됩니다.위에서 본 비트맵 인덱스의 특징처럼 비트맵 인덱스는 NULL도 인덱싱합니다.

카산드라와 HBase같은 빅테이블로부터 내려오는 칼럼 패밀리 개념은 칼럼 지향 저장소와는 다르다. 각 칼럼 패밀리 안에는 로우 키에 따라 로우와 모든 칼럼을 함께 저장하여 칼럼 압축을 사용하지 않는다. 따라서 빅테이블 모델은 대부분 로우 지향이다.

 

메모리 대역폭과 벡터화 처리

  • 수백만 로우를 스캔할 때는 디스크로부터 데이터를 가져오는 대역폭이 큰 병목이다
  • 그러나 다른 사항들도 중요하다
    • 메인 메모리에서 CPU 캐시로 가는 대역폭의 효율적 사용도 필요
    • CPU 명령 처리 파이프라인에서 분기예측 실패와 버블을 피해야 한다
    • 단일 명령 다중 데이터 명령을 사용하게끔 신경써야 한다
  • 칼럼 저장소 배치는 CPU 주기를 효율적으로 사용하기에도 적합하다
    • 압축된 칼럼 데이터를 CPU의 L1 캐시에 딱 맞게 덩어리로 나누어 가져오는 작업을 타이트 루프(?)에서 반복한다
      • CPU는 함수 호출이 많이 필요한 코드나 각 레코드 처리를 위해 분기가 필요한 코드보다 타이트 루프를 훨씬 빨리 수행한다.
    • 칼럼 압축으로 같은 양의 L1 캐시에 칼럼의 더 많은 로우를 저장할 수 있다
    • 비트 AND나 OR같은 연산자는 압축된 칼럼 데이터 덩어리에 바로 연산할 수 있게 설계 -> 벡터화 처리

칼럼 저장소와 순서정렬

칼럼 저장소에서는 로우가 저장되는 순서가 반드시 중요하지 않다. 따라서 삽입된 순서로 저장하는 방식이 가장 쉽다.

그러나 각 칼럼을 독립적으로 정렬할수는 없다. → 이는 당연하다. 독립적으로 정렬하면 연관된 로우를 알수가 없어지기 때문이다.

 

보통 date_key 같은 날짜를 첫번째 정렬 기준으로 삼고, 그 다음에 product_sk 같은 키컬럼을 두번째 정렬기준으로 삼는다.

 

이렇게 순서 정렬을 하면 칼럼 압축에 도움이 된다. 순서 정렬시에 고유값을 많이 포함하는 경우가 아니라면 중복된 값이 연속으로 드러날 것이고 비트맵 부호화 압축을 효율적으로 수행할 수 있다. 이러한 압축 효과는 첫번째 정렬키에서 가장 강력하다.

 

칼럼 지향 저장소에 쓰기

대부분의 작업은 분석가가 수행하는 읽기 전용 질의이며 이에 따라 쓰기작업이 어렵다는 단점이 존재한다.

따라서 쓰기 최적화는 합리적이다.

 

B트리는 압축된 칼럼에서는 불가능하다. 정렬된 테이블의 중간에 있는 로우에 삽입을 원하는 경우 모든 칼럼 파일을 재작성해야한다.

즉 하나의 컬럼에 모든 로우가 저장되어있으므로, 반대로 하나의 로우에 특정 칼럼만 변경하려 하면 오히려 모든 칼럼 파일을 건드리게 되는 것이다.

 

이때 LSM 트리를 활용할 수 있다.

모든 쓰기는 먼저 인메모리 저장소로 이동해 정렬된 구조에 추가하고 디스크에 쓸 준비를 한다.

충분한 쓰기를 모으면 디스크의 칼럼 파일에 병합하고 대량으로 새로운 파일에 기록한다.

 

이때 질의를 한다면 디스크의 칼럼 데이터와 메모리의 최근쓰기를 모두 조사해서 두가지를 결합해야한다.

 

집계: 데이터 큐브와 구체화 뷰

모든 데이터 웨어하우스가 칼럼 저장이 필수는 아니지만 분석 질의에 대해 상당히 빠르기때문에 급속하게 인기를 얻는다.

 

데이터 웨어하우스의 다른 측면으로 구체화 집계가 있다.

매번 원시데이터에 집계를 처리하는 것은 낭비이으로 자주 사용하는 집계를 캐시하는 한가지 방법이 구체화 뷰이다.

이러한 뷰는 테이블 같은 객체로 일부 질의의 결과가 내용이다. 구체화 뷰는 디스크에 기록된 질의 결과의 실제 복사본이고, 가상 뷰는 단지 질의를 작성하는 단축키라고 생각하고 둘을 구분할 수 있다.

따라서 원본데이터를 변경하면 구체화 뷰를 갱신해야한다.

데이터 베이스는 보통 이러한 작업을 자동으로 수행한다. 하지만 이런 갱신으로 인한 쓰기 비용은 비싸서 OLTP에서는 자주사용하지 않는다.

 

데이터 큐브 혹은 OLAP큐브라고도 알려져있는 구체화 뷰의 사례중 하나는 n차원의 테이블이다.

이러한 데이터 큐브의 장점은 특정 질의를 효과적으로 미리 계산했기 때문에 해당 질의를 수행할 때 매우 빠르다.

단점은 원시 데이터에 질의하는 것과 동일한 유연성이 없다는 점이다. 즉 데이터큐브에서 보여주는 그 데이터에 대해서만 파악 가능하지만 좀 더 나아간 단계에 대한 데이터를 질의를할 수 없다.

 

정리

이번 장에서는 데이터베이스가 어떻게 저장과 검색을 다루는지 알아보았다.

  • OLTP VS OLAP
    • OLTP는 대량의 요청을 받은, 사용자 대면, 작은 수의 레코드만 질의에서 다룸, 일부 키에 대한 데이터를 조회하므로 색인을 사용
    • OLAP는 최종적으로 비즈니스 분석가가 사용. 질의가 매우 복잡하고 많은 양을 다룬다.
  • OLTP 측변에서 주요한 두가지 관점을 살펴봄
    • 로그 구조화 관점에서 SS 테이블, LSM 트리 등
      • 최근에 개발. 임의 접근 쓰기를 체계적으로 디스크에 순차쓰기로 바꾼 것
    • 제자리 갱신관점에서 덮어쓰기할수있는 B트리
  • OLAP는 색인을 사용하지 보다는 질의가 디스크에서 읽는 데이터의 양을 최소화하기 위해 데이터를 작게 부호화하는 일이 중요
    • 칼럼지향 저장소가 도움
728x90

+ Recent posts