Pyohwan / english-study

0 stars 0 forks source link

Predictive CPU isolation of containers at Netflix #18

Open Pyohwan opened 4 years ago

Pyohwan commented 4 years ago

https://medium.com/netflix-techblog/predictive-cpu-isolation-of-containers-at-netflix-91f014d856c7

Noisy Neighbors

클라우드에서 실행중인 컨테이너는 공유 공간이 있다. 호스트 인스턴스의 CPU 메모리 계층을 특히 공유한다. 마이크로프로세서는 매우 빠르기 때문에, 컴퓨터 아키텍처 설계를 bits 를 brains 으로 옮기는 latency 를 숨기기 위해 다양한 캐싱을 추가하는 방향으로 발전 했다. 그러나 중요한 점은 이러한 캐시가 CPU 간에 부분적으로 공유되기 때문에, co-hosted 컨테이너간 완벽산 성능 분리가 불가능하다. 특정 컨테이너가 갑자기 RAM 에서 많은 데이터를 가져오면, 필연적으로 더 많은 캐시가 누락된다.

Linux to the rescue?

전통적으로 이런 performance isolation 문제 완화는 OS 스케쥴러 책임이었다. Linux 의 현재 주류 솔루션은 CFS(Completely Fair Scheduler)이다. 이것의 목표는 실행중인 프로세스를 CPU 의 타임 슬라이스에 "fair" 방식으로 할당하는것. 그런데, Netflix 사용사례에서 성능과 거리가 멀더라. Titus 는 Netflix 컨테이너 플랫폼인데, 매달 수천대 컴퓨터에서 수백만개의 컨테이너를 실행한다. critical low-latency 서비스 인코딩이나 머신 러닝을 위한 기계 학습 등에 사용한다. 내부 및 외부 고객에게 좋은 경험을 주려면 애플리케이션 간 performance isolation 가 중요하다.

CPU isolation 책임 일부를 운영체제에서 빼고, combinatorial optimization and machine learning 과 관련된 data driven solution 으로 이동해서, 컨테이너의 예측과 성능을 의미있게 향상 시켰다.

The idea

CFS 는 CPU 하드웨어 사용에 휴리스틱을 적용해서 매우 빈번하게(마이크로초) 작동한다. 대신 개입 빈도(몇초)를 줄였지만, 배치 노이즈를 최소화하기 위해 data-driven 결정으로 프로세스 리소스를 계산하는 결정을 하면 어떨까?

CFS 성능 문제를 푸는 방법은 애플리케이션 소유자가 고정값 or 유용한값으로 수동으로 조절하는것. 하지만, 우리는 실제 사용 정보를 기반으로 배치 기회를 감지하여 글로벌 결정을 자동으로 내릴 수 있다. 예를 들어, 컨테이너 A 가 곧 CPU 를 많이 사용할것으로 예상되면, latency-sensitive 한 B 컨테이너에서 NUMA 소켓을 실행해야할 수도 있다. 이렇게 하면 B 에서 캐시를 많이 쓰려는것을 방지하고, 머신의 L3  캐시 부담을 없앤다.

Optimizing placements through combinatorial optimization

OS task 스케쥴러의 작업은 자원 할당 분제를 해결하는 것: 실행 가능한 X 쓰레드를 가졌고, Y CPU 만 사용 가능하다면, 스레드를 CPU에 할당하여 동시성의 환상(illusion)을 주는 방법은 무엇인가?

환상의 예는, 16 하이퍼쓰레드의 토이 인스턴스를 생각해보자. 이것은 8 물리 하이퍼스레드 코어이며, 2 NUMA 스켓으로 분할된다.

컨테이너 A 에서 4개 스레드를 실행하고, 컨테이너 B 에서 2개 쓰레드를 실행하면, "bad" 와 "good" 배치를 알 수 있다.

첫번째 배치(first placement)는 전체 소켓을 비워두기 때문에 좋지 않다. 두번째 배치(second placement)는 CPU에 자체 L1/L2 캐시가 제공되고, 2개 L3 캐시를 더 잘 활용한다.

