[주제]
- 대용량 DB 관리 방법
[환경]
- Database RDB(Oracle, MS-SQL, MySQL 등..)
※ RDB(Relational Database) – 관계형 데이터베이스
[Preview]
1. 새로 개발되고 운영하는 DB에 대해 시간이 지남에 따라 수 많은 데이터들이 쌓이게 됩니다.
2. 또한 초기 설계 및 구성되었던 DB는 기능 추가, 데이터 변환, 신규 화면 개발 등으로 인해 성능 및 저장공간이 부족하게 됩니다.
3. 차세대 개발이 진행되지 않는 한 시스템은 계속 악화하게 되며, 초기 개발 당시 최적화되었던 설정이 문제가 되며, 결국 최적화 및 튜닝이 필요하게 됩니다.
4. 이번 시간에는 대용량 데이터로 인한 성능 문제 발생에 대해 해결할 수 있는 몇 가지 방법을 공유하고자 합니다.
[샤딩(Sharding)] – 대량의 DB 데이터를 다른 물리 시스템에 분할하여 저장 관리 기술
1. 정의
A. 물리적으로 다른 데이터베이스에 동일한 테이블 스키마를 가진 데이터를 분산하여 저장 및 조회하는 DB 분할 기법.
B. 하나의 거대한 데이터베이스 테이블을 수평 분할(Horizontal Partitioning)하여 여러 개의 작은 단위로 나눈 후, 물리적으로 다른 위치에 분산하여 저장·관리하는 기술
2. 샤딩 분할 방법
방법 | 설명 | 특징 |
Vertical Partitioning |
테이블별로 서버를 분할하는 방식 각 서버 데이터 거대화시 추가 샤딩 필요 |
구현 간단, 시스템 구조 변경 최소화 |
Range Based Partitioning | 하나의 Feature 나 Table 거대화 시 샤딩 데이터값이 범위 지정 분할 |
데이터 분할방법 예측 가능시 구현 가능 |
Key or Hash Based Partitioning | 엔티티를 해쉬함수에 넣어 나오는 값 이용 서버를 결정하는 방식, 해시값 기준 분할 | 결과값이 균등분포 되게 해쉬 함수 설계 필요 |
Directory Based Partitioning | 파티셔닝 메커니즘 제공 추상화 서비스 생성 Shard key 기준 분할 |
샤드 키 Look-up 기능 구현 |
[파티셔닝(Partitioning)] – 대량의 데이터 테이블을 테이블 분할하여 저장 관리 기술
1. 정의
A. SQL 문이나 어플리케이션 수정없이, 큰 테이블이나 인덱스를 관리하기 쉬운 작은 단위로 테이블을 분할하여 관리하기 위한 분할 관리 기법
B. 대용량 테이블이나 인덱스를 동일한 논리적 속성을 가진 여러 개의 세그먼트로 나누는 방식
2. 목적
A. 관리 용이성, 가용성 증대, 부하 분산, 수행 시간 단축
3. 파티셔닝 종류
A. 수평 파티셔닝(horizontal partitioning)
i. 레코드를 기준으로 테이블을 분할하여 특정 범위만 조회하여 성능개선 기법(샤당과 동일한 개념)
ii. 특징 - 성능, 가용성을 위해 KEY 기반으로 여러 곳에 분산 저장
iii. 장점 - 테이블당 데이터 개수가 작아지고 따라서 Index의 개수도 작아져 성능 향상
iv. 단점 - 테이블간 Join 이 많아져 지연 시간이 증가
B. 수직 파티셔닝(vertical partitioning)
i. 테이블의 모든 컬럼 중 특정 컬럼을 쪼개서 별도 저장하는 형태, 하나의 엔티티를 2 개 이상으로 분리
ii. 장점 - 자주 사용하는 컬럼을 분리하여 성능 향상, 컬럼 수 축소로 I/O 이점
iii. 단점 - 파티션 키 값 변경에 대한 별도 관리 필요.
[샤딩과 파티셔닝 비교]
구분 | 파티셔닝 | 샤딩 |
개념 | 대용량 테이블이나 인덱스를 동일한 논리적 속성을 가진 여러 개의 세그먼트로 나누는 방법 | 물리적으로 다른 데이터베이스에 데이터를 수평 분할 방식으로 분산 저장하고 조회하는 방법 |
개념도 | ||
구현방법 | Range, Hash, List, Composite | Range, Hash, Vertical, Horizontal, Directory Based |
활용 | 파티션 설계 시 데이터 보관 주기 및 보존 주기를 고려 | 데이터 재분배, 조인, Global Unique Key 고려 |
[인덱스(Index)]
1. 정의
A. 데이터베이스 테이블에 대한 검색 성능의 속도를 높여주는 자료 구조로 특정 컬럼의 인덱스를 생성하여 컬럼의 특정 값을 필요로 할 시 인덱스를 통해 위치를 파악하여 접근
B. 예를 들어 도서 책 뒤편에 있는 색인과 비슷하며, 특정 단어가 포함된 페이지를 찾고 싶을 시 색인에서 확인하여 도서 페이지를 찾아가는 것과 같은 원리
2. 목적
A. 인덱스가 없다면, 특정 자료를 찾을 시 자료 전체를 처음부터 끝까지 전부 검색해야 함(Full Scan)
B. 인덱스를 생성함으로써, 특정 자료에 대해 위치를 신속히 파악하여, 자료를 검색(Index Seek)
3. 장점
A. SELECT 문으로 검색하는 속도가 매우 빨라짐
B. 컴퓨터의 부담이 줄어들어서 결국 전체 시스템의 성능이 향상.
4. 단점
A. 인덱스도 공간을 차지해서 데이터베이스 안에 추가적인 공간이 필요
i. 인덱스는 대략 테이블 크기의 10% 정도의 공간이 추가 필요
B. 처음에 인덱스를 만드는 데 시간이 오래 걸릴 수 있음
i. 찾아보기가 없는 책에 새로 찾아보기를 만드는 것과 마찬가지로 시간 필요
C. SELECT가 아닌 변경작업(INSERT, UPDATE, DELETE)이 자주 일어나면 성능이 나빠짐
5. 종류
A. 클러스터형 인덱스(Clustered Index)
i. 데이터 레코드의 순서가 인덱스 엔트리 순서와 동일하게 유지되도록 물리적으로 행을 재배열하는 인덱스(순서대로 데이터 저장)
ii. 최대 갯수는 테이블 당 1개
iii. 테이블에서 지정하는 컬럼 자체가 인덱스와 동일
B. 넌클러스터 인덱스((Non-Clustered Index)
i. 데이터 레코드의 순서가 인덱스 엔트리 순서와 성관없이 저장되도록 구성된 인덱스
ii. 물리적 행 재배열 없음(입력한 순서대로 저장)
iii. 포인팅 정보를 가지므로 인덱스 크기가 커짐
iv. 최대 갯수는 테이블 당 249개
[클러스터형과 넌클러스터 인덱스 비교]
간단한 예시로 클러스터형과 넌클러스터 형을 비교해 보겠습니다.
1. 회사에서 팀장님이 인사 자료를 주고 두 직원에게 ‘이름’으로 찾기 편하게 정리하라고 했습니다. 두 직원인 A사원과 B사원은 아래와 같은 방법으로 정리하였습니다.
2. A사원 – 자료들을 이름 순으로 순서대로 정리해 놓자 [Clustered Index]
B사원 – 현재 자료에서 각 이름이 어디 위치에 있는지 책에 따로 적어 놓자 [Non-Clustered Index]
3. 팀장님이 각 사원들에게 ‘김철수’ 라는 이름을 찾아 달라고 요청.
A. A사원 – 순서대로 정리되어 있어서 빠르게 제공
B. B사원 – 따로 적어 놓은 책에서 자료 위치를 확인 후 제공
C. 결론 – 단일 조건에 대해서는 둘 다 빠르나, A사원(Cluster)이 약간 더 빠른 상황
4. 팀장님이 각 사원들에게 가~다 사이의 성을 갖은 이름을 찾아 달라고 요청
A. A사원 – 정렬된 이름 중 가~다까지 범위를 잘라서 제공
B. B사원 – 따로 적어 놓은 책에서 자료 위치 확인하는 행위를 반복 시행
C. 결론 – 범위 조건에 대해서는 A사원(Cluster)이 아주 매우 빠른 상황
5. 팀장님이 각 사원들에게 ‘박철수’ 라는 자료를 더 공유해 줌
A. A사원 – 정렬된 자료에서 넣어야 할 위치 파악하여 자료 사이에 공간을 만들어서 추가 자료를 입력
B. B사원 – 자료를 그냥 포함시키고, 책에 관련 위치만 추가
C. 결론 – 변경작업에 대해서는 B사원(Non-Cluster)이 빠른 상황
6. 팀장님이 각 사원들에게 이름만 아니라 나이도 찾기 편하게 해 달라고 함
A. A사원 – 이름으로 정렬된 자료를 나이로 정렬할 수 없기 때문에 적용할 수 없음
B. B사원 – 나이 관련된 위치가 저장된 책 하나를 더 추가
C. 결론 – B사원(Non-Cluster)은 관련 인덱스를 추가할 수 있으나, A사원(Cluster)은 불가능
7. 결론
A. 클러스터 인덱스는 조회에 대해서는 빠르나 변경(Insert, Update, Delete)는 느리며, 한 테이블 당 하나밖에 생성하지 못한다.
B. 넌클러스터 인덱스는 조회에 대해서는 클러스터보다 느리나 변경이 빠르며, 한 테이블 당 여러 개를 만들 수 있다.
[Tip – 대용량 테이블 데이터 삭제 방법]
1. 특정 조건에 대해서 대용량 테이블 데이터 삭제 시 인덱스가 포함되어 있으면 빠르나, 포함되어 있지 않으며, 많은 시간이 걸려서 진행이 됨.
2. 일반적 DELETE는 WHERE 절을 사용해서 삭제하는 명령어인데, 테이블에 있는 데이터를 하나하나 선택하여 제거하는 방식.
WHERE 절을 쓰지 않고 모든 데이터를 삭제하더라도, 내부적으로는 한줄한줄 일일이 제거하는 과정을 거치면서 대량 데이터 삭제 시 느린 성능을 보인다.
3. 테이블 전체 데이터를 빠르게 삭제하는 방법
A. DROP TABLE - 삭제 조건없이 전체 데이터를 삭제하고 싶을 때(테이블 삭제)
i. 테이블 자체를 완전히 날려버리는 명령문
ii. 테이블을 다시 사용해야 한다면 새로 CREATE 해야 한다.
B. TRUNCATE TABLE - 삭제 조건없이 전체 데이터를 삭제하고 싶을 때(테이블 유지)
i. DELETE와 다르게 테이블에 있는 데이터를 한꺼번에 제거
ii. 초기 테이블을 생성했던 상태로 변경된다.
4. 특정 조건에 대해 대용량 테이블 데이터를 삭제하는 방법
A. DELETE를 사용하여 대량의 데이터를 삭제하는 것은 큰 부하를 줄 뿐만 아니라 Lock 문제가 동시성에 악영향을 준다.
B. 특히, 넓은 범위의 Lock이나 Blocking을 유발시킬 수 있다.
C. 요점은 최소한의 부하로 삭제하는 것이 중요
D. DELETE문에 TOP문과 Loop문을 활용하여, 루프를 돌리면서 작은 부하를 여러 번 주어 삭제 권고
E. 예제 – 데이터를 10개의 단위로 조회하여 DELETE 무한 루프 실행
'일 > 개발, IT정보' 카테고리의 다른 글
Oracle 실행 계획 확인 / 쿼리 튜닝과 최적화 (0) | 2024.10.15 |
---|---|
DB 이상현상, 정규화 과정 (3) | 2024.10.14 |
서버 이중화, 로드 밸런싱 구성 및 개념 (0) | 2024.07.27 |
Web ↔ WAS 구조 및 동작 과정 (0) | 2024.07.26 |
도메인(URL) 입력 시 IP와 통신하는 과정 / 개념 (0) | 2024.07.22 |