#title 튜닝의 개요 [[TableOfContents]] ==== 개요 ==== 이 문서에서는 필자 나름대로의 튜닝에 대한 의미와 무엇이 성능에 관련된 것들이며, 궁극적인 목표가 무엇인지에 대한 이야기를 한다. 튜닝의 의미를 제대로 아는 것은 튜닝의 좋은 출발점이 된다. [Performance Tuning] 부분은 데이터베이스 이론을 설명하는 부분이 아니다. 그러므로 잡다하게 용어설명은 하지 않을 것이다. 단지 여러분이 들어보고 알고 있던 용어들에 대해서 좀 더 깊이 살펴볼 것이다. 기본이 갖춰져 있지 않다면 당장 브라우저를 접고, 데이터베이스론 책을 다시 보기 바란다. 참고로 이 사이트에서는 "성능튜닝"이 "튜닝"과 동의어다. ==== 튜닝이란? ==== 튜닝이란 주어진 시스템의 자원을 최대한 효율적을 사용하게끔 하는 작업이다. 특히 SQL 튜닝과 같은 작업에서 간단한 수정만으로도 20 ~30배 또는 몇 백배 빨라지는 경우를 많이 볼 수 있는데, 이것은 주어진 자원을 최소한으로 사용하여 원하는 결과를 얻게끔 한 작업일 뿐이다. 주어진 자원을 최소한으로 사용했다는 것은 시스템의 자원을 최대한 효율적으로 사용하게끔 한 것이라고 바꾸어 말할 수 있다. 만약 주어진 자원을 최소한으로 사용하는데 불구하고, 적시에 결과를 내지 못한다면, 설계문제에 의한 한계 또는 하드웨어 자원의 부족이다. 시스템의 자원을 사용하는 것은 무엇인가? 바로 어플리케이션 프로그램이다. 이 어플리케이션 프로그램들이 주어진 자원을 잘 사용하게 하기 위해서는 환경을 잘 만드는 것이 중요하다. 그 환경(통계정보, 서버 구성 등)이라는 것은 대부분 기본에 속하는 것들이며, 우리가 그토록 싫어하고 무시하는 기본에서 남들이 말하는 고급기술(실제로 필자는 이것이 고급기술이라고 보지는 않는다.)이 나온다고 보면 맞다. 기본은 설계에 그대로 반영되어야 하며, 기본이 잘 반영된 설계는 정보의 질을 좋게 해주는 것이다. 튜닝을 성능을 높이는 작업이라고 본다면, 이것은 궁극적으로 원하는 목표에 끝이라고 생각하면 안 된다. 정보의 3요소인 정확성, 적시성, 관련성 중 적시성만을 만족시킨 것이기 때문이다. 아무리 빠르다고 해도 정확하지 못하고, 관련성이 없는 결과는 정보가 아닌 데이터이기 때문이다. __튜닝의 궁극적인 목표는 정보의 질을 향상시키는 것이고, 이것은 사용자의 정보 욕구를 만족시키는 것으로 마무리가 된다.__ 그렇다면 어느 기준에 맞추어 최적화냐 아니냐를 따져야 할까? 이미 답은 나와 있다. 최적화의 기준은 사용자의 만족에 두면 된다. "고객님 저희가 만든 프로그램이 만족스러우십니까?" 했을 때 "그냥 그럭저럭 쓸 만하다." 라는 답을 얻는다면 아마도 미소 정도는 지을 수 있는 자격이 될 것이다. ==== 성능 개념 ==== Performance Concept * Latency - Task가 완료되는데 걸리는 (예상할 수 있는)시간(Activity는 Task의 모임), Latency의 종류(I/O, Handshaking...) * Throughput - 단위 시간에 처리할 수 있는 Activity의 양 * Performance - 각각의 Task들을 얼마나 빨리 처리할 수 있는지.. 퍼포먼스 높이기 위한 고려사항들.. * 반드시 해야 할 작업과 나중에 처리해도 되는 작업을 분리(Dependency 고려, 동기화되어야 하는 작업 ..) * 하드웨어 증설(Sacle-Up) -> 개발의 고통이 없다. * 설계 변경(알고리즘, 데이터구조) * 작업에 대한 병렬 처리(scale-out에 의한 병렬처리, 성능의 선형증가) 어떤 부분을 개선? * 개선 전 측정한다.(외국 애덜은 아주 면밀하게 측정한다, POC(Proof-of-Concept)) * 우리의 비지니스에 가장 필요한 부분은 어떤 부분이고, 성능개선이 필요한 부분은 어떤 부분인가? Bottleneck * Client + Server Pattern 전체구조에서 Sigle point Bottle-neck --> 매우 중요하다.. * Master-Slave Pattern(Master + Worker Pattern) -> Master Bottleneck Failure and Recovery Partition for Parallelism * 7200 SATA dirve = 30 - 80 IOPS * 10k SCSI/SAS = 140 IOPS * 15k SCSI/SAS = 180 IOPS raid 10: read = 1 IOPS write = 2 IOPs (mirroring write penatly) raid 5 read = 1 IOPS write = 4 IOPS(parity write penatly) 참고 * Throughput(IOPs) * Physical Disk * Disk Read Bytes/Sec * Disk Write Bytes/Sec * Disk Read/Sec * Disk Writes/Sec * Latency(10 ~ 20ms) * Physical Disk * Avg. Disk Sec/read * Avg. Diks Sec/wrtie * Wait Statistics * Page Io latch waits * Page latch waits * Non-Page latch waits ==== 튜닝의 범위 ==== 튜닝은 사용자에게서 느리다는 불만이 나왔을 때 행해지는 작업이 아니다. 튜닝은 전 개발 과정에 이루어져야 하는 작업으로 각각의 개발 단계에서 튜닝이 행해짐으로써 비용과 시간이 절감될 수 있다. 그러므로 튜닝의 범위는 "모든 범위"로 보면 된다. 대부분의 개발방법은 대부분 폭포수 모델을 근간으로 한 개발방법이다. 폭포수 모델의 가장 큰 단점은 이전 결과물에 막대한 영향을 끼치는 것이다. 그러므로 첫 단추를 잘 꿰어야 시스템 개발이 순조로워 진다. 그러므로 실제 구현보다는 설계 이하의 과정에 초점을 맞추는 것이 좋은 튜닝 전략임은 더욱 분명해진다. 튜닝의 범위는 정보시스템에 한정된 것은 아니다. 업무분석 과정에서 업무를 재조정함으로써 얻는 튜닝의 효과도 뛰어나며, 정보시스템 개발과정에서 BPR(BUSINESS PROCESS RE-ENGINEERING)을 수행하는 것이 일반적이다. 예를 들어 어떤 부서에도 소속되지 않는 사원이 있다면, 인사부에 넣는 것으로 한다면 정보가 단절되지 않을 수 있다는 것이다. 이러한 것은 모델링과 설계 부분에서 좀 더 자세하게 다룰 것이다. ==== 튜닝의 시기와 효과 ==== 튜닝은 아래의 그림처럼 개발 초기에 이루어질수록 비용은 절감되고 효과는 높일 수 있다. 특정 개발단계에서만 튜닝을 하는 것은 그만큼 효과가 떨어지며, 모든 개발단계에서 튜닝이 이루어진다면 비용과 효과 면에서 많은 이득을 볼 수 있다. attachment:튜닝의개요/tuning_effect.jpg 대부분의 문제점은 시스템의 전 개발과정에서 튜닝이 이루어지지 않음에 비용과 시간이 많이 소요되는 것이다. 튜닝에 대한 인식이 바뀌는 것이 중요하다. 앞으로도 설계문제로 인한 이슈가 많이 다루어질 것이므로 자연히 계몽될 것이다. ==== 튜닝의 종류 ==== 튜닝은 각각의 개발단계별로 이루어지며, 튜닝의 종류는 다음과 같다. 나열된 순서는 필자가 중요하게 생각하는 튜닝의 순서이다. 노파심에서 이야기하지만 여기서 말하는 설계튜닝은 어떤 H/W 제품을 쓰는지도 포함한다. * 비즈니스 프로세스 튜닝 * 요구사항 튜닝 * 설계 튜닝 * 어플리케이션 튜닝 * 하드웨어 튜닝(서버 튜닝) 비즈니스 프로세스 튜닝과 설계 튜닝은 일반적으로 거의 동시에 일어나는 작업이 될 수 있으며, 일반적인 프로젝트에서의 튜닝은 설계단계 이후에 발생하게 된다. 그러므로 대부분 현실에서의 튜닝 작업은 어플리케이션 튜닝작업이 가장 먼저 일어나게 되며, 그 다음으로는 하드웨어 튜닝의 단계를 거친다. 문제점이 일어나지 않는 환경을 만드는 것이 데이터베이스의 기본철학임에도 불구하고, 문제점이 일어나야만 그것을 해결하는 노력에서 나온 결과이다. 잘못되었다고 보지만 지금의 현실이다. 많은 경우 어플리케이션 튜닝 단계를 거치지 않고, 하드웨어를 증설함으로써 성능을 높이는 작업을 하기도 한다. 그 이유는 어플리케이션 튜닝의 능력이 안되므로 컨설턴트를 불러야 하는데 그 비용이 만만치 않기 때문이거나 아예 그 중요성을 모르기 때문일 것이다. 하드웨어의 증설은 바람직한 방법은 아니지만 역시 특정 상황에서는 현실적인 방법이기도 하다. 그러나 문제점을 그대로 가져가는 근시안적인 방법임을 알아 두어야 한다. 중요한 것은 설계가 뒷받침 되지 않으면 어플리케이션 튜닝이라든지 하드웨어 튜닝은 한계가 있다는 것이다. 설계상의 문제로 어플리케이션 튜닝이 불가능한 경우도 많이 있다. 앞으로 많은 예제가 설계 쪽과 연결하여 문제를 연관시킬 것이다. ==== 일반적인 목표 ==== 데이터베이스 튜닝의 일반적인 목표는 다음과 같으며, 모든 DBMS에 적용된다. * 최소한의 디스크 입/출력 * 메모리의 최대 활용 * 최소의 페이지(블록) 이용 * 자원 사용의 경합을 줄이는 것 * 백업/복원 등의 큰 작업이 가능한 빨리 이루어져 서비스에 영향을 주지 않게 하는 것 가장 중요한 성능요소는 DISK I/O이다. (물론 설계가 뒷받침 되었을 때의 이야기다) CPU는 DISK로 직접 접근을 못하고, MEMORY(이후부터 RAM 또는 Main Memory는 모두 Memory이다.)에만 접근이 가능하므로 사용자의 요청이 있을 때, MEMORY에서 원하는 데이터가 없다면 CACHE MISS 하게 되고, DISK I/O를 하게 된다. MEMORY와 DISK의 성능 차이는 일반적으로 10의 6승배만큼 차이가나며, 대부분의 성능 차이는 DISK I/O 또는 Memory I/O에서 판가름 된다. Disk에 대한 이야기는 나중에 심도 있게 다시 다룰 것이다. 그렇다고 해서 I/O에만 너무 집착하면 안 된다. CPU, MEMORY에도 신경을 써줘야 한다. 특정 부분만이 빨라졌다고 모두 빨라지는 것은 아니다. 조인의 경우도 과도한 HASH JOIN이 일어나면 CPU가 많이 사용된다. 대부분 HASH 조인은 대용량 데이터베이스에서 많이 볼 수 있는데(설계의 잘못으로 자주 보이기도 한다), 일반적인 OLTP환경에서 HASH 조인과 MERGE 조인이 많이 일어나는 것을 보았다면 뭔가 잘못되고 있음을 암시하는 것이 된다. OLTP환경에서 대부분의 쿼리는 NESTED LOOP JOIN으로 충분히 해결될 수 있다. 실제로 어플리케이션(SQL)이 잘못 짜여진 경우가 성능을 저하시키는 요인으로 많이 작용하기도 하나 기본적인 구성이 잘못되어 있다면 어느 곳이 병목점이 되는지 파악하는 것도 매우 중요하다. CPU, MEMORY는 충분하나 DISK에 경합이 일어나면, 느려질 수도 있다. 대부분 CPU, MEMORY를 많이 신경 쓰는데 실제로 많은 병목점은 DISK다. 그렇다고 무조건 DISK에 병목이 있다고 생각하면 오산이다. Memory가 부족해도 Disk 병목이 생긴다. 폰 노이만의 프로그램 내장방식의 구조상의 문제이다. 종합적인 판단이 있어야 하는 것은 당연하다. 대부분의 경우는 Disk I/O, Memory I/O, Network I/O에 집중을 하고, 특정한 경우에 CPU등의 다른 자원의 사용에 눈을 돌리면 될 것이다. ==== 일반적인 지침 ==== 튜닝의 일반적인 지침은 다음과 같다. * 핵심적인 작업과 트랜잭션을 최대한 빨리 구별 * 응용프로그램에게 제어권을 최대한 빨리 넘김 * I/O에 집중 * Index등의 물리적인 객체를 최대한 이용할 것 대부분의 DBMS에서는 SQL자체가 느린 것인지 어느 한 곳이 병목이어서 느린 것인지 구분을 해야 한다. LOCK 이슈로 느려지는 경우도 허다하다. 그러므로 먼저 LOCK 이슈인지 아닌지를 판단하는 것도 좋은 튜닝의 방법이다. 실제로 LOCK에 의한 블록킹이나 데드락은 큰 걱정거리가 되지 않는다. LOCK을 너무 의식하면 LOCK의 본질을 잊는 수가 많이 있다. LOCK은 데이터베이스의 일관성을 위해 꼭 필요한 것이다. LOCK 자체는 부하가 아니다. 실제의 부하는 LOCK으로 인해 QUERE에 작업이 쌓이고, 이것을 처리하기 위해서 LOCK이 풀림과 동시에 자원의 경합으로 인해 느려지는 것이 문제이다. 그러므로 QUEUE에 작업이 쌓이기 전에 LOCK을 빨리 풀어주는 것이 중요하다. 그러므로 많은 서적에서는 트랜잭션을 짧게 가져가라고 하는 것이다. 더 자세한 것은 이후에 트랜잭션 처리에 대한 몇 가지 기법을 살펴볼 것이다. 버전으로 관리를 할 수도 있으나 상용DBMS는 버전으로 일관성을 관리하는 것은 없다고 보면 된다. ==== 중요한 것 ==== 중요한 것은 '현상'을 해결하는 것이 아니라 '원인'을 해결하는 것이다. 현상A만을 해결하면 현상A만이 발생하지 않는다. 하지만 대부분의 경우 현상A의 원인을 파악하여 해결하면 튜닝 초기의 경우 하나의 원인만 해결해도 20~30%의 성능 문제가 해결되는 경우도 있다. '현상'에 집중하지 말고, '원인'에 집중하자.