성능이란 무엇인가?
원문은 Salvatore Sanfilippo님이 에 게재했습니다. 이 블로그 구독하기
이 블로그 글의 제목은 언뜻 보기에 답하기 쉬워 보이는 질문이지만, 성능이 진정으로 무엇을 의미하는지 좀 더 깊이 생각해 볼 가치가 있다. 확장성과 성능을 혼동하기 쉽고, 특히 데이터베이스 시스템이라는 맥락에서 성능을 주요 구성 요소들로 분해하는 일은 결코 자명하지 않기 때문이다. 이 짧은 글에서는 데이터베이스 시스템의 맥락에서 내가 현재 생각하는 성능의 개념을 정리해 보고자 한다.
좋은 출발점은 아마도 최근 Redis에 대해 강연할 때 사용하는 첫 번째 슬라이드일 것이다. 이 첫 슬라이드는 다름 아닌 성능에 관한 것으로, 성능이란 크게 세 가지라고 말한다.
- 레이턴시: 쿼리에 대한 응답을 받기까지 걸리는 시간.
- 코어당 단위 시간당 연산 수: 주어진 기준 연산 단위에서 시스템이 초당 몇 건의 쿼리(연산)를 처리할 수 있는가?
- 연산의 품질: 그 연산들이 얼마나 많은 일을 해낼 수 있는가?
레이턴시
이것은 아마도 성능을 구성하는 요소 중 가장 단순한 것이다. 많은 애플리케이션에서 시스템으로부터 응답을 받는 데 걸리는 시간이 짧을수록 좋다. 하지만 평균 시간도 중요한 동시에, 레이턴시 수치의 예측 가능성과 평균적인 경우와 최악의 경우 사이에 얼마나 큰 차이가 있는지도 중요한 고려 사항이다. 잘 활용될 경우, 인메모리 시스템은 매우 뛰어난 레이턴시 특성을 제공할 수 있으며, 시간이 지나도 일관된 레이턴시를 유지할 수 있다.
코어당 초당 연산 수
내가 열거하는 두 번째 요소는 순수 성능과 확장성을 가르는 지점이다. 우리가 관심 있는 것은 주어진 기준 연산 단위에서, 주어진 단위 시간 동안 시스템이 수행할 수 있는 작업량이다. 선형적으로 확장 가능한 시스템은 다수의 노드를 이용해 초당 많은 연산 수를 달성할 수 있지만, 이는 그 시스템이 확장 가능하다는 것을 의미할 뿐 반드시 성능이 뛰어나다는 뜻은 아니다.
코어당 초당 연산 수는 또한 와트당 처리할 수 있는 쿼리 수, 즉 시스템의 에너지 효율과도 보통 밀접하게 연결된다.
연산의 품질
마지막 요소는 개발자들 사이에서 처리량이나 레이턴시만큼 강조되지는 않지만, 특정 종류의 시스템, 특히 인메모리 시스템에서는 매우 중요하다.
초당 100건의 연산을 수행할 수 있지만 연산의 “품질”이 낮은 시스템(예를 들어 Redis로 치면 GET과 SET만 제공하는 경우)은 동일한 레이턴시와 OPS 특성을 가지면서 INCR 연산까지 제공할 수 있는 시스템에 비해 성능이 낮다. 예를 들어 카운터를 증가시켜야 하는 문제라면, 전자의 시스템은 카운터를 하나 증가시키는 데 두 번의 연산이 필요하다(이 맥락에서는 레이스 컨디션을 고려하지 않는다). 반면 INCR을 제공하는 시스템은 단 한 번의 연산으로 이를 처리할 수 있다. 결과적으로 후자는 전자보다 실제로 두 배의 성능을 제공할 수 있는 셈이다.
볼 수 있듯이 연산의 품질은 절대적인 척도가 아니라 해결하려는 문제의 종류에 따라 달라진다. HTML 프래그먼트를 캐시하려는 경우라면 INCR 연산이 무용지물이므로, 위 두 시스템은 동등한 성능을 낸다.
연산의 품질은 특히 인메모리 시스템에서 중요하다. 일반적으로 연산 자체에 드는 시간은 명령을 수신하고 디스패치하며 응답을 생성하는 데 필요한 시간에 비하면 무시할 만한 수준이기 때문이다. 따라서 Redis처럼 풍부한 연산 집합을 갖춘 시스템은 사용자가 단일 연산으로 더 많은 일을 할 수 있게 함으로써, 거의 추가 비용 없이 많은 상황에서 더 나은 성능을 제공할 수 있다. 여기서 “더 많은 일”은 여러 가지를 의미할 수 있다. 예를 들어 Redis의 ZRANK 명령처럼 더 복잡한 질문에 답을 제공하는 것일 수도 있고, HMGET 명령처럼 Hash 값을 구성하는 필드 중 일부에 대해서만 정보를 제공하여 서버와 클라이언트 간의 대역폭 사용량을 줄이는 것과 같이 더 선택적인 응답을 제공하는 것일 수도 있다.
일반적으로 연산의 품질은 시스템이 수행할 수 있는 초당 연산 수에 더 크거나 작은 가치를 부여한다는 점에서만 성능에 영향을 미치는 것이 아니다. 연산 품질은 레이턴시에도 직접적인 영향을 미친다. 더 복잡한 연산을 사용하면 여러 개의 단순한 연산을 조합해 복잡한 계산을 수행할 때 필요한 클라이언트와 서버 간의 왕복 데이터 전송을 피할 수 있기 때문이다.
결론
성능이란 무엇인가에 대한 이 짧은 탐구가, 이러한 관점에서 데이터베이스 시스템의 역량을 평가하는 과정에 내재된 복잡성을 조금이나마 드러냈기를 바란다. 이에 대해 더 할 말은 많지만, 위에서 언급한 성능의 세 가지 구성 요소는 시스템을 평가할 때, 그리고 기존 시스템을 어떻게 발전시켜 성능 특성을 개선할지 이해해야 할 때 가장 흥미롭고 중요한 요소들이라고 생각한다.
이 주제에 대해 피드백을 준 Yiftach Shoolman에게 감사드립니다.
글을 무작위로 읽기
댓글
로그인하고 댓글 남기기