Redis 레이턴시 스파이크와 99번째 백분위수
Stripe 블로그 포스트에서 Redis에 대해 흥미로운 점은 테스트 중에 얻은 레이턴시 그래프를 포함했다는 것입니다. Redis는 디스크에 영속화하기 위해 fork() 시스템 호출을 호출해야 합니다. 일반적으로 물리적 서버와 대부분의 하이퍼바이저에서 fork는 큰 프로세스에서도 빠릅니다. 그러나 Xen은 fork가 느리므로 특정 EC2 인스턴스 유형(및 다른 가상 서버 제공업체도 마찬가지)에서는 디스크에 영속화하기 위해 부모 프로세스가 fork할 때마다 심각한 레이턴시 스파이크가 발생할 수 있습니다. Stripe 그래프는 이 점에서 꽤 분명합니다.

짐작할 수 있듯이, fork 중에 레이턴시 테스트를 수행하면 부모 프로세스가 fork하는 순간에 걸쳐 있는 모든 요청이 최대 1초까지 지연됩니다 (위 그래프를 예로 들면, 프로세스 크기나 EC2 인스턴스가 무엇인지 확실하지 않습니다). 이로 인해 높은 레이턴시를 가진 많은 샘플이 생성되고 99번째 백분위수 결과에 영향을 미칩니다.
이 동작을 개선하기 위해 인스턴스 유형, 구성, 설정 등을 변경하는 것은 좋은 생각이며, 단일 요청이라도 너무 높은 레이턴시를 허용할 수 없는 사용 사례도 있습니다. 그러나 30분마다 1초씩 발생하는 레이턴시 스파이크가 (올바른 재작성 트리거를 사용하는 AOF를 사용한다면 더 자주 발생할 수도 있습니다) 요청 집합에 고르게 분포된 레이턴시 스파이크와 매우 다르다는 것은 분명하지 않은 것 같습니다.
고르게 분포된 스파이크의 경우, 페이지 생성이 출력을 만들기 위해 Redis 서버에 여러 요청을 수행해야 한다면 페이지 뷰가 레이턴시 불이익을 받을 가능성이 매우 높습니다. 이는 잠재적으로 서비스 품질에 큰 영향을 미칩니다. 이 링크를 확인하세요: http://latencytipoftheday.blogspot.it/2014/06/latencytipoftheday-most-page-loads.html. 그러나 30분마다 1초의 레이턴시는 완전히 다른 문제입니다. 우선, 좋은 레이턴시를 가진 백분위수는 *요청 수가 증가함에 따라* 더 좋아집니다. 요청이 많을수록 이 1초의 레이턴시가 샘플에서 과대 대표될 가능성이 낮아지기 때문입니다 (1분에 1개의 요청만 있고 그 요청 중 하나가 높은 레이턴시에 걸리면, 초당 100개의 요청이 있을 때보다 99.99번째 백분위수에 훨씬 더 큰 영향을 미칩니다).
둘째, 대부분의 페이지 뷰는 영향을 받지 않습니다. 1초 지연을 겪는 유일한 사용자는 fork 호출에 걸치는 요청을 만드는 사람들입니다. 다른 모든 요청은 평균 레이턴시보다 훨씬 나쁜 레이턴시를 가진 요청에 부딪힐 확률이 극히 낮습니다. 또한 fork 시간에 걸치는 페이지 뷰는 100개의 요청으로 구성되어 있더라도 1초 이상 지연될 수 없습니다. fork() 호출이 종료되는 즉시 요청들이 완료되기 때문입니다.
결론적으로, 각 개별 요청에 대해 엄격한 레이턴시 요구 사항이 있다면 요청이 때때로 1초 지연될 수 있는 설정은 분명히 큰 문제입니다. 그러나 좋은 서비스 품질을 제공하는 것이 목표라면 레이턴시 스파이크의 분포가 결과에 큰 영향을 미칩니다. Xen에서 fork로 인한 Redis 레이턴시 스파이크는 시간선상의 고립된 지점이므로, 페이지 뷰가 많은 수의 Redis 요청으로 구성되어 있어도 페이지 뷰의 일정 비율에 영향을 줍니다. 이 비율은 레이턴시 스파이크의 총 시간 비율에 비례하며, 이 경우 1800초마다 1초이므로 페이지 뷰의 0.05%만 영향을 받습니다.
레이턴시 특성은 단일 지표로 파악하기 어렵습니다. 전체 백분위수 곡선과 스파이크의 분포가 더 나은 그림을 제공할 수 있습니다. 일반적으로 좋은 경험 법칙은 연구를 시작하는 좋은 방법이며, 일반적으로 평균 레이턴시는 좋지 않은 지표라는 것이 사실입니다. 그러나 경험 법칙을 절대적 진실로 승격시키는 것에도 단점이 있습니다. 많은 복잡한 것들이 복잡하게 남아 있으며, 우리가 지나치게 단순화하려는 의지와 관계없이 면밀한 조사가 필요하기 때문입니다.
동시에, EC2 인스턴스에서의 fork 지연은 오늘날 가장 인기 있는 런타임 환경 중 하나에서 Redis 사용자에게 가장 나쁜 경험 중 하나입니다. 그래서 저는 이제 정기적으로 EC2로 Redis를 테스트하기 시작했습니다. 곧 Redis 공식 문서에 EC2 특화 최적화 페이지를 제공하고, 영속화를 비활성화한 마스터-슬레이브 복제본을 더 안전하게 운영하는 방법을 제공할 것입니다.
지금 EC2 + Redis 마스터를 영속화 없이 사용해야 한다면, 배포하기 가장 간단한 '빠른 해결책'은 Redis 인스턴스의 자동 재시작을 비활성화하고 Sentinel을 장애 조치에 사용하는 것입니다. 그러면 충돌한 마스터가 자동으로 사용 가능 상태로 돌아오지 않고 Sentinel에 의해 장애 조치됩니다. 시스템 관리자는 장애 조치가 성공하고 새 활성 마스터가 있는지 확인한 후 마스터를 수동으로 재시작할 수 있습니다.
편집: EC2, Xen 및 fork 시간에 대한 흥미로운 정보가 포함된 Hacker News 스레드를 꼭 확인하세요: https://news.ycombinator.com/item?id=8532851. 또한 모든 EC2 인스턴스가 동일한 것은 아니며, 특정 유형은 베어메탈 시스템에 필적하는 훌륭한 fork 시간을 제공합니다: https://redislabs.com/blog/testing-fork-time-on-awsxen-infrastructure#.VFJQ-JPF8yF
글을 무작위로 읽기