CPU 경합과 시끄러운 이웃

CPU 경합과 시끄러운 이웃

폐허는 모든 남자들이 돌진하는 목적지이며, 각각은 공통점의 자유를 믿는 사회에 대한 자신의 관심을 추구합니다. – 개렛 하딘

과거에 나는 좋은 결정이든 아니든 거의 모든 것을 자체 주최 한 회사에서 일했으며 별도의 토론이 필요합니다.

복싱 데이 아침, 사건이 일어났습니다. 우리는 RabbitMQ 대기열에 큰 메시지를 가졌으며 클러스터는 정족수를 잃었습니다. 메트릭은 옳게 보였지만 노드는 심장 박동이 실패했습니다. 진단을 위해 기계에 연결되어 있습니다 top 실제 이야기를했습니다. %st 일관되게 높았으며 70-80%사이의 교대 값; 우리는 시끄러운 이웃 효과를 경험하고있었습니다.

논쟁이 정말로 무엇인지

Linux VM 내부에서 CFS 스케줄러는 가상 CPU 만 볼 수 있습니다. 그러나 하이퍼 바이저는 해당 VCPU를 유한 한 코어 세트로 저글링하고 있습니다. 모든 사람이 한 번에 달리기를 원할 때 누군가가 기다립니다. VM에서는 대기 시간 표면이 훔치기 (%st).

이웃 워크로드가 발사되면 RabbitMQ VCPU 중 2 개가 준비 대기열에주기를 소비합니다. 이웃 워크로드가 발사되면 RabbitMQ VCPU 중 2 개가 준비 대기열에주기를 소비합니다.

시뮬레이션

CPU 경합 시나리오를 시뮬레이션하고, AWS에서 T3.Small (2 VCPU 파버리) 인스턴스를 돌리고 두 VCPU의 핀 응력 NG를 봅시다.

stress-ng --cpu 2 --timeout 3000s --metrics-brief

버스 테이블 인스턴스는 기준 CPU를 갖도록 설계되었지만 CPU 크레딧을 사용하여 더 높은 파열을 일으킬 수 있습니다. 실행하는 것이 중요합니다 stress-ng

모든 CPU 크레딧을 계속 소비하기 전에 충분합니다.

그런 다음 상당한 페이로드로 응답하는 간단한 웹 앱을 만들고 실행하십시오.

package main

import (
	"fmt"
	"net/http"
	"strings"
)

func handler(w http.ResponseWriter, r *http.Request) {
	response := strings.Repeat("Hello, world! ", 8000) // about 100KB
	fmt.Fprintln(w, response)
}

func main() {
	http.HandleFunc("/", handler)

	fmt.Println("Starting server on :8080...")
	if err := http.ListenAndServe(":8080", nil); err != nil {
		panic(err)
	}
}

부하 및 기록 대기 시간을 생성합니다.

hey -n 10000 -c 200 

인스턴스가 CPU 신용 잔액을 소비 한 후, 하이퍼 바이저는 기준선을 시행하여주기를 거부하고 75.0%ST로 상단에 나타납니다.인스턴스가 CPU 신용 잔액을 소비 한 후, 하이퍼 바이저는 기준선을 시행하여주기를 거부하고 75.0%ST로 상단에 나타납니다.

높은 CPU 훔치기 시간으로 인한 대기 시간높은 CPU 훔치기 시간으로 인한 대기 시간

경쟁 감지

핵심은 런닝 가능한 스레드가 볼 수없는 물리적 코어를 얼마나 오래 기다리는 지 모니터링하는 것입니다. 실제로, VM 레벨 카운터, 하이퍼 바이저 또는 클라우드 원격 측정 및 워크로드 증상의 세 가지 증거 층을 조립 한 다음이를 상관시킵니다.

VM 레벨 카운터

현대적인 Linux AMI에는 두 가지 일류 지표가 있습니다.

  • %st (훔치기) mpstat -P ALL 1 또는 top . 이는 하이퍼 바이저에 의해 비자발적으로 교정 된 1 초 간격의 백분율입니다. 니트로 하드웨어의 5% 이상 또는 파버리 가능한 T- 클래스에서 2% 이상 지속되는 값은 측정 가능한 경합을 나타냅니다.
  • schedstat 대기 시간에 노출 perf sched timehist 또는 perf schedule record. 이것은 지연을 캡처하는 모든 컨텍스트 스위치를 추적합니다. 일반적으로 수석 이하 지연 지연을 보여주는 워크로드는 호스트가 초과 구독 될 때 수십 밀리 초를 표시합니다.

예제 30 초 스냅 샷 :

# per-CPU steal
mpstat -P ALL 1 30 | awk '/^Average:/ && $2 ~ /^[0-9]+$/ { printf "cpu%-2s %.1f%% steal\n", $2, $9}'

# scheduler wait histogram
sudo perf sched record -a -- sleep 30
sudo perf sched timehist --summary --state

지연 분포의 올바른 이동과 일치하는 도둑질 스파이크를 찾으십시오.

하이퍼 바이저 및 클라우드 원격 측정

AWS는 CPU 경합에 직접 매핑되는 두 가지 파생 메트릭을 게시합니다.

  • CPUSurplusCreditBalance (파열 된 인스턴스). 신용 잔액이 0 이하로 떨어지면 하이퍼 바이저는 VCPU를 기준 백분율로 조절하여 즉각적인 도둑질이 발생합니다.
  • CPUCreditUsage평평한 라인이 있습니다 CPUUtilization. 사용 핀이 아직 VM보고 된 이용률이없는 경우, 소진하는 작업이 아닌 스케줄러 천장에 닿는다. 컴퓨팅 최적화 된 가족에서 자세한 모니터링 옵션을 활성화하고 섭취하십시오. %steal 에서 InstanceId CloudWatch 에이전트를 통한 치수.

