Excel 시트 등보다 효율적인 데이터 구조로 관리해야 한다. (B+ 트리 인덱스) 나 (해시인덱스) 와같은 데이터 구조로 이러한 레코드를 관리할 필요가 있다
대량의 데이터를 메모리 내에서 만으로는 취급할 수 없다.
장애가 발생했을 때 빠른 복구가 어렵다
병렬성 제어가 어렵다
배타제어가 필요하며. 배타의 범위가 중요. 가장 단순한 형태는 Lock File 이다. 이러한 형태는 동시에 한 명만이 갱신 할 수 있기 때문에 실행 성능 면에서 매우 큰 제약이 생기게 되므로, 행 수준의 배타범위를 가지는 것이 바람직하다.이렇게 되면 단순한 파일로서의 제어가 어려워 지지만, 데이터베이스를 사용하면 이러한 배타 제어도 간단히 할 수 있게 된다, 배타 제어의 범위가 넓으면 병렬성이 떨어지고 속도면에서도 실용성이 줄어든다. 특히 최근에는 멀티 CPU가 대두되고 있음에도 동시에 하나의 처리밖에 할 고 한개의 코어만을 사용해야 한다는 것은 큰 손해이다.
데이터 무결성을 보장하는 것은 어렵다.
병렬성 제어와 강하게 연관된 요소이며,데이터 자체가 불일치를 일으키지 않게 하는 구조가 중요하다
인덱스로 고속 엑세스 실현하기
키와 값의 페어를 관리하고 싶다
선형 검색은 대량의 데이터에 적합하지 않다.
원하는 위치까지 순식간에 도달하는 방법
사용자 정보를 고정길이로 관리하는 기술 –>새로운 데이터 항목이 생길경우 어려움, 데이터낭비가 생김
인덱스 구조 도입하기
각 ID마다 파일상의 시작위치를 기록한다.
고정길이 레코드보다 효율적이고 확장성을 가진 형태로 검색이 가능, 인덱스–> 파일 2단계 액세스가 단점
해시인덱스
키값, 바이트 위치 인덱스에서 키는 문자열, 숫자, 날짜 등 여러가지를 생각할 수 있으므로, 고정길이로 생각하긴 어렵다. 실제 데이터베이스의 구현은 키 값을 그대로 관리하는 것이 아니라 키값을 해싱하여 사용. 해시 계산비용은 데이터양에 의존하지 않기 때무네 O(1)으로 가장빠른 알고리즘이다.
해시가 만능은 아니다.
가격이 10,00원 이하의 아이템을 찾아라
제목이 Final 로 시작하는 아이템을 찾아라 (범위검색)
시간순 정렬을 하고 싶다. ( 정렬 )
해시 인덱스는 일부용도에서만 빠르게 처리할 수 있다
인덱스의 기본 B+트리 인덱스
이진트리가 아니고 다분기 트리, 분기개수가 수십 개에서 수백 개에 걸치는 경우도 있다. 분기개수를 많이 하는 이유는 계층의 단수를 줄여 액세스를 줄이기 위해서
이진 트리의 경우 N계층당 2의n승 개 밖에 기록을 관리할 수 없다. 이진 트리의 경우 레코드 수 N당 탐색에 필요한 계산량이 O(log2N)이 되는 것으로 알려져 있다. O(N)과는 비교가 되지 않을 정도로 효율이 좋지만해시 인덱스 O(1)과 비교하면 효율성이 떨어진다. B+ 트리와 같은 다부기의 트리 구성을 취함으로써 O(logmN) 의 계사량ㅇ이 되어 액세스 수를 크게 줄일수 있다.
B 트리 인덱스 중에서도 RDBMS는 끝단의 리브 블록에서만 값을 관리하, B+ 트리 (혹은 그 발전형) 가 가장 많이 사용된다. B- 트리 라는 인덱스 구조도 있는데. 이것은 모든 값을 리프 블록에서만 갖도록 제한하지 않으며, 브랜치에서도 값을 가질 수 있다. 보통 B-트리 인덱스에 비하면 B+트리 인덱스는 어떠한 검색어라도 루트에서 리프까지 거치지 않으면 검색할 수 없다는 단점이 있지만. 브랜치가 보다 컴팩트하게 되므로 인덱스 자체의 계층구조를 작게 할 수 있다.즉 최악의 경우 액세스 횟수를 줄일 수 있다는 것을 의미한다. B- 인덱스의 경우 리프가 아닌 브랜치로 되돌아가 값의 존재를 확인 하고 브랜치로 올라 가거나 인근 리프로 가야하지만, B+ 인덱스라면 리프 블록에서 인접한 리프로만 이동하기 때문에 효율적이다. B+트리 인덱스를 사용하면 등호검색은 물론 부등호나 전방 일츠 검색등의 범위 검색도 리프 블록을 스캔하는 것만으로 완결하기 떄문에 고속이다. 이러한 사정으로 인해 B+트리 인덱스는 RDBMS의 사실상 표준으로 널리 사용되었다.
RDBMS에서는 어떻게 최적화를 실현하고 있는가
고유성의 보장 ,해시 인덱스라면 동일한 ID의 경우 반드시 동일한 해시값이 되고, B+트리 인덱스이면 동일한 리프에 도달하기 때문에 적은 코스트로 중복체크가 가능하다
멀티칼럼 대부분의 RDBMS는 두가지 요소를 결합한 인덱스를 만들 수 있으며,이러한 AND 조건에서 검색을 가속화할 수 있다
인덱스만을 읽는 검색. 인덱스 부분과 데이터 부분은 서로 독립적인 영역에 존재하고 있기 때문에 양쪽을 한번의 액세스로 단 번에 읽을 수 는 없다. 가격이 10,000원 이하인 상품의 개수를 알고싶다 라는 경우에는 가격인덱스가 있으면 이 인덱스에서 조건에 맞는 레코드 건수를 열거하는 것만으로 결과를 구할 수 있으므로 데이터 영역에 액세스할 필요가 없다. DB구현에 따라 이러한 검색패터에 있어 데이터 영역을 읽지 않고 인덱스 영역을 읽는 것만으로 고속으로 처리완료 할 수 있는데, 이러한 작업을 Index Only Read, Covering Index라고 부른다.
인덱스 병합. 부서코드가 100번 또는 입사 연도가 2010년인 직원을 찾고 싶다. 라는 경우, 이러한 OR 조건의 검색은 하나의 인덱스만으로는 검색에 도움이 되지 않는다. 그래서 한 번의 검색에서 두 개 이상의 인덱스를 동시에 사용하여 각각의 결과에서 원하는 레코드를 꺼내려고 하는 발상이 생겨남. 인덱스 병합은 각 인덱스에서 각각 검색을 실시하여 대상의 행 번호를 추출한다.그 다음 각각의 결과에 대해 AND 조건과 OR조건 등으로 집합 연산을 수행하고 마지막으로 남은 행 번호에 대해 실제 데이터를 읽어가는 효율적인 동작을 시행한다.
랜덤 액세스는 느리다. DB성능 특성을 이해하는데 있어 매우 중요한 것이 랜덤액세스 성능이다.HDD의 경우라면 대게 디스크가 반 정도 회전하는 시간이다. 고성능 디스크라도 분당 10,000~15,000 회전밖에 할 수 없다. 초당으로 환산하면 수백회정도이다.
업데이트 비용 절감을 위한 노력
인덱스는 본체데이터와 별도로 유지할 필요가 있기 때문에 검색성능은 높아지지만 업데이트 성능이 떨어진다는 단점이 있다. 각 DBMS는 이 업데이트 비용으 최대한 떨어뜨리기 위해 다양한 최적화를 구현하고 있다. 아래는 그 예
디스크에 모아서 기록하기. 전통적인 방식은 순서대로 업데이트된 순서대로 디스크에 써 나갈 것이다. 그러나 이런 식이라면 속도가 느린 랜덤 라이트가 많이 발생하게 된다. 이에 업데이트된 정보를 메모리나 전용파일 등에 일시적으로 기록하여 두고 나중에 모아서 단번에 리프 블록을 갱신하는 구조를 채택하고 있는 데이터베이스가 바로 MySQL(InnoDB) 이다. 이러한 구조에서는 랜덤라이트보다 훨씬 빠른 시퀀셜 라이트로 빠르게 처리한다.
병렬 갱신 성능. B+ 트리 인덱스에 값의 추가/갱신/삭제를 할 경우, 인덱스의 리프 블록의 내용을 이동시켜야 하는데 이것을 리프분할이라고 한다. 클라이언트에서 업데이트가 다수 발생하여 리프분할이 여기저기 일어날 경우, 그것들의 일관성을 갖는 것은 상당히 어려운 자업이다. InnoDB 등에서는 인덱스의 재편성 처리가 완료될 때까지 일체의 참조/갱신 처리를 차단하는 동작을 시행하고 있다. 재편성 조작 자체는 금방 끝나지만 동시에 대량의 insert update 를 시행하여도 동시성이 그다지 높아지지 않는 문제가 있다. 멀티코어 환경에서는 이러한 병렬 갱신성능으 중요성도 높아짐. B+ 트리 인덱스에는 락프리로 갱신 가능하게 하는 알고리즘도 제안되고 있다. 또한 현재 MySQL (InnoDB)에서 이것을 해결하는 가장 빠른 방법은 파티션테이블을 사용하는 것이다.
테이블 설계와 릴레이션
SQL문의 특징과 이를 잘 다루는 법
조인
대규모 애플리케이션에서는 특정 테이블로의 트래픽이 매우커서 한서버에서 처리할 수 없는 경우 테이블단위로 (또는 하나의 테이블을) 여러 서버에 분산하는 경우가
있다. 이런 분할을 샤딩이라고 한다. 샤딩을 하고 있으면 조인을 사용하기 어렵운데, 결합대상 테이블이 반드시 같은 서버에 있다고 할 수 없기 때문이다. 대규모가 될 것으로 예상되는 애플리케이션은 샤딩의 필요성을 처음부터 염두해 두고 거대하게 될 것 같은 테이블과 조인을 하지 않도록 애플리케이션을 작성하는 방법이 자주 사용된다.
SQL문의 실행효율
적절한 인덱스가 사용되고 있는지 확인. 쿼리분석도구 EXPLAIN 사용
SQL의 장점과 단점
기술습득이 용이함
기능면. 저장프로시저를 이용하면 다소 복잡한 로직은 구현가능. MySQL등의 오픈소스는 빈약한 기능을 제공하지만, Oracle에서는 PL/SQL이라는 전용언어까지 제공. 저장프로시저는 데이터베이스 서버에서 동작해서, 수십번 수행할 쿼리를 저장프로시저를 사용하면 네트워크 액세스 빈도를 줄일 수 있다.. 네트워크가 느린 10년전 이야기,, 최근은 사용하는 일이 적고 로직은 프로그래밍 언어, 데이터 조작은 sql에 분담시키는 이유는 프로그래밍언어 쪽이 저장 프로시저보다 개발환경이 압도적으로 좋기 때문.
가용성과 데이터의 복제
디스크 이중화로 데이터 손실 방지하기
용량에 여유가 있으면 RAID1 없는 경유에는 5이다
복제
단방향복제
MySQL 표준 복제. 마스터에 갱신한 결과가 슬레이브로 비동기 전파하는 유형.
마스터에서 실행한 갱신계의 SQL문이 바이너리 로그라는 전용로그 파일로 기록된다. 이 로그 파일로 슬레이브로 전송
슬레이브는 바이너리 로그 수신, 바이너리 로그 수행 2단계로 이루어져, 각각 I/O스레드 , SQL스레드에서 실행한다. 이모두 비동기. 디스크에 비해 네트워크 병목이 되는 일이 적기 때문에 거의 동기에 가까운 속도로 실행된다.
마스터가 장애를 일으킨 경우 슬레이브에서 지금까지 업데이트 결과가 반영되지 않을 수 있다.
마스터에서 생성한 바이너리 로그가 슬레이브에서 마지막까지 수신되지 않은상황
슬레이브에서의 바이너리 로그의 실행이 마지막까지 종료되지 않은 상황
단방향/준동기화
MySQl의 경우에는 슬레이브가 바이너리 로그를 수신하는 부분을 동기화 방식으로 할 수 있다. 이것을 준동기식 복제라고 한다. 마스터를 업데이트한 클라이언트는 그 결과 뿐만 아니라 대상 슬레이브로 전송하여 그 확인응답이 반활될 때까지 기다림.
단방향/동기
MySQL기능으로서 구현되어 있지 않지만. 슬레이브에 대한 업데이트 결과 반영까지 응답을 반환하는 방식.
양방향 복제
마스터를 두 개 이상 갖게 하고 각각의 마스터를 업데이트할 수 있도록 한 멀티마스터라는 구성도 생각할 수 있다.
기술적으로 어려움. 업데이트가 서로 충돌하면 어떻게 하느냐?
MySQL Cluster는 여러 서버에 각각 업데이트를 할 수있으며 그들이 자동으로 동기화 되는 구조이다.
트랜잭션과 무결성,무정지성
SQL문 레벨에서의 롤백
한번의 업데이트성 SQL문에서는 여러 레코드를 업데이트 할 수 있다.,인덱스나, 물리적 위치 등등.
무정지성 확보하기
Oracle 과 InnoDB 같은 트랜잭션 대응 DB는 REDO로그를 이용한 아키텍트로 무정지성을 보장한다.
REDO 로그의 역할
InnoDB에서는 트랜잭션을 커밋하면 그때마다 LSN이라는 시퀴스 번호가 증가하고, 그 번호와 갱신 대상의 블록의 정보를 REDO로그 파일에 쓴다.
한편 열 값과 인덱스를 갖는 데이터 파일에는 커밋을 할 때마다 기록을 하는 것이 아니라 캐시 영역에 보관해 두고 정기적으로 디스크에 기록을 한다.
서버 장애 등의 이유로 데이터베이스가 멈춰 재기동을 하는 경우 캐시영역의 데이터는 없어졌기 떄문에 데이터 파일과 REDO로그에 기록되있는 데이터가 올바르다. 그러나 데이터 파일은 이전 데이터 밖에 남지 않아있지 않기 때문에 REDO로그의 내용을 데이터 파일에 적용시켜 나감으로써 데이터 파일과 REDO로그의 LSN을 일치시키는 작업을 수행한다. 이 과정을 충돌 복구( Clash recovery ) 라고 한다. 복구 시에는 적용을 시작할 가장 오래된 LSN을 틍정한 뒤 그 위치에서부터 REDO로그의 내용을 순서대로 대응해 나간다.
이중 기록의 비용
1회 갱신에 대한 그 자체의 갱신 정보를 REDO 로그에 동기적으로 기록하면서 나중에 데이터 파일에도 기록하는 식의 두 번의 기록이 발생. 그렇다고 두배로 느려지는것은 아님. REDO로그 파일이 순차적으로 기록을 하는 특징이 있기 때문에. 레코드나 익덱스의 기록은 램던 라이트 이다.
잠금 메커니즘에 의한 배타제어
잠금의 범위 – MyISAM의 경우 테이블에 대해 배타적 잠금을 건다. InnoDB등은 레코드 단위로 잠금을 건다.
잠금기간 = 트랜잭션의 종료시까지 유지.
복제 및 트랜잭션
스토리지 기술의 변천
인덱스와 실제 데이터는 물리적으로 인접해 있지 않기 때문에 별도로 액세스할 필요가 있음 –> 이러한 접근 방식은 랜덤 액세스
동일한 쿼리라 해도 초당 수천~수십만쿼리가 가능한 이유는 데이터가 메모리에 있는가 아니면 디스크에 있는가
가정해서 사용자 수가 50만 명, 총 50GB정도의 데이터라면 ,, 메모리 가겨이 하락하고 64비트 리눅스로서 한대당 16GB이상 메모리를 탑재하여 히트율을 높인다. DB서버용으로 50GB의 사용하면 몇배의 실 데이터를취한다.
DB서버 한 대당 데이터양 /사용자 수가 몇배가 늘어나면 새로운 문제가 생긴다. 집계 처리와 같은 단일 스레드에서 행하는 타입의 작업에 시간이 오래 걸린다는 점이다. MySQL 에서는 복제 구성을 일방적인 방식이지만, 사실 MySQL의 복제는 단일 스레드로 작동한다. 따라서 복제 구성의 문제가 표면화 되었음. 한 대당 다수의 트래픽이 마스터에 전해지게 되면 마스터는 병렬화된 처리가 행해진다. 한편, 복제는 단일 스레드이기 때문에 갱신처리는 직렬화 된다. 마스터의 갱신에 비해 오래 걸리고 신시간으로 마스터의 갱신처리를 따라잡을 수 없어 지연되어 버린다. 64비트 OS대두의 부작용으로 수십 분 이상의 복제 지연이 관찰 되기도함.
단일 스레드 처리의 성능 지연의 주요이유는 디스크 I/O가 느리기 때문. 4개의 HDD에서 RAID10 구성을 하면 단ㅇ일 스레드와 다중 스레드 경우 I/O 성능이 4배 이상의 차이가 난다. 디스크 개수가 4배라는 점 외에도 명령대기(Command Queuing)라는 메커니즘이 있어 여러 I/O 명령을 같이 모아서 효율적으로 실시할 수 있다. 스레드가 많아지면 이 혜택을 살리기 쉽고, 결과적으로 4배정도가 아닌 8~10배 정도 차이가 발생하는 일도 있다. 이문제를 해결하기 위해 가장 현실적인 해결책은 슬레이브에 SATA SSD를 사용하는것이다.
마스터 IOPS(1,000이상)와 슬레이브 IOPS(수백) 차이가 복제 지연을 일으키는 원인
단일 스레드에서 높은 IOPS를 얻는 방법은 없을까
SATA SSD Read IOPS 는 단일 스레드에서 3,000~5000 정도 낼 수 있다 (hdd15배 이상)
메모리 양이 그리 많지 않아도 hdd를 ssd를 교체하는 것만으로 복제 지연이 단숨에 해결
읽기 주체의 처리도 고속화
SSD를 마스터에 ? 이것은 용기가 필요..
마스터 보다 슬레이브가 효과가 크다 . (1,000이상 –> 수천) ,(수백–>수천)
우선 슬레이브 SSD 도입
슬레이브 대수 감소에 크게 기여
SATA 보다 빠른 PCI-EXPRESS 인터페이스의 SSD가 주목을 받음
데이터베이스 개선의 역사
cpu확장성 향상
디스크 I/O 병렬성의 개선 –> MySQL 5.0 까지는 I/O담당 스레드가 읽기 쓰기 하나씩,, ,5.1이후부터 개수 늘어남.
백그라운드 처리와 분할/병렬화
체크포인트 처리 및 DELETE된 레코드를 물리적으로 제거하는 처리 등… 이런처리 들이 쌓이면 일정시간 블록이 일어남 이러한 백그라운드 처리도 다중화 하고 고속화할 필요. MySQL 5.5 에서는 비동기 I/O도 지원되어 스레드 수가 적어도 I/O 요청을 많이 던질 수 있다
향후 데이터베이스에 요구되는것
네트워크 및 cpu의 이용 효율이 더 중요함. 고속화로 쿼리양이 증가하면 CPU사용률이 높아짐, 미래에는 병목현상이 CPU나 네트워크로 이동할 것..
새로운 리눅스 커널에는 Multiqueue 라는 기능이 있어 려어 CPU코어를 사용하여 네트워크 송수신이 가능
SQL문의 실행을 위한 문자열 처리, 데이터베이스와 연결 처리등 CPU를 사용하는 처리효율이 중요해짐,, 최근 주목을 끌고 있는 NoSQL은 이러한 CPU이용 효율 문제를 해결하는것이 커다락 목적임.
성능이외의 중요성이 높아짐.. 다양한기능, 높은 복원력, 자동화등등.
데이터베이스 운용 기술의 급소
잘알고 있는 기술사용,
모니터링해야 할 항목
응답시간
CPU사용률
디스크I/O
시스템 공간 사용률
사용자 공간 사용률
동시접속 수 및 스톨
예를 들어 갱신량이 너무 많아 redo 로그 파일로 쓰기가 따라가지 못하는 경우 갱신을 차단하고 REDO로그 파일을 씀. 이런 현상을 스톨이라고 한다.
초당 SQL문의 실행 횟수
접속 여부 및 데이터베이스 내부상태
대처 방법
애플리케이션수정,인덱스 추가
웹서버 증설
캐시서버증설
슬레이브 서버 증설
스펙이 높은 서버로 마이그레이션 및 서버 분할
MySQl로 배우는 데이터베이스 관리
스토리지엔진
운영기초 지식
로그파일 형식
오류로그파일 MySQL 프로세스의 기동/정지 및 오류정보를 출력하는 파일
슬로우쿼리 파일. 일정시간 이상이 걸린 쿼리를 로깅하는 파일
일반로그 파일, 개발/테스트환경에서 사용. 모든 쿼리출력
바이너리 로그파일. 업데이트성 SQL문을 모두 기록
백업기초
무엇을백업하는가
데이터베이스파일,바이너리 로그파일
백업유형
콜드백업과 온라인 백업,
논리적 백업과 물리적 ㅂㄱ업
복구방법
바이너리로그를 사용. 정해진 시간 이후 실행된 바이너리 로그를 따라간다. PTTR
MySQL의 소스코드
데이터베이스 기술동향
온라인에서의 스키마변경.
MySQL Cluster에서 지원.
트리거를 사용하여 변경내용을 이력테이블에 기록하고 현테이블을 덤프 후 새테이블로 옮김.
복제구성활용. 마스터 한대 슬레이브 두대라면 슬레이브를 순차적으로 정의변경후 마스터를 다른 슬레이브로 옮긴다,,그후 원래 마스터였던 노드의 스키마를 변경
스키마없는 데이터베이스. NoSQL
대량의 데이터를 고속으로 처리하는 기술
레인지 파티셔닝.
테이블 및 인덱스를 내부적으로 복수의 파일로 관리. 특정파티션에만 액세스를 집중시킴. 트위터나 일기의 경우 최근 데이터위주로 구성 한다던가..
B+트리 이외의 인덱스
TokuDB가 갖는 Fractal Tree라는 인덱스는 보조 인덱스의 크기가 아무리 커져도 Insert의 성능이 일정함.
고속의 SSD 이용
트랜잭션. 복제를 사용하고 있더라고. 트랜잭션을 지원하지 않으면 오류가 발생해도 일관성을 보장하지 못함
분석게열 처리 및 열 지향 데이터베이스
레코드와 데이터사이즈가 크다.
처리 대상이 아닌 열도 접근을 하게된다. 실제 접근은 열중 극히 일부.
인덱스 설계가 매우 어렵다.
열지향 데이터베이스가 좋은 궁합이 됨
필요할ㄴ 열만 액세스 되기 때문에 io효율이 높음
압축효율이 좋음. 일반적으로 Datawarehouse 는 카디널리티가 작아지는 경향이 있음
로드처리가 고속이다.
효율적인 조인 방식은 해시조인
단점– 기본 키 검색등 좁은 범위처리가 느림, 제품으로 성숙도가 떨어짐
NoSQL
일반적인 단점
트랜잭션을 지원하지 않음
스키마가없다
기본키 이외의 인덱스가 없음
용도
캐시
세션데이터
하이브리드 구성
MySQl Cluster
그 외의 주제
테이블과 Redo로그파일, 일반적인 2회 쓰기 형태가 아닌 1회쓰기로 완료하는 아키텍쳐ㅡ PBXT, Rethink DB같은 Write Once DB
Write Scaling
다중 마스터 구성,, 지역별 최적화 구성가능,,, 미국,일본,한국 별로 마스터 각각.. 문제는 충돌을 어떻게 감지할 것인가
자동 Shard 편성
기본적으로 Sharding 에 대한 로직은 애플리케이션에서 담당,,, 어느 데이터가 어느 Shard로 갈것인가?
매우 귀찮은 일임. 이를 자동화하는 유형의 DB도 나왔음, MySQL Cluster, MongoDB, HBase등
데이터베이스가 없으면 무엇이 곤란하가
대량의 데이터 중에서 필요한 것을 빨리 반환할 수 없다.
Excel 시트 등보다 효율적인 데이터 구조로 관리해야 한다. (B+ 트리 인덱스) 나 (해시인덱스) 와같은 데이터 구조로 이러한 레코드를 관리할 필요가 있다
대량의 데이터를 메모리 내에서만으로는 취급할 수 없다.
장애가 발생했을 때 빠른 복구가 어렵다
병렬성 제어가 어렵다
배타제어가 필요하며. 배타의 범위가 중요. 가장 단순한 형태는 Lock File 이다. 이러한 형태는 동시에 한 명만이 갱신 할 수 있기 때문에 실행 성능 면에서 매우 큰 제약이 생기게 되므로, 행 수준의 배타범위를 가지는 것이 바람직하다.이렇게 되면 단순한 파일로서의 제어가 어려워 지지만, 데이터베이스를 사용하면 이러한 배타 제어도 간단히 할 수 있게 된다, 배타 제어의 범위가 넓으면 병렬성이 떨어지고 속도면에서도 실용성이 줄어든다. 특히 최근에는 멀티 CPU가 대두되고 있음에도 동시에 하나의 처리밖에 할 고 한개의 코어만을 사용해야 한다는 것은 큰 손해이다.
데이터 무결성을 보장하는 것은 어렵다.
병렬성 제어와 강하게 연관된 요소이며,데이터 자체가 불일치를 일으키지 않게 하는 구조가 중요하다
인덱스로 고속 엑세스 실현하기
키와 값의 페어를 관리하고 싶다
선형 검색은 대량의 데이터에 적합하지 않다.
원하는 위치까지 순식간에 도달하는 방법
사용자 정보를 고정길이로 관리하는 기술 –>새로운 데이터 항목이 생길경우 어려움, 데이터낭비가 생김
인덱스 구조 도입하기
각 ID마다 파일상의 시작위치를 기록한다.
고정길이 레코드보다 효율적이고 확장성을 가진 형태로 검색이 가능, 인덱스–> 파일 2단계 액세스가 단점
해시인덱스
키값, 바이트 위치 인덱스에서 키는 문자열, 숫자, 날짜 등 여러가지를 생각할 수 있으므로, 고정길이로 생각하긴 어렵다. 실제 데이터베이스의 구현은 키 값을 그대로 관리하는 것이 아니라 키값을 해싱하여 사용. 해시 계산비용은 데이터양에 의존하지 않기 때무네 O(1)으로 가장빠른 알고리즘이다.
해시가 만능은 아니다.
가격이 10,00원 이하의 아이템을 찾아라
제목이 Final 로 시작하는 아이템을 찾아라 (범위검색)
시간순 정렬을 하고 싶다. ( 정렬 )
해시 인덱스는 일부용도에서만 빠르게 처리할 수 있다
인덱스의 기본 B+트리 인덱스
이진트리가 아니고 다분기 트리, 분기개수가 수십 개에서 수백 개에 걸치는 경우도 있다. 분기개수를 많이 하는 이유는 계층의 단수를 줄여 액세스를 줄이기 위해서
이진 트리의 경우 N계층당 2의n승 개 밖에 기록을 관리할 수 없다. 이진 트리의 경우 레코드 수 N당 탐색에 필요한 계산량이 O(log2N)이 되는 것으로 알려져 있다. O(N)과는 비교가 되지 않을 정도로 효율이 좋지만해시 인덱스 O(1)과 비교하면 효율성이 떨어진다. B+ 트리와 같은 다부기의 트리 구성을 취함으로써 O(logmN) 의 계사량ㅇ이 되어 액세스 수를 크게 줄일수 있다.
B 트리 인덱스 중에서도 RDBMS는 끝단의 리브 블록에서만 값을 관리하, B+ 트리 (혹은 그 발전형) 가 가장 많이 사용된다. B- 트리 라는 인덱스 구조도 있는데. 이것은 모든 값을 리프 블록에서만 갖도록 제한하지 않으며, 브랜치에서도 값을 가질 수 있다. 보통 B-트리 인덱스에 비하면 B+트리 인덱스는 어떠한 검색어라도 루트에서 리프까지 거치지 않으면 검색할 수 없다는 단점이 있지만. 브랜치가 보다 컴팩트하게 되므로 인덱스 자체의 계층구조를 작게 할 수 있다.즉 최악의 경우 액세스 횟수를 줄일 수 있다는 것을 의미한다. B- 인덱스의 경우 리프가 아닌 브랜치로 되돌아가 값의 존재를 확인 하고 브랜치로 올라 가거나 인근 리프로 가야하지만, B+ 인덱스라면 리프 블록에서 인접한 리프로만 이동하기 때문에 효율적이다. B+트리 인덱스를 사용하면 등호검색은 물론 부등호나 전방 일츠 검색등의 범위 검색도 리프 블록을 스캔하는 것만으로 완결하기 떄문에 고속이다. 이러한 사정으로 인해 B+트리 인덱스는 RDBMS의 사실상 표준으로 널리 사용되었다.
RDBMS에서는 어떻게 최적화를 실현하고 있는가
고유성의 보장 ,해시 인덱스라면 동일한 ID의 경우 반드시 동일한 해시값이 되고, B+트리 인덱스이면 동일한 리프에 도달하기 때문에 적은 코스트로 중복체크가 가능하다
멀티칼럼 대부분의 RDBMS는 두가지 요소를 결합한 인덱스를 만들 수 있으며,이러한 AND 조건에서 검색을 가속화할 수 있다
인덱스만을 읽는 검색. 인덱스 부분과 데이터 부분은 서로 독립적인 영역에 존재하고 있기 때문에 양쪽을 한번의 액세스로 단 번에 읽을 수 는 없다. 가격이 10,000원 이하인 상품의 개수를 알고싶다 라는 경우에는 가격인덱스가 있으면 이 인덱스에서 조건에 맞는 레코드 건수를 열거하는 것만으로 결과를 구할 수 있으므로 데이터 영역에 액세스할 필요가 없다. DB구현에 따라 이러한 검색패터에 있어 데이터 영역을 읽지 않고 인덱스 영역을 읽는 것만으로 고속으로 처리완료 할 수 있는데, 이러한 작업을 Index Only Read, Covering Index라고 부른다.
인덱스 병합. 부서코드가 100번 또는 입사 연도가 2010년인 직원을 찾고 싶다. 라는 경우, 이러한 OR 조건의 검색은 하나의 인덱스만으로는 검색에 도움이 되지 않는다. 그래서 한 번의 검색에서 두 개 이상의 인덱스를 동시에 사용하여 각각의 결과에서 원하는 레코드를 꺼내려고 하는 발상이 생겨남. 인덱스 병합은 각 인덱스에서 각각 검색을 실시하여 대상의 행 번호를 추출한다.그 다음 각각의 결과에 대해 AND 조건과 OR조건 등으로 집합 연산을 수행하고 마지막으로 남은 행 번호에 대해 실제 데이터를 읽어가는 효율적인 동작을 시행한다.
랜덤 액세스는 느리다. DB성능 특성을 이해하는데 있어 매우 중요한 것이 랜덤액세스 성능이다.HDD의 경우라면 대게 디스크가 반 정도 회전하는 시간이다. 고성능 디스크라도 분당 10,000~15,000 회전밖에 할 수 없다. 초당으로 환산하면 수백회정도이다.
업데이트 비용 절감을 위한 노력
인덱스는 본체데이터와 별도로 유지할 필요가 있기 때문에 검색성능은 높아지지만 업데이트 성능이 떨어진다는 단점이 있다. 각 DBMS는 이 업데이트 비용으 최대한 떨어뜨리기 위해 다양한 최적화를 구현하고 있다. 아래는 그 예
디스크에 모아서 기록하기. 전통적인 방식은 순서대로 업데이트된 순서대로 디스크에 써 나갈 것이다. 그러나 이런 식이라면 속도가 느린 랜덤 라이트가 많이 발생하게 된다. 이에 업데이트된 정보를 메모리나 전용파일 등에 일시적으로 기록하여 두고 나중에 모아서 단번에 리프 블록을 갱신하는 구조를 채택하고 있는 데이터베이스가 바로 MySQL(InnoDB) 이다. 이러한 구조에서는 랜덤라이트보다 훨씬 빠른 시퀀셜 라이트로 빠르게 처리한다.
병렬 갱신 성능. B+ 트리 인덱스에 값의 추가/갱신/삭제를 할 경우, 인덱스의 리프 블록의 내용을 이동시켜야 하는데 이것을 리프분할이라고 한다. 클라이언트에서 업데이트가 다수 발생하여 리프분할이 여기저기 일어날 경우, 그것들의 일관성을 갖는 것은 상당히 어려운 자업이다. InnoDB 등에서는 인덱스의 재편성 처리가 완료될 때까지 일체의 참조/갱신 처리를 차단하는 동작을 시행하고 있다. 재편성 조작 자체는 금방 끝나지만 동시에 대량의 insert update 를 시행하여도 동시성이 그다지 높아지지 않는 문제가 있다. 멀티코어 환경에서는 이러한 병렬 갱신성능으 중요성도 높아짐. B+ 트리 인덱스에는 락프리로 갱신 가능하게 하는 알고리즘도 제안되고 있다. 또한 현재 MySQL (InnoDB)에서 이것을 해결하는 가장 빠른 방법은 파티션테이블을 사용하는 것이다.
테이블 설계와 릴레이션
SQL문의 특징과 이를 잘 다루는 법
조인
대규모 애플리케이션에서는 특정 테이블로의 트래픽이 매우커서 한서버에서 처리할 수 없는 경우 테이블단위로 (또는 하나의 테이블을) 여러 서버에 분산하는 경우가
있다. 이런 분할을 샤딩이라고 한다. 샤딩을 하고 있으면 조인을 사용하기 어렵운데, 결합대상 테이블이 반드시 같은 서버에 있다고 할 수 없기 때문이다. 대규모가 될 것으로 예상되는 애플리케이션은 샤딩의 필요성을 처음부터 염두해 두고 거대하게 될 것 같은 테이블과 조인을 하지 않도록 애플리케이션을 작성하는 방법이 자주 사용된다.
SQL문의 실행효율
적절한 인덱스가 사용되고 있는지 확인. 쿼리분석도구 EXPLAIN 사용
SQL의 장점과 단점
기술습득이 용이함
기능면. 저장프로시저를 이용하면 다소 복잡한 로직은 구현가능. MySQL등의 오픈소스는 빈약한 기능을 제공하지만, Oracle에서는 PL/SQL이라는 전용언어까지 제공. 저장프로시저는 데이터베이스 서버에서 동작해서, 수십번 수행할 쿼리를 저장프로시저를 사용하면 네트워크 액세스 빈도를 줄일 수 있다.. 네트워크가 느린 10년전 이야기,, 최근은 사용하는 일이 적고 로직은 프로그래밍 언어, 데이터 조작은 sql에 분담시키는 이유는 프로그래밍언어 쪽이 저장 프로시저보다 개발환경이 압도적으로 좋기 때문.
가용성과 데이터의 복제
디스크 이중화로 데이터 손실 방지하기
용량에 여유가 있으면 RAID1 없는 경유에는 5이다
복제
단방향복제
MySQL 표준 복제. 마스터에 갱신한 결과가 슬레이브로 비동기 전파하는 유형.
마스터에서 실행한 갱신계의 SQL문이 바이너리 로그라는 전용로그 파일로 기록된다. 이 로그 파일로 슬레이브로 전송
슬레이브는 바이너리 로그 수신, 바이너리 로그 수행 2단계로 이루어져, 각각 I/O스레드 , SQL스레드에서 실행한다. 이모두 비동기. 디스크에 비해 네트워크 병목이 되는 일이 적기 때문에 거의 동기에 가까운 속도로 실행된다.
마스터가 장애를 일으킨 경우 슬레이브에서 지금까지 업데이트 결과가 반영되지 않을 수 있다.
마스터에서 생성한 바이너리 로그가 슬레이브에서 마지막까지 수신되지 않은상황
슬레이브에서의 바이너리 로그의 실행이 마지막까지 종료되지 않은 상황
단방향/준동기화
MySQl의 경우에는 슬레이브가 바이너리 로그를 수신하는 부분을 동기화 방식으로 할 수 있다. 이것을 준동기식 복제라고 한다. 마스터를 업데이트한 클라이언트는 그 결과 뿐만 아니라 대상 슬레이브로 전송하여 그 확인응답이 반활될 때까지 기다림.
단방향/동기
MySQL기능으로서 구현되어 있지 않지만. 슬레이브에 대한 업데이트 결과 반영까지 응답을 반환하는 방식.
양방향 복제
마스터를 두 개 이상 갖게 하고 각각의 마스터를 업데이트할 수 있도록 한 멀티마스터라는 구성도 생각할 수 있다.
기술적으로 어려움. 업데이트가 서로 충돌하면 어떻게 하느냐?
MySQL Cluster는 여러 서버에 각각 업데이트를 할 수있으며 그들이 자동으로 동기화 되는 구조이다.
트랜잭션과 무결성,무정지성
SQL문 레벨에서의 롤백
한번의 업데이트성 SQL문에서는 여러 레코드를 업데이트 할 수 있다.,인덱스나, 물리적 위치 등등.
무정지성 확보하기
Oracle 과 InnoDB 같은 트랜잭션 대응 DB는 REDO로그를 이용한 아키텍트로 무정지성을 보장한다.
REDO 로그의 역할
InnoDB에서는 트랜잭션을 커밋하면 그때마다 LSN이라는 시퀴스 번호가 증가하고, 그 번호와 갱신 대상의 블록의 정보를 REDO로그 파일에 쓴다.
한편 열 값과 인덱스를 갖는 데이터 파일에는 커밋을 할 때마다 기록을 하는 것이 아니라 캐시 영역에 보관해 두고 정기적으로 디스크에 기록을 한다.
서버 장애 등의 이유로 데이터베이스가 멈춰 재기동을 하는 경우 캐시영역의 데이터는 없어졌기 떄문에 데이터 파일과 REDO로그에 기록되있는 데이터가 올바르다. 그러나 데이터 파일은 이전 데이터 밖에 남지 않아있지 않기 때문에 REDO로그의 내용을 데이터 파일에 적용시켜 나감으로써 데이터 파일과 REDO로그의 LSN을 일치시키는 작업을 수행한다. 이 과정을 충돌 복구( Clash recovery ) 라고 한다. 복구 시에는 적용을 시작할 가장 오래된 LSN을 틍정한 뒤 그 위치에서부터 REDO로그의 내용을 순서대로 대응해 나간다.
이중 기록의 비용
1회 갱신에 대한 그 자체의 갱신 정보를 REDO 로그에 동기적으로 기록하면서 나중에 데이터 파일에도 기록하는 식의 두 번의 기록이 발생. 그렇다고 두배로 느려지는것은 아님. REDO로그 파일이 순차적으로 기록을 하는 특징이 있기 때문에. 레코드나 익덱스의 기록은 램던 라이트 이다.
잠금 메커니즘에 의한 배타제어
잠금의 범위 – MyISAM의 경우 테이블에 대해 배타적 잠금을 건다. InnoDB등은 레코드 단위로 잠금을 건다.
잠금기간 = 트랜잭션의 종료시까지 유지.
복제 및 트랜잭션
스토리지 기술의 변천
인덱스와 실제 데이터는 물리적으로 인접해 있지 않기 때문에 별도로 액세스할 필요가 있음 –> 이러한 접근 방식은 랜덤 액세스
동일한 쿼리라 해도 초당 수천~수십만쿼리가 가능한 이유는 데이터가 메모리에 있는가 아니면 디스크에 있는가
가정해서 사용자 수가 50만 명, 총 50GB정도의 데이터라면 ,, 메모리 가겨이 하락하고 64비트 리눅스로서 한대당 16GB이상 메모리를 탑재하여 히트율을 높인다. DB서버용으로 50GB의 사용하면 몇배의 실 데이터를취한다.
DB서버 한 대당 데이터양 /사용자 수가 몇배가 늘어나면 새로운 문제가 생긴다. 집계 처리와 같은 단일 스레드에서 행하는 타입의 작업에 시간이 오래 걸린다는 점이다. MySQL 에서는 복제 구성을 일방적인 방식이지만, 사실 MySQL의 복제는 단일 스레드로 작동한다. 따라서 복제 구성의 문제가 표면화 되었음. 한 대당 다수의 트래픽이 마스터에 전해지게 되면 마스터는 병렬화된 처리가 행해진다. 한편, 복제는 단일 스레드이기 때문에 갱신처리는 직렬화 된다. 마스터의 갱신에 비해 오래 걸리고 신시간으로 마스터의 갱신처리를 따라잡을 수 없어 지연되어 버린다. 64비트 OS대두의 부작용으로 수십 분 이상의 복제 지연이 관찰 되기도함.
단일 스레드 처리의 성능 지연의 주요이유는 디스크 I/O가 느리기 때문. 4개의 HDD에서 RAID10 구성을 하면 단ㅇ일 스레드와 다중 스레드 경우 I/O 성능이 4배 이상의 차이가 난다. 디스크 개수가 4배라는 점 외에도 명령대기(Command Queuing)라는 메커니즘이 있어 여러 I/O 명령을 같이 모아서 효율적으로 실시할 수 있다. 스레드가 많아지면 이 혜택을 살리기 쉽고, 결과적으로 4배정도가 아닌 8~10배 정도 차이가 발생하는 일도 있다. 이문제를 해결하기 위해 가장 현실적인 해결책은 슬레이브에 SATA SSD를 사용하는것이다.
마스터 IOPS(1,000이상)와 슬레이브 IOPS(수백) 차이가 복제 지연을 일으키는 원인
단일 스레드에서 높은 IOPS를 얻는 방법은 없을까
SATA SSD Read IOPS 는 단일 스레드에서 3,000~5000 정도 낼 수 있다 (hdd15배 이상)
메모리 양이 그리 많지 않아도 hdd를 ssd를 교체하는 것만으로 복제 지연이 단숨에 해결
읽기 주체의 처리도 고속화
SSD를 마스터에 ? 이것은 용기가 필요..
마스터 보다 슬레이브가 효과가 크다 . (1,000이상 –> 수천) ,(수백–>수천)
우선 슬레이브 SSD 도입
슬레이브 대수 감소에 크게 기여
SATA 보다 빠른 PCI-EXPRESS 인터페이스의 SSD가 주목을 받음
데이터베이스 개선의 역사
cpu확장성 향상
디스크 I/O 병렬성의 개선 –> MySQL 5.0 까지는 I/O담당 스레드가 읽기 쓰기 하나씩,, ,5.1이후부터 개수 늘어남.
백그라운드 처리와 분할/병렬화
체크포인트 처리 및 DELETE된 레코드를 물리적으로 제거하는 처리 등… 이런처리 들이 쌓이면 일정시간 블록이 일어남 이러한 백그라운드 처리도 다중화 하고 고속화할 필요. MySQL 5.5 에서는 비동기 I/O도 지원되어 스레드 수가 적어도 I/O 요청을 많이 던질 수 있다
향후 데이터베이스에 요구되는것
네트워크 및 cpu의 이용 효율이 더 중요함. 고속화로 쿼리양이 증가하면 CPU사용률이 높아짐, 미래에는 병목현상이 CPU나 네트워크로 이동할 것..
새로운 리눅스 커널에는 Multiqueue 라는 기능이 있어 려어 CPU코어를 사용하여 네트워크 송수신이 가능
SQL문의 실행을 위한 문자열 처리, 데이터베이스와 연결 처리등 CPU를 사용하는 처리효율이 중요해짐,, 최근 주목을 끌고 있는 NoSQL은 이러한 CPU이용 효율 문제를 해결하는것이 커다락 목적임.
성능이외의 중요성이 높아짐.. 다양한기능, 높은 복원력, 자동화등등.
데이터베이스 운용 기술의 급소
잘알고 있는 기술사용,
모니터링해야 할 항목
응답시간
CPU사용률
디스크I/O
시스템 공간 사용률
사용자 공간 사용률
동시접속 수 및 스톨
예를 들어 갱신량이 너무 많아 redo 로그 파일로 쓰기가 따라가지 못하는 경우 갱신을 차단하고 REDO로그 파일을 씀. 이런 현상을 스톨이라고 한다.
초당 SQL문의 실행 횟수
접속 여부 및 데이터베이스 내부상태
대처 방법
애플리케이션수정,인덱스 추가
웹서버 증설
캐시서버증설
슬레이브 서버 증설
스펙이 높은 서버로 마이그레이션 및 서버 분할
MySQl로 배우는 데이터베이스 관리
스토리지엔진
운영기초 지식
로그파일 형식
오류로그파일 MySQL 프로세스의 기동/정지 및 오류정보를 출력하는 파일
슬로우쿼리 파일. 일정시간 이상이 걸린 쿼리를 로깅하는 파일
일반로그 파일, 개발/테스트환경에서 사용. 모든 쿼리출력
바이너리 로그파일. 업데이트성 SQL문을 모두 기록
백업기초
무엇을백업하는가
데이터베이스파일,바이너리 로그파일
백업유형
콜드백업과 온라인 백업,
논리적 백업과 물리적 ㅂㄱ업
복구방법
바이너리로그를 사용. 정해진 시간 이후 실행된 바이너리 로그를 따라간다. PTTR
MySQL의 소스코드
데이터베이스 기술동향
온라인에서의 스키마변경.
MySQL Cluster에서 지원.
트리거를 사용하여 변경내용을 이력테이블에 기록하고 현테이블을 덤프 후 새테이블로 옮김.
복제구성활용. 마스터 한대 슬레이브 두대라면 슬레이브를 순차적으로 정의변경후 마스터를 다른 슬레이브로 옮긴다,,그후 원래 마스터였던 노드의 스키마를 변경
스키마없는 데이터베이스. NoSQL
대량의 데이터를 고속으로 처리하는 기술
레인지 파티셔닝.
테이블 및 인덱스를 내부적으로 복수의 파일로 관리. 특정파티션에만 액세스를 집중시킴. 트위터나 일기의 경우 최근 데이터위주로 구성 한다던가..
B+트리 이외의 인덱스
TokuDB가 갖는 Fractal Tree라는 인덱스는 보조 인덱스의 크기가 아무리 커져도 Insert의 성능이 일정함.
고속의 SSD 이용
트랜잭션. 복제를 사용하고 있더라고. 트랜잭션을 지원하지 않으면 오류가 발생해도 일관성을 보장하지 못함
분석게열 처리 및 열 지향 데이터베이스
레코드와 데이터사이즈가 크다.
처리 대상이 아닌 열도 접근을 하게된다. 실제 접근은 열중 극히 일부.
인덱스 설계가 매우 어렵다.
열지향 데이터베이스가 좋은 궁합이 됨
필요할ㄴ 열만 액세스 되기 때문에 io효율이 높음
압축효율이 좋음. 일반적으로 Datawarehouse 는 카디널리티가 작아지는 경향이 있음
로드처리가 고속이다.
효율적인 조인 방식은 해시조인
단점– 기본 키 검색등 좁은 범위처리가 느림, 제품으로 성숙도가 떨어짐
NoSQL
일반적인 단점
트랜잭션을 지원하지 않음
스키마가없다
기본키 이외의 인덱스가 없음
용도
캐시
세션데이터
하이브리드 구성
MySQl Cluster
그 외의 주제
테이블과 Redo로그파일, 일반적인 2회 쓰기 형태가 아닌 1회쓰기로 완료하는 아키텍쳐ㅡ PBXT, Rethink DB같은 Write Once DB
Write Scaling
다중 마스터 구성,, 지역별 최적화 구성가능,,, 미국,일본,한국 별로 마스터 각각.. 문제는 충돌을 어떻게 감지할 것인가
자동 Shard 편성
기본적으로 Sharding 에 대한 로직은 애플리케이션에서 담당,,, 어느 데이터가 어느 Shard로 갈것인가?
매우 귀찮은 일임. 이를 자동화하는 유형의 DB도 나왔음, MySQL Cluster, MongoDB, HBase등