관찰 가능성은 엔지니어였던 루돌프 E. 칼만Rudolf E. Kalman 이 1960년에 처음 사용한 이래, 많은 커뮤니티에서 다양한 의미로 사용되면서 널리 퍼지기 시작했습니다.
칼만은 1960년에 쓴 논문에서 수학적 제어 시스템을 설명하기 위해 관찰 가능성이라는 특징을 사용했습니다. 이 논문에서 관찰 가능성은 제어 이론에서 외부 출력으로부터 시스템 내부의 상태를 얼마나 잘 추론할 수 있는지를 측정하는 것으로 정의되었습니다. 관찰 가능성의 정의를 살펴보다 보면 센서, 선형대수학 방정식, 정형 기법과 함께 관찰 가능성과 제어 가능성을 수학적 쌍대 개념을 학습하는 자신을 발견할지도 모릅니다.
이렇듯 관찰 가능성에 대한 기존 정의는 기계공학 엔지니어나 특정한 상태로 동작이 멈추는 것을 염두에 두는 물리적 시스템 관리자의 영역이었습니다. 칼만의 관찰 가능성에 대한 정의는 현대적인 소프트웨어 시스템에도 적용할 수 있습니다. 그런데 물리적 시스템 관리자의 영역이였던 관찰 가능성을 현대적인 소프트웨어 시스템에 꼭 적용해야 할까요? 왜 이러한 전환이 지금 필요한 것인지에 대해 이야기 해보려고 합니다.
짧게 요약하자면, 메트릭을 사용하여 소프트웨어를 모니터링하는 기존의 접근 방법은 상당히 많이 부족합니다. 이러한 접근 방법은 상당히 사후 대응적reactive이기 때문입니다.
과거에는 소프트웨어 산업에서 꽤 잘 동작했던 방식이지만 현대적인 시스템은 더 나은 방법론을 요구하고 있습니다. 지난 2~30년 동안, 하드웨어와 운영자 사이의 영역은 ‘모니터링’이라 불리는 일련의 도구와 규약에 의해 통제되어 왔습니다. 실무자들은 대체로 이러한 도구와 규약을 물려 받았고, 물리적인 하드웨어와 소프트웨어 코드 사이의 간극을 이해하기 위한 최선의 방식으로 받아들였습니다. 또한 이 방식이 갖고 있는 근본적인 제약사항들로 인해 트러블슈팅으로 밤잠을 설치는 경우가 많다는 사실을 알면서도 특별히 바꾸려는 노력도 하지 않았습니다. 그럼에도 불구하고 실무자 들은 여전히 이 방식이 그들이 알고 있는 최고의 방법이라 여기며 무한한 신뢰와 애정을 보내고 있습니다.
하지만 모니터링만으로는 소프트웨어 개발자들의 시스템을 완전히 살펴볼 수 없습니다. 개발자들은 시스템을 매의 눈으로 바라봅니다. 시스템을 확장하기 위해 무수한 가능성에 대해 예측하려고 노력하지만 허사입니다. 이후 개발자들은 알려진 실패 상황을 살펴보는 작업, 즉 모니터링을 수행합니다. 성능 임계치를 설정하고 임의로 ‘좋음’ 혹은 ‘나쁨’으로 구분합니다. 그들을 대신할 조그만 로봇 병사를 배포해 임계치를 계속 체크합니다. 그렇게 발견된 것들을 대시보드에 보여 줍니다. 그런 다음 개발자들은 그 로봇들을 중심으로 팀을 만들고 모니터링 로테이션을 구성하 고 필요할 때 에스컬레이션할 수 있도록 준비합니다. 시간이 지나면 임계치에 다가가 불필요한 수치를 없애고 임계치를 조정하고 그들이 키운 쓸데없는 신호들에 대해 호들갑을 떱니다.
수십 년 동안 개발자들과 운영자들은 이런 방식으로 모니터링을 수행했습니다. 모니터링은 사실상 표준이 되어 왔기 때문에 사람들은 모니터링이 시스템을 이해하는 여러가지 방법 중 하나가 아니라, 유일한 방법이라 생각해 왔습니다. 모니터링이 기본이 되다 보니 거의 눈에 잘 띄지 않았죠. 업계에서는 모니터링해야 하는지보다 단지 어떻게 할 것인지에만 관심이 쏠려 있었습니다.
모니터링 관행은 시스템에 대한 많은 암묵적 가정을 기반으로 수행되었습니다(자세한 내용은 책 『데브옵스 엔지니어를 위한 실전 관찰 가능성 엔지니어링』 에서 설명합니다). 하지만 시스템이 더 추상적이고 복잡해지면서 기반이 되는 컴포넌트는 점점 덜 중요해지는 방향으로 계속 진화했고 모니터링이 시스템을 이해하는 유일한 방법이 라는 가정은 깨지기 시작했습니다. 개발자와 운영자들이 소프트웨어 시스템을 배포하기 위해 SaaS와 컨테이너 오케스트레이션 플랫폼, 분산 시스템과 같은 현대적인 접근 방법들을 채택하기 시작함에 따라 가정이 깨지고 있다는 것은 점점 분명해졌습니다.
이에 따라 점점 많은 사람들이 내재된 한계에 부딪히며, 모니터링의 접근 방법론은 새로운 현대 세계에서는 더 이상 동작하기 어렵다는 것을 깨달았습니다.
기존의 모니터링 방법은 시스템을 이해하는 데 너무나도 비효율적이기 때문이죠. 메트릭과 모니터링의 가정만으로는 시스템을 이해하기 어려웠습니다. 메트릭과 모니터링이 실패할 수밖에 없었던 이유를 이해하기 위해서는 먼저 그 역사와 의도된 문맥을 조사해 볼 필요가 있습니다.
1988년, RFC 1157에 정의된 SNMPSimple Network Management Protocol를 통해 모니터링의 기본적인 기반이 탄생했습니다. 이것이 바로 메트릭입니다.
메트릭은 단일 숫자로 표현되며 그룹화하거나 숫자를 검색하기 위해 태그를 추가할 수 있습니다. 본질적으로 메트릭은 일회성이었으며 투입 비용이 저렴했습니다. 메트릭은 스토리지 소요량을 예측할 수 있었고, 규칙적인 시계열 버킷을 통해 쉽게 집계할 수 있었습니다. 따라서 메트릭은 한, 두 세대 동안 원격지 엔드포인트를 통해 자동으로 모니터링 시스템으로 수집된 원격 측정 데이터를 위한 기본 단위가 되었습니다. 많고 복잡한 부가 요소들 또한 메트릭을 기반으로 만들어졌습니다.
대표적으로 시계열 데이터베이스TSDB 와 통계 분석, 그래프 라이브러리와 매혹적인 대시보드, 온콜 로테이션 체계, 운영팀, 에스컬레이션 정책, 그리고 조그만 로봇 군단이 알려주는 정보를 이해하고 대응하기 위한 많은 방법 등이 있습니다.
하지만 메트릭과 모니터링 도구로 이해할 수 있는 시스템의 복잡도에는 상한선이 존재했습니다. 이 경계를 넘어가는 순간 모든 상황은 급변했습니다. 지난달에 아주 잘 동작하던 것들이 이번 달에는 제대로 동작하지 않았습니다. 다시 strace, tcpdump와 같은 저수준 명령어로 돌아가야만 했고 시스템이 어떻게 동작하고 있는지를 매일 살펴보기 위해 수많은 print 구문을 이용해야만 했습니다. 언제 변곡점에 도달하게 될지 정확하게 예측하기는 어렵습니다. 결국 시스템이 가질 수 있는 상태의 수는 이전에 발생한 장애를 기반으로 한 패턴 매칭 방식의 추적 범위를 벗어날 것입니다.
우리는 이제 너무나 새롭고 참신한 상태 값들에 대해 계속해서 이해하기 위해 노력해야만 합니다. 곧 여러분의 팀은 수많은 장애 모드를 보여주기 위해 어떤 대시보드를 만들어야 하는지도 생각하기 어려워지겠죠. 모니터링과 메트릭 기반의 도구들은 아키텍처와 조직 구조에 대한 특정한 가정과 실제 상황에서 복잡도에 대한 한계를 기반으로 구축되었습니다.
이러한 가정은 보통 내재된 한계를 넘어설 때까지는 눈에 띄지 않지만, 그 시점을 넘어선 순간 갑자기 튀어나와 무슨 일이 일어나고 있는 지 이해하기 어렵게 만들 수 있습니다. 대표적인 가정은 다음과 같습니다.
● 여러분의 애플리케이션은 모놀리식 방식입니다.
● 상태를 저장하는 데이터 저장소, 즉 데이터베이스는 하나만 있습니다.
● 상주 메모리resident memory, CPU 평균 부하CPU load average와 같은 많은 저수준 시스템 메트릭을 사용할 수 있습니다.
● 애플리케이션은 여러분의 통제하에 있는 컨테이너, 가상 머신(VM), 베어메탈 서버에서 동작합니다.
● 시스템 메트릭과 계측된 메트릭은 코드를 디버깅하기 위한 주요 정보의 원천입니다.
● 어느 정도 정적이면서 오랫동안 실행되는 노드nodes, 컨테이너, 호스트를 모니터링합니다.
● 엔지니어는 문제가 발생한 이후에만 시스템 분석을 수행합니다.
● 운영자 필요에 의해 제공될 대시보드와 원격 측정 정보가 존재합니다.
● 모니터링은 ‘블랙박스blackbox’ 애플리케이션을 로컬 애플리케이션과 매우 비슷한 방식으로 검사합니다.
● 모니터링의 주안점은 가동 시간uptime과 실패 예방입니다.
● 상관관계 검사는 매우 제한적이거나 매우 적은 수의 디멘션 사이에서만 이루어집니다.
현대적 시스템의 현실을 생각해보면, 기존의 모니터링은 여러 가지 면에서 부족합니다. 현대적 시스템의 실제 상황은 다음과 같습니다.
● 애플리케이션은 많은 서비스로 구성됩니다.
● 폴리글랏 퍼시스턴스polyglot persistence방식을 사용합니다.
● 인프라스트럭처는 아주 역동적이며 용량이 탄력적으로 늘어나거나 줄어듭니다.
● 광범위하면서도 느슨하게 연결된 서비스들이 관리되고 있지만, 대부분은 통제 범위 밖에 있습니다.
● 엔지니어는 아주 작은 이슈라도 가능한 한 빨리 발견하여 사용자에게 영향을 주지 않도록 프로덕션 환경에 배포된 코드가 만드는 변화를 지속해서 관찰합니다.
● 자동 계측automatic instrumentation만으로는 복잡한 시스템 내에서 발생하는 일을 완전히 이해하기에 충분하지 않습니다.
● 소프트웨어 엔지니어들은 프로덕션 환경에서 운영 중인 자신의 코드를 갖고 있으며, 미리 코드를 계측하고 배포 시 발생할 수 있는 성능의 변화를 면밀히 살펴봅니다.
● 신뢰성reliability의 초점은 오류 예산error budget, 서비스 품질quality of service, 사용자 경험user experience과 같은 요소를 활용하여 사용자에게 영향을 줄 수 있는 실패를 줄이도록 탄력성resiliency을 구축하는 동시에 일정하 면서도 지속적인 성능 저하를 허용하는 데 있습니다.
● 상관관계 분석은 수많은 디멘션에 대해 일어납니다.
위의 내용 중 마지막이 중요합니다.
이는 사람이 합리적으로 생각할 수 있을 거라 예상되는 연관 지식의 한계와 현대적인 시스템 아키텍처의 현실 사이의 절망을 설명합니다. 성능 문제 이면에 숨겨진 근원적인 상관관계를 찾아내기 위해서는 사람의 두뇌나 어떤 스키마로도 담을 수 많은 디멘션이 관련될 수밖에 없습니다. 관찰 가능성이 없었다면 복잡한 시스템 아키텍처에 묻혀 숨겨진 이슈가 되었을 높은 디멘셔널 리티high-dimensionality 데이터와 높은 카디널리티high-cardinality 데이터의 비교는 관찰 가능성이 찾을 수 있게 해준 중요한 컴포넌트가 되었습니다.
시스템 복잡도가 한계를 넘어서면 시스템 모델을 여러분의 머릿속에 집어넣는 것이 불가능해집니다. 다양한 컴포넌트 동작을 통해 추론하려는 동안 여러분 머릿속에 만들어 둔 모델은 이미 구식이 되어 있을지도 모릅니다. 엔지니어로서 수행하는 디버깅은 직관에 의존하는 경우가 많습니다.
문제의 원인을 파악하기 위해 직감을 따르거나 조사를 도와줄 수 있는 오래전의 장애 상황들을 떠올리기도 할 것입니다. 그렇지만 과거에 유용했던 많은 기술들은 더 이상 적용되기 어려운 경우가 많습니다. 직관적인 접근 방법은 문제가 이전에 겪었던 문제의 변형이거나 연장선에 있는 것과 같이 예측 가능한 때에만 적용할 수 있습니다. 마찬가지로 모니터링을 이용한 메트릭 기반의 접근 방법은 과거의 실패 사례에 의존합니다.
모니터링은 이전에 발생했던 시스템 예외 상황을 바탕으로 만들어진 임계치를 기준으로, 이를 넘 거나 밑도는 상황을 감지하도록 해줍니다. 하지만 그런 형태의 비정상적인 예외 상황이 발생할 수 있다는 사실조차 모른다면 무슨 일이 일어날까요? 역사적으로 소프트웨어 엔지니어가 직면하는 대부분의 문제는 예측 가능한 장애 모드의 변형 입니다. 아마도 소프트웨어가 이전과 동일한 방식으로 고장 날 것이라고 단언할 수는 없겠지 만, 어떤 컴포넌트에서 무슨 상황이 일어날지 추론해 두었다면, 적어도 새로운 버그나 고장 상황을 찾아내는 데 있어서 어려움을 겪지는 않을 것입니다.
대부분의 소프트웨어 개발자는 복잡한 형태의 문제를 다루는 경우가 많지 않기 때문에, 완전히 예측 불가능하면서도 논리적으로 설명하기 어려운 상황에 직면하지 않을 것입니다( 오늘날 개발자들이 겪는 대부분의 복잡성은 모놀리식monolithic 앱에 포함되어 있습니다).
하지만, 현대적인 분산 시스템 아키텍처는 그 누구도 예측할 수 없고 이전에 경험해 보지도 못했던 새로운 방식으로 실패하는 것으로 악명 높습니다. 이러한 실패는 분산 컴퓨팅 환경에 익숙하지 못한 프로그래머들이 자주 하는 잘못된 가정에 대한 일련의 주장이 생겼을 정도로 빈번하게 일어납니다. 또한, 현대의 분산 시스템은 개발자들이 추상화된 인프라스트럭처 플랫폼처럼 접근 할 수 있도록 만들어졌습니다. 이러한 플랫폼을 사용하는 애플리케이션 개발자들은 플랫폼이 갖고 있는 고유의 축소 불가능한 복잡성을 다뤄야만 합니다.
이전에는 겉으로 드러나지 않았던, 물리 서버의 숨겨진 메모리에서 상호 작용하고 있던 애플리케이션 코드의 서브루틴 복잡성은 호스트 간의 서비스 요청을 통해 드러나게 됩니다. 이렇게 드러난 복잡성은 단일 기능을 수행하는 경우라도 여러 서비스를 넘나들며 예측하기 힘든 여러 네트워크 구간을 통과하게 합니다.
현대적인 아키텍처가 모놀리식 구조를 마이크로서비스 방식으로 쪼개기 시작한 이래, 소프트웨어 엔지니어는 더이상 일반적으로 쓰이던 디버거를 통해 코드를 살펴보는 것이 어려워졌습니다. 그뿐만 아니라 그들이 사용하던 도구 역시 이러한 큰 변화에 제대로 대처하지 못했습니다.
요약하자면, 모놀리식은 사라졌습니다.
이제 모든 요청은 네트워크 구간을 여러 번 거쳐야만 하고 모든 소프트웨어 개발자는 일상의 작업 수행을 위해 시스템과 운영에 대해 더 많은 지식을 갖추어야 할 필요가 생겼습니다.
위 콘텐츠는 『데브옵스 엔지니어를 위한 실전 관찰 가능성 엔지니어링』에서 내용을 발췌하여 작성하였습니다.
관찰 가능성이라는 용어가 정의된 지 수십년이 지났지만, 관찰 가능성을 소프트웨어 시스템에 적용하는 것은 여전히 여러 가지 고려 사항과 특성이 수반되는 새로운 적응 과정 입니다. 상대적으로 단순했던 초기의 시스템에 비해, 현대의 시스템은 고장을 예측, 감지, 해결 하기 어렵다는 복잡성을 갖고 있습니다. 엔지니어링팀은 복잡성을 낮추기 위해, 어떻게 고장이 발생하는지 먼저 예측하지 않고도 이슈에 대해 디버깅할 수 있도록 유연한 방식으로 원격 측정 정보를 지속적으로 수집할 수 있어야 합니다.
엔지니어가 원격 측정 데이터를 유연한 방법을 통해 자유자재로 다루게 돕고, 예상치 못한 방식으로 발생한 모든 이슈의 근본적인 원인을 찾을 수 있도록 돕는 관찰 가능성을 도입해야 하는 이유죠.
관찰 가능성의 개념과 중요성부터 관찰 가능성과 모니터링의 차이점 분석을 통해 각 접근 방식의 장단점을 알아보고 관찰 가능성 시스템 구현과 데이터 기반 문제 해결 방법까지. 관찰 가능성의 모든 것은 책 『데브옵스 엔지니어를 위한 실전 관찰 가능성 엔지니어링』을 통해 더욱 자세히 확인하실 수 있습니다.
최신 콘텐츠