관찰 가능성을 다루다 보면 늘 나오는 용어들. 그 중에서도 SLI, SLO, SLA는 늘, 반드시 나옵니다.
SLI - Service Level Indicator
SLI는 단일하면서도 측정 가능한 서비스의 동작을 나타내는 지표입니다. 중요한 것은 SLI의 대상은 명확하게 의미를 갖고 있는 것이어야 합니다.
예시
Availability (%)
Response time (ms)
SLA - Service Level Agreement
SLA는 여러 SLI를 조합한 형태로 보통 표현되는 지표입니다. 특히 계약 관계가 얽혀 있을때는 패널티 Penalty 나 크레딧 Credit 을 부여하는 기준이 되기도 합니다. 때문에 벤더 제품이나 플랫폼을 사용할 때 늘 첨예한 충돌이 일어나는 지점이기도 합니다. 사내에 제공되는 내부 개발 플랫폼이라 하더라도 SLA를 명확하게 정의해 두는 것이 정신건강을 위해 좋습니다.
SLA의 내용은 보통 (1) 보장하고자 하는 것과, 이를 위해 제시되는 (2) 제약 조건으로 구성됩니다.
예시
매일 99% 이상의 요청이 200ms 이내의 응답시간으로 응답되어야 하며, 이 때 응답 Body 크기는 1MB 이하여야 합니다. 이보다 큰 Body를 응답하는 경우 응답시간을 보장할 수 없습니다
가만히 보면 SLA를 구성하는 요소들이 바로 SLI입니다.
예시 SLA에 포함된 SLI들
Availability (% of requests)
Latency (ms)
Content Length (MB)
SLA는 서비스에 대한 SLA가 일반적으로 이야기되지만 컴포넌트 단위의 SLA도 정의할 수 있습니다.
SLO - Service Level Objective
SLO는 내용상으로보면 SLA와 거의 동일합니다. 따라서 구성 요소도 SLA와 마찬가지로 여러 SLI가 됩니다. 다만 SLA가 "꼭 지켜야만 하는 수준"을 나타낸다면 SLO는 "우리가 달성하고자 하는 수준"을 나타냅니다.
효율적인 SQL 구문은 아니지만, 가벼운 SQL 쿼리문에서는 WHERE절에 `IN`을 이용한 Multiple Value에 대한 매칭을 하는 경우가 종종 있습니다. 안타깝게도 Presto 쿼리 신텍스에는 동일한 구문이 존재하지는 않습니다. 다만, 비슷한 방식으로 사용하는 구문이 존재합니다.
-- Presto Query
SELECT id, name, department
FROM data_source.default
WHERE department = ANY (VALUES 'ORG1', 'ORG2')
Presto의 WHERE 구문에서는 ANY라는 키워드를 이용할 수 있습니다. 이후 VALUES 키워드에 이어서 해당 컬럼에서 찾고자 하는 여러 값을 콤마로 구분해서 넣어주면 됩니다. 보다 자세한 구문 설명은 아래 링크에서 참고하세요.
위 설정은 nginx 기본 설정 파일인 nginx.conf의 예입니다. http 서빙을 위해 http 블록이 들어가 있고 로그 형식을 지정하는 log_format과 access_log 지시자가 있습니다.
access_log 는 기본적으로 활성화 되어 있기 때문에 off 를 지정하여 http 요청에 대해 기본적으로 로깅을 하지 않도록 구성했습니다. 패키지 저장소에서 nginx를 설치했기 때문에 /etc/nginx/에 필요한 파일들이 위치해 있고 conf.d 경로 아래의 conf 확장자를 가진 파일들을 include 하고 있습니다.
원칙#2, 로그는 필요한 경우에만 켜자
로깅을 껐으면 이제는 필요한 부분에서 로깅을 켜야 합니다. 보통은 location 블록을 활용해 업스트림 서버를 구분하거나 필요한 프록시 기능을 구현하고 계실겁니다. 다음의 설정은 location 블록 내에서 로깅을 활성화하는 예시입니다.
이렇게 구성하면 /no-log-path 경로로 들어오는 요청들은 앞서 http 블록에서 지정한 access_log off 에 따라 로깅을 하지 않습니다. 대신 중요한 경로인 /admin 으로 들어오는 요청들은 앞서 지정한 main 로그 형식에 따라 지정된 경로에 로그를 남기게 됩니다.
원칙#3, 필요한 경우 샘플링해서 로그를 남기자
이렇게 필요한 경우에만 로그를 남기도록 구성했더라도 요청량이 너무 많은 경우에는 제한적으로 로그를 남길 필요가 있습니다. 엔진엑스의 access_log 지시자는 if 구문을 이용해 조건부로 활성화 할 수 있습니다. 위의 예제를 조금 수정해 보겠습니다.
split_clients 지시자를 이용해 사용자 IP중 5%에 대해서 $is_need_to_logged 라는 변수 값을 1로 지정하도록 했습니다. 1은 true의 의미를 갖는다는 것을 활용해 access_log 지시자의 if 구문에 활용했습니다. 이렇게 구성한 설정의 흐름을 정리하면 다음과 같습니다.
엔진엑스 서버로 http 요청이 들어오면 일단 로그를 비활성화 한다
/admin 경로로 들어오는 요청은 main 형식으로 /var/log/nginx/admin.access.log 파일에 로그를 기록한다
다만, 요청 사용자 IP기준으로 5%의 사용자에 대해서만 로그를 남긴다
로그는 중요합니다. 하지만 로그는 가장 큰 부담중 하나입니다. 적절한 규모로 로그를 관리하는 것이 편안한 취침의 지름길입니다.
엔진엑스의 다양한 활용에 대해 알고싶다면 제가 번역한 <엔진엑스 쿡북>을 읽어보시는 건 어떨까요? :-)