웹 성능 측정 도구 carrotw 소개
2016년 7월 20일 초안 작성
서론
우리 회사는 10여년 전 부터 carrot이라는 성능 측정 도구를 만들어 부하 테스트를 진행해왔다. carrot은 지정한 만큼의 thread를 생성해 해당 thread가 쉬지 않고 동기(synchronous)로 socket 통신을 하면서 타겟 서버의 성능을 측정할 수 있게 하는 성능 측정 도구다.
본론
가령 응답속도가 20ms인 서버가 있다면 thread 2 일때 초 당 100회 요청이 가능하다.
- 1s = 1000ms = 20ms x 50회
- 50회 x 2 thread = 100회
Threads
thread 수 는 자유롭게 조정할 수 있으며 서버가 감당하기 힘든 상황까지 높이게 되면 응답속도가 지연될 것이다. 즉, thread 5 일때까지 동일한 20ms 응답을 보인다면 이 서버의 성능 저하 없는 최대 성능은 250 TPS로 볼 수 있다. 그러나 thread 6 부터 응답 속도가 30ms 정도로 감소한다면 이 서버는 한계 상황으로 치닫고 있다고 볼 수 있으며, 서비스에서 100ms 까지 응답 대기가 가능하다고 정했다면 그 상황까지 thread를 높인 다음 TPS를 산출해 최대 유효 성능을 산정할 수 있다.
설정
carrot은 리눅스 콘솔에서 약간의 XML 설정으로 실행하는 형태인데 매 번 설정을 수정하고 콘솔에서 실행하는 것이 생각외로 번거롭다. 따라서 이를 좀 더 편리하게 사용하기 위해 웹 서비스 형태로 구현한 carrotw를 만들었다. 웹에서는 번거로운 XML 설정이 필요 없으며 검색 서비스를 위해 최신 모바일 통검 쿼리셋도 미리 마련해두었다. 즉, query 파라미터 명을 정하기만 하면 해당 파라미터(e.g. q
)에 최신 모바일 통검 쿼리가 매 요청시 순차적으로 들어간다. 모바일 통검 쿼리는 ad-hoc 시스템으로 추출한 데이타에서 ‘가나다’ 순 분류를 uniq/shuffling 했다. 또한 웹 기반의 장점을 최대한 활용해 단순 수치로만 표현되던 값을 실시간 그래프로 보여줄 수 있게 했다.
carrot은 초 단위의 실시간 TPS를 확인할 수 있다는 점에서 기존 ab, httperf 보다 더 직관적으로 사용할 수 있으며 다이나믹 파라미터를 지원해 검색 서비스에서 동적 쿼리 테스트시에 매우 유용하다.
서비스
아쉽게도 이 서비스는 성능 측정 도구인 만큼 자칫 DoS 툴로 악용될 수 있고 따라서 사내 전용으로만 사용 가능하다. 사내에서 접속 가능한 private 도메인이 설정되어 있으며 접속 주소는 사내 위키에서 ‘carrotw’를 검색하여 찾을 수 있다.
구성
서비스 구성은 매우 심플하다.
URL, thread 수, query 파라미터, 동작 시간(duration time), timeout(기본 1초)등으로 구성되며, Permalink 생성을 누를 경우 해당 설정 값으로 고유한 URL이 생성된다. 따라서 이 URL을 공유하면 즉시 성능 테스트가 가능한 환경으로 구성할 수 있다.
QPS
: Queries Per Second, 원래 TPS(Transactions)가 맞으나 검색 서비스에서 사용을 위해 쿼리로 명칭을 변경한다. 즉, 초당 최대 쿼리 요청 수 이다.Response Time
: 응답 시간. 단위는 ms 이다.Fail Count
: 요청 실패 횟수. 주로 timeout을 초과하거나 socket 커넥션 오류가 발생하거나 또는 너무 많은 요청이 들어가 thread에 문제가 발생한 경우에 올라간다. 콘솔에는 stderr에 오류를 표시하나 웹에서는 stdout만 표현하므로 오류 메시지는 보여주지 않고 카운트만 올라간다. 이는 다음 버전에 해결 예정이다.
timeout에는 두 가지가 있는데 Connection-Timeout은 socket 통신이 연결되기 전까지, Read-Write Timeout은 연결 이후 TTLB(Time To Last Byte)까지의 시간이다. 보통은 Connection이 훨씬 더 짧아야 하나 TTLB가 긴 것도 서버의 응답(Response)이 지나치게 느리다는 것이므로 좋지 않다.
개선 사항
기존 검색 서비스에서 사용하던 carrot은 2002년에 빌드한 1.1 버전이고 더 이상 관리 되지 않고 있었다. carrotw를 만들기 직전 파악한 결과 carrot은 기반기술셀에 의해 작년(2014년)까지도 꾸준히 버전업 되고 있었고 따라서 carrotw에는 최신 버전을 빌드해서 적용하기로 했다.
아울러 carrotw에 들어가는 carrot은 기존 최신 버전에 아래와 같이 개선 및 버그 패치를 기반기술셀의 지원으로 추가 진행했다.
- OpenSSL 업데이트 및 https 지원 추가: https 서비스도 문제 없이 테스트 가능
- CARROTW_MODE 추가: carrotw 서비스에는 이 옵션을 부여한 빌드 버전이 올라가며 ANSI 코드를 사용하지 않고 표시 문구가 다르다. 이외에도 웹 서비스를 위한 사소한 처리 추가
- WebSocketd에서 구동될때 segfault 발생하던 버그 패치
- transfer-encoding chunked 모드를 제대로 처리못하던 버그 패치
결론
이 서비스는 단순히 carrot을 웹 서비스로 구현한 것 외에도 추가 패치를 진행했고 웹에서 실시간 통신을 위한 WebSocketd, 실시간 그래프를 그리기 위해 Smoothie Charts를 활용했다. 아울러 서비스는 PHP와 Bootstrap으로 구현했으며 모든 소스는 사내 깃헙에 공개했다.
또한 carrotw에서 사용하는 carrot은 기반기술셀 깃헙 레파지토리를 fork하여 항상 upstream의 최신 커밋을 반영하며 경우에 따라 별도 패치를 upstream에 PR 한다. 이외에도 사내 위키에 빌드, 버그 패치와 관련한 좀 더 기술적인 문서가 있으므로 참고할 수 있다.
carrot은 오래된 도구이고 전통적인 thread 방식의 blocking I/O로 구현되어 있어 엄청난 고부하 테스트는 힘들다. 추후에는 wrk와 같은 이벤트 기반의 nonblocking I/O 성능 테스트 도구를 개발하여 어마어마한 볼륨의 테스트도 가능하도록 개선하길 바란다.