{"id":"IL-0247","org":"Pinterest","date":"2025-07-16","docs":[],"title":{"en":"One in a million search requests took 100 times longer on Pinterest's Manas leaf nodes after moving to Kubernetes","ko":"쿠버네티스로 옮긴 검색 시스템 Manas 에서 요청 백만 건에 한 건이 평소보다 100배 느려졌다"},"domain":["kubernetes","aws"],"impact":{"scope":"Manas test search cluster on PinCompute during the migration to Kubernetes; the migration was paused","users":"unknown","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"CPU shielding does not fully isolate a process from its neighbours. Showing early that the node image was not the cause narrowed the search and avoided dead ends. Simple blackbox debugging, breaking things until the system stops working, works as a way of bisecting the problem.","ko":"자원 격리는 까다롭다. CPU 격리를 해도 프로세스가 이웃 프로세스의 영향에서 완전히 벗어나지는 않는다. 문제 범위를 좁히는 일이 중요했다. PinCompute AMI 가 원인이 아님을 확인하자 범위가 좁아졌고, 소득 없는 조사를 많이 피할 수 있었다. 시스템이 제대로 동작하지 않게 될 때까지 하나씩 꺼 보는 단순한 블랙박스 디버깅도 효과가 있었다. 이것도 문제를 반씩 나눠 범위를 좁히는 방법의 하나다."},"related":[],"sources":[{"url":"https://medium.com/pinterest-engineering/debugging-the-one-in-a-million-failure-migrating-pinterests-search-infrastructure-to-kubernetes-bef9af9dabf4","kind":"blog","archived":"https://web.archive.org/web/20251208164101/https://medium.com/pinterest-engineering/debugging-the-one-in-a-million-failure-migrating-pinterests-search-infrastructure-to-kubernetes-bef9af9dabf4"}],"summary":{"en":"Manas is Pinterest's in-house search system; it serves dozens of search indices from more than 100 clusters on thousands of hosts. In 2024 Pinterest built a new setup for Manas on PinCompute, its in-house Kubernetes platform, and in early 2025 began performance testing it. A root node fans each request out to leaf nodes, and each leaf serves one shard of an index with memory-mapped lookups during retrieval and ranking. On the test cluster a small but persistent share of requests timed out because leaf max latency spiked as high as 5s, and Pinterest paused the migration to find the cause.\n\nChanging the hardware, node image, cgroup limits and container setup and isolating the CPUs did not help. Suspending processes one by one showed that cAdvisor caused the spikes, and perf showed it spending its time in the kernel's smaps feature. The cause was the metric container_referenced_bytes, which cAdvisor enables by default and whose documentation marks it as intrusive to collect. It estimates working set size by scanning the whole page table, counting accessed bits and then clearing every one of them, and PinCompute ran cAdvisor every 30 seconds. Manas leaf indices can be hundreds of gigabytes, and a host with 100GB of used memory can have 25 million page table entries; smaps and clear_refs each take locks while scanning all of the kernel's page structures, and clear_refs also flushes the working set from the TLB; Pinterest concluded that this memory contention was the likely cause of the stalls in the memory-intensive leaf process. Pinterest turned off cAdvisor's working set estimation on all PinCompute nodes with a one-line change and opened an issue in the cAdvisor repository. cAdvisor itself could not be removed because PinCompute needs its container metrics, including for workload autoscaling.","ko":"Pinterest 는 자체 검색 시스템 Manas 를 2017년부터 자체 클러스터 관리 시스템으로 운영했다. 이 관리 시스템이 복잡해지자 2024년 내내 자체 쿠버네티스 플랫폼 PinCompute 위에 새 시스템을 만들었다. 2025년 초 시험 클러스터로 성능 시험을 하자 요청 일부가 꾸준히 타임아웃을 냈다. 운영 장애는 아니었지만, 그대로 두면 Pinterest 의 모든 추천 서비스에 문제가 남고 최악에는 회사 전체의 장애로 번질 수 있다고 보고 이전을 멈췄다. Manas 는 root 노드가 요청을 shard 마다 leaf 노드로 나눠 보내는 구조이고, leaf 노드는 메모리에 매핑한 색인에서 후보를 찾고 순위를 매긴다. 정상이면 60ms 아래여야 할 leaf 노드의 최대 지연이 5s 까지 올랐고, 노드 하나에서는 몇 분마다 지연이 튀었다.\n\n팀은 더 큰 인스턴스, 운영과 같은 AMI, cgroups 제한 제거, 컨테이너 밖 실행, CPU 격리를 차례로 시험했지만 아무 효과가 없었다. 결국 sudo kill -STOP 으로 로그 수집, 통계 파이프라인, 보안, kubelet, Pinterest 전용 데몬을 하나씩 멈췄고, cAdvisor 를 멈추자 지연 급등이 곧바로 사라졌다. perf 로 보니 cAdvisor 가 리눅스 커널의 smaps 를 부르며 메모리 정보를 읽는 데 지나치게 많은 시간을 쓰고 있었다. cAdvisor 에 기본으로 켜진 container_referenced_bytes 지표는 페이지 테이블의 accessed bit 로 프로세스의 작업 집합 크기를 추정한다. 이를 위해 측정할 때마다 페이지 테이블 전체를 훑어 accessed bit 를 세고 모두 지운다. PinCompute 는 cAdvisor 를 30초마다 돌렸다. Manas leaf 노드는 수백 GB 색인 전체를 메모리에 매핑하므로, 메모리를 100GB 쓰는 호스트라면 페이지 테이블 항목이 2,500만 개에 이른다. smaps 와 clear_refs 는 커널의 페이지 구조 전체를 훑는 동안 잠금을 잡고, clear_refs 는 그 과정에서 작업 집합의 모든 페이지를 TLB 에서 내보낸다. 팀은 이 메모리 경합이 요청 약 백만 건에 한 건이 100배 느려진 원인일 가능성이 크다고 보고 조사를 마쳤다. 모든 PinCompute 노드에서 cAdvisor 의 작업 집합 크기 추정을 껐고, 조사에서 배운 것을 cAdvisor 저장소에 GitHub 이슈로 올렸다."},"trigger":null,"severity":"unknown","symptoms":["high-latency","intermittent-timeouts"],"timeline":{"detected_after":null,"resolved_after":null},"date_kind":"published","detection":{"en":"Performance testing with traffic sent to a test cluster showed a small but persistent percentage of requests timing out.","ko":"이전을 검증하려고 시험 클러스터에 트래픽을 보내며 성능 시험을 하던 중, 적지만 꾸준한 비율의 요청이 타임아웃을 내는 것을 발견했다."},"components":["telemetry-agent","linux-kernel"],"root_cause":"software-bug","remediation":[{"text":{"en":"Disabled cAdvisor's working set size estimation on all PinCompute nodes","ko":"한 줄 설정 변경으로 모든 PinCompute 노드에서 cAdvisor 의 작업 집합 크기 추정을 껐다. 같은 내용을 cAdvisor 저장소에 GitHub 이슈로 올렸다."}}],"action_items":[],"contributing":["default-config-unchanged"],"recurrence_of":null,"symptoms_text":{"en":"During performance testing of Pinterest's search system Manas on its new Kubernetes platform, a small but persistent share of search requests timed out. About one request in a million took 100 times longer than usual.\n\nAcross the leaf nodes, p9999 and lower latencies stayed in the normal range, but max latency reached up to 5s where under 60ms was expected. On a single leaf node, the max latency of both the retrieval and the ranking phase showed sharp spikes every few minutes and fell back almost to normal between them. Both phases run in a single thread per request, so something was either taking that thread off the CPU or making its work slow.\n\nRemoving variables had no effect at all. Manas already had exclusive nodes and dedicated networking; the test cluster was moved to a larger EC2 instance type that held the whole index in memory, given the same AMI as the production EC2 Manas clusters, run without cgroup CPU and memory limits, and finally run directly on the node outside a container. Sampling CPU, memory and network use, comparing preemption with perf, checking cache use and kernel lock contention, and shielding the Manas leaf process onto almost all CPUs with taskset and cpusets showed no CPU stealing or preemption and did not change the spikes.\n\nThe team then paused nonessential processes one at a time with sudo kill -STOP, including logging, stats pipelines, security, the kubelet and Pinterest daemons, and the latency spikes disappeared as soon as cAdvisor was suspended. perf top on the CPUs not used by Manas showed most CPU time in memory-related kernel spans, with cAdvisor calling the kernel's smaps feature.","ko":"2025년 초 쿠버네티스 플랫폼 PinCompute 로 옮긴 검색 시스템 Manas 의 시험 클러스터에 트래픽을 보내자, 적지만 꾸준한 비율의 요청이 타임아웃을 냈다.\n\nleaf 노드 전체를 모은 최대 처리 지연은 매우 높았지만 p9999 이하는 정상 범위였다. 정상이라면 최대 지연이 60ms 아래여야 했는데 최대 5s 까지 나와 거의 100배 나빴다.\n\nleaf 노드 하나를 짧은 시간 간격으로 보자 검색 단계와 순위 단계의 P100 지연이 몇 분마다 급격히 튀었고, 그 사이에는 거의 정상으로 돌아왔다. 두 단계는 요청마다 스레드 하나에서 돌므로, 무언가가 스레드를 CPU 에서 떼어 놓거나 작업 자체를 느리게 만들고 있었다. leaf 노드마다 요청을 수만 건씩 보내고 있었으므로, 요청 하나로 보면 백만 번에 한 번 일어나는 일이었다.\n\n팀은 먼저 변수를 줄였다. 색인 전체를 메모리에 올릴 수 있는 더 큰 EC2 인스턴스 유형으로 시험 클러스터를 다시 만들고, 운영 EC2 Manas 클러스터와 같은 AMI 를 쓰고, CPU 와 메모리의 cgroups 제한을 없애고, 컨테이너 밖에서 노드에 직접 Manas 를 돌려 봤다. 어느 것도 효과가 없었다.\n\nperf 로 CPU 스케줄링 이벤트와 선점 비율, 캐시 사용률, 커널 잠금 경합을 운영 노드와 비교했고, taskset 과 cpuset 으로 Manas leaf 프로세스에 노드의 거의 모든 CPU 를 전용으로 할당했다. CPU 를 빼앗기거나 선점되는 흔적은 보이지 않았고, 이를 막으려는 조치도 효과가 없었다. 팀은 사용자 공간의 자원 제약이나 네트워크, 메모리, 디스크 I/O 의 병목은 없다고 판단했다. 문제는 쿠버네티스가 AMI 위에 더한 무언가에 있고, 일시적으로 나타난다고 보았다."},"updated_at":"2026-11-14T12:33:49.512593Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0247","org_slug":"pinterest"}