하테나 북마크의 데이터의 사이즈는 무려 3억 5천만개가 넘는다고 합니다.
SELECT COUNT(*) FROM relword;
3512277311
따라서 SELECT * FROM relword;
와 같은 쿼리는 응답이 반환되지 않습니다. 그 이유는 3억개 이상의 레코드가 존재하기 떄문입니다.
잡담 : 실제로 회사에서
SELECT * FROM tables
와 같은 쿼리를LIMIT
제한을 걸지 않고 날린 적이 있는데, 다수의 클러스터를 모두 쿼리했기에, 인프라팀에서 내부자산으로의 다량의 포트스캔이 감지되었다고 메일이 날라온 적이 있습니다.
저자는 다음과 같이 인덱스를 태우지 않고 쿼리를 던졌는데, 200초가 넘게 검색결과가 나오지 않는다고 합니다.
SELECT url FROM entry USE INDEX(hoge) WHERE eid = 98615899;
// 200초 넘게 응답 X
이 것이 이 책에서 대상으로 하는 대규모 데이터에 대한 예입니다. 데이터의 크기는 크게 수 GB부터 수백 GB, 이 정도 데이터가 되면 아무 생각 없이 던진 쿼리가 응답하지 않으며, 디버그 목적으로 데이터를 출력하고자 하여도 엄청난 부하가 걸리게 됩니다.
주의 : 데이터베이스는
공용
이라는 것을 인지하고 사용합시다.
메모리 내에서 계산할 수 없다.
라는 점이 가장 어려운 포인트 입니다. 메모리에 올리지 않으면 기본적으로 디스크를 계속 읽어가면서 검색하게 되어 좀처럼 발견할 수 없는 상태가 됩니다.
데이터 건수가 많으면 입력 데이터 건수가 늘어나는 것도 있지만, 계산량이 많아지는 것보다 중요하게 여길 것은 디스크를 많이 읽고 있다. 라는 점입니다.
메모리 내의 특정 번지에 있는 데이터를 찾는 데이터 탐색과 디스크의 특정 원반 내에 있는 데이털르 찾는 것은 얼마나 속도차가 날까 계산해 봅시다.
이 책이 쓰여진
2009년도
에는 메모리가 디스크보다10^5 ~ 10^6
정도 빠르다고 합니다. (즉 10만~100만 배)
이후의 디스크는
HDD
를 의미합니다.
디스크는 여러개의 판으로 이루어져있고, 헤더가 그 판을 트랙마냥 읽으며 정보를 읽습니다.
따라 정보를 읽어오기 위해서는 헤더의 이동
과 원반의 회전
이라는 두가지 물리적인 이동이 필요합니다. 이런 특징 때문에 메모리의 경우는 마이크로초 단위로 정보를 읽어올 수 있지만 디스크의 경우 수십밀리초까지 걸리는 것입니다.
데이터가 여러군데 흩어져 있다면 그만큼 디스크와 헤더가 물리적으로 많이 이동해야 하기에 속도가 느려집니다.
디스크는 느리지만 OS
는 이것을 어느 정도 커버하는 작용을 합니다. OS
는 연속된 데이터를 같은 위치에 쌓으며, 데이터를 읽을 때 한꺼번에 한 단위의 데이터를 읽어옵니다.
따라 1회의 디스크회전으로 최대한 많은 데이터를 읽어 올 수 있도록 합니다.
탐색속도 뿐만 아니라 전송속도도 차이가 납니다. 메모리나 디스크 모두 CPU
와 버스로 연결되어 있습니다.
따라 탐색 속도 뿐만아니라 데이터를 전송하는데도 속도차가 나게 됩니다.
앞 장에서 메모리와 디스크의 속도차를 알아보았고, 데이터가 대규모화 되면 될 수록 이 속도차는 더욱 더 커질 것입니다. 이번 장에서는 이런 사항들이 시스템 전체의 확장성 전략에 어떤 영향을 주는지 알아봅니다.
대규모 환경이라고 하면 서버를 여러 대 나열해놓고 그 서버로 부하를 분산한다라는 얘기를 들어보았을 것입니다. 웹 서비스에서 자주 거론되는 규모조정(scaling) 및 확장성(scalability)가 그런 종류의 이야기입니다.
앞단에서 말했듯 고가의 빠른 하드웨어를 사서 성능을 높이는 스케일업(scale-up)
전략 보다도 저가이면서 일반적인 성능의 하드웨어를 많이 나열해서 시스템 전체 성능을 올리는 스케일아웃(scale-out)
전략이 주류입니다. 개별적인 이유는 다양하겠지만, 스케일아웃 전략이 더 나은 이유는 웹 서비스에 적합한 형태이고 가성비가 좋다는 점이 포인트입니다.(10배 비싼 하드웨어가 10배 더 빠르지 않습니다.)
스케일 아웃을 통해 CPU 부하의 확장성
을 확보하는 것은 쉽습니다. DB
에 질의하고 응답 데이터를 가공해서 HTTP
로 반환하는 것은 기본적으로 CPU
의 몫 입니다.
하지만, I/O
부하를 해결하기 위해 스케일 아웃을 이용하면 동기화의 문제가 생기게 됩니다. 즉, Write
하는 행위를 간단하게 분산할 수 없습니다.
서비스를 운영하다보면 서비스가 무거우니 서버를 늘리는 것은 어때?
와 같은 제안을 하는 경우도 있는데, 사실 서버를 늘려서 해결할 수 있으면 아주 간단한 것 입니다.
이런 동작은 CPU 부하
를 해결해 줄 순 있지만 I/O 부하
를 해결해 주진 못합니다.
대규모 데이터는 메모리에서 처리하기 어렵고, 디스크 I/O
는 느립니다. 또한 이를 분산하기도 힘듭니다. 그렇다면 어떻게 해결해야 할까요?
그 방법에 대해 저자는 두가지 관점에서 설명합니다.
세가지 요령을 제공합니다.
Seek
을 최소화한다는 의미로 메모리를 활용하라.Log Order
알고리즘을 적용하는 등 대규모 데이터에 적합한 알고리즘을 활용하라.seek
횟수도 적어지게 될 것이다.프로그램을 만드는 입장에서는 알고리즘, 압축, 검색 등이 중요합니다. 책에서는 이를 활용하는 세가지 예를 들도록 하겠습니다.
OS
캐시 활용RDBMS
를 운용할 떄는 어떻게 해야하는지