작업량 증상과 상관 관계

대기 시간에 민감한 서비스는 종종 급격한 변곡을 노출시킵니다. 평균 대기 시간은 꾸준히 유지되는 반면 P95와 P99는 발산됩니다. 인과성을 확인하기 위해 %도둑질 및 준비된 시간으로 백분위 수를 오버레이하십시오. 진정한 경합 동안, 처리량은 일반적으로 각 요청이 여전히 완료되기 때문에 고원을 고원하지만, 단순히 컴퓨팅 슬라이스를 위해 더 오래 기다립니다. 처리량이 무너지면 병목 현상이 다른 곳 (I/O 또는 메모리) 일 수 있습니다.

고급 추적

지난 몇 초 동안 정기적 인 사건의 경우 EBPF 프로브를 첨부하십시오.

sudo timeout 60 /usr/share/bpftrace/tools/runqlen.bt

현재 CPU에 걸친 런 큐 길이의 히스토그램이 현재 서비스 대기 시간 스파이크는 CPU 초과 가입에 대한 결정적인 증거입니다.

경고 임계 값

경험적으로 다음과 같은 경우에 경고하십시오.

사용하십시오 그리고 잘못된 양성을 피하기위한 조건; 사용자가 가시성 대기 시간없이 도둑질은 배치 노드에 허용 될 수 있습니다.

완화

첫 번째 결정은 인스턴스 패밀리입니다. 컴퓨팅 최적화 또는 메모리에서 최적화 된 세대는 버스 테이블 클래스보다 VCPU 당 더 높은 스케줄러 가중치를 보유합니다.

예측 가능한 대기 시간이 요구되는 경우, 초과 구매 가족을 완전히 피하거나 전용 인스턴스를 사용하여 다중 테넌트 변동성을 제거하십시오.

인스턴스가 어떻게 문제가되는지. 스프레드 배치 그룹은 동일한 호스트에 착륙하는 두 명의 무거운 임차인의 확률을 줄입니다. 클러스터 그룹은 동서 대역폭을 개선하지만 CPU 집약적 인 이웃과 상자를 공유 할 위험을 증가시킬 수 있습니다. 대기 시간에 민감한 함대의 경우 스프레드 정책은 일반적으로 더 안전합니다.

이상치에 대한 자동 응답을 구축하십시오. 가벼운 람다는 클라우드 워치를 상승하기 위해 투표 할 수 있습니다 %steal 인스턴스를 재부팅하십시오. 경합은 호스트-국소 인 경향이 있기 때문에, 재활용은 종종 몇 분 안에 사건을 해결합니다.

if metric("CPUStealPercent") > 10 and age(instance) > 5min:
    cordon_from_alb(instance)
    instance.reboot(instance)

관리하는 Kubernetes 내부에서 동일한 아이디어가 적용됩니다. 스케줄러가 보장 된 서비스 품질 클래스를 할당하여 동일한 요청과 한계가있는 중요한 포드를 할당하고, 시끄러운 이웃을 쌓지 않도록 토폴로지 스프레드로 고정하고, CPU 할당량으로 기회 주의적 배치 작업을 제한하여 자체적으로 경합 된 경합을 방지합니다.

정책 제어가 불충분 한 경우 수직 헤드 룸이 나머지 레버입니다. 대기 시간 크리티컬 서비스의 경우 과잉 프로비저 VCPU; 추가 비용은 기회 비용이 누락 된 것보다 낮을 수 있습니다.

편리한 경우 베어 메탈로 가십시오.

결론

CPU 경합은 다중 테넌트 클라우드 컴퓨팅에서 가장 흔하고 가장 눈에 띄는 성능 위험 중 하나입니다. 하이퍼 바이저는 물리적 코어에 대한 액세스를 중재하기 때문에 모든 손님은 현실의 투영 만 본다. 적용 대기 시간 이동 시점까지 근본 원인은 이미 스케줄러의 상류입니다. 요약 :

  • 기기 일류 경합 메트릭 : 훔치기 시간 및 스케줄러 대기 서비스 수준 지표와 함께 대기.
  • 컴퓨팅 최적화 된 가족에서 전용 임차에 이르기까지 SLA와 일치하는 격리 수준을 선택하고 트래픽 패턴이 발전함에 따라 이러한 선택을 다시 방문하십시오.
  • 재활용 인스턴스, 재조정 포드 또는 스케일링 용량에 관계없이 개선을 자동화하여 고객이 열화를 인식 할 수있는 것보다 시정 조치가 더 빨리 완료되도록합니다. 이러한 관행이 플랫폼에 내장되면 CPU 경합은 운영 놀라움이 아닌 또 다른 모니터링 변수가됩니다. 결과는 예측 가능한 대기 시간, 에스컬레이션이 적고, 노이즈 이웃에게 예측할 수 없을 정도로 실패하는 대신로드 하에서 우아하게 저하되는 인프라입니다. 나머지 예측 불가능 성은 비즈니스 결정이됩니다. 더 강력한 격리 비용을 지불하거나 잔여 분산을 용인하는 소프트웨어를 설계합니다.

출처 참조

Post Comment

당신은 놓쳤을 수도 있습니다