자원 할당 문제는airline scheduling or logistics problems 에 사용되는 combinatorial optimization 메카니즘으로 효율적으로 해결 가능하다.

Mixed Integer Program(MIP) 으로 공식화한다. d 개의 스레드를 소유한 인스턴스에서 특정수의 CPU를 요청하는 각 K 컨테이너 세트가 주어지면, 목표는 각 컨테이너의 CPU 수를 얻는 (d,K) 크기와 2진 행렬 M를 찾는것이다. 손실 함수 및 제약 조건에는 다음과 같은 다양한 용어들이 있다.

시스템의 low-latency 와 low-compute 요구사항이 주어지면 (CPU 사이클을 파악하기 위해, 컨테이너가 얼마나 사용하는지 자주 파악하고 싶지 않다), 이 작업을 수행할수 있겠냐?

Implementation

우리는 Linux cgroup을 통해 전략 구현하기로 했다. 이 방식은 user-space 프로세스에 CFS가 작동하는 "fence" 를 정의한다.

이 user-space 프로세스는 titus-isolate 로 작동한다. 각 인스턴스에서 트리거 하는 세가지 이벤트를 정의한다

최근에 placement decision 안했다면, 주기적으로 rebalance 큐에 넣음

배치 이벤트가 트리거 되면, titus-isolate 는 원격으로 스레드 최적화 쿼리를 한다. (Titus 서비스로 실행함으로 자체적으로 격리됨)

10분 안에 각 컨테이너의 P95 CPU 사용량을 예측하는 로컬 GBRT 모델을 쿼리 한다. (전체 Titus 플랫폼에서 수집한 후, 주에 2시간씩 재교육). 이 모델에는 컨텍스트 기능 (컨테이너와 관련된 메타: 실행한 사람, image, 메모리, 네트워크, 앱 이름 등) 뿐만 아니라, 커널 CPU accounting 컨트롤러를 통해 이전 1시간의 CPU 사용률을 포함한다.

예측은 MIP를 통해 즉시 해결. cvxpy 를 사용함.

64개 논리 CPU(r4.16xlarge)를 가졌다면 이렇다. (컬러는 CPU 사용량을 나타냄)

Results

배치잡의 전체 런타임을 multiple 퍼센트를 줄여서 런타임 잡의 편차를 줄였다. isolation 개선 없는 real-world 배치 잡이다.

long-running 의 문제가 사라졌다. noisy-neighbors 가 사라졌다.

Netflix 스트리밍 서비스를 제공하는 Titus 미들웨어 서비스는 필요한 P99 latency SLA 를 제공하기 위해 13% 이상의 용량 감소(1000 컨테이너 이상 감소) 한것을 보았다. 커널에서 캐시 무효화 로직을 소비하는 시간이 훨씬 적어서 머신의 CPU 사용량이 급격히 감소했다.

Next Steps

CPU oversubscription 을 지원하도록 시스템을 확장하려 한다. 앱에 필요한 CPU 수를 올바르게 조정하는 법을 알아야 하고, 컨테이너의 lifetime 동안 CPU 의 수가 다양하게 변한다. 컨테이너의 향후 CPU 사용량을 이미 예측했으므로, 사용하지 않다면 자동으로 감지하고 회수하려 한다. 예를 들어, 사용자의 민감도 임계 값을 감지할 수 있다면, 특정 컨테이너를 낮은 CPU 사용을 cgroup 에 할당하고, 전반적인 격리와 머신 활용도를 향상 시킬수 있다.

또한 커널 PMC 이벤트로 캐시 noise 를 최소화 하고 싶다. 가능한 방법 중에는 Amazon 에 최근 도입된 인텔 기반 베어메탈 인스턴스이다. (컨테이너B 와 동일한 코어에 스레드 하나를 배치하고 동일한 소켓에서 C 가 실행되고 있음을 안다면, 1분이 지나면 컨테이너 A 의 성능은 어떨까?)

Conclusion