{"id":"IL-0276","org":"Parse.ly","date":"2016-06-09","docs":[],"title":{"en":"Chef restarted two of three ZooKeeper nodes at once, and Parse.ly's real-time data stopped for about 3 hours","ko":"Chef 가 ZooKeeper 세 노드 가운데 두 대를 동시에 재시작해 쿼럼이 깨지면서 Parse.ly 의 실시간 데이터 전달이 약 3시간 멈췄다"},"domain":["database"],"impact":{"scope":"Parse.ly real-time data delivery to the dashboard stopped for about 3 hours; the data from that window was delivered late and none was lost","users":"Parse.ly customers","region":"unknown"},"review":{"written_by":"session","reviewed_at":null,"reviewed_by":null},"lessons":{"en":"Automatic routine service restarts are dangerous for services that form a cluster across nodes, and jittering configuration runs only makes simultaneous restarts unlikely, not impossible, once a fleet has hundreds of nodes. A system designed to survive single-node failures still needs a recovery plan for multi-node failures.","ko":"Parse.ly 는 자동 서비스 재시작을 다시 생각하게 됐다. Chef 가 설정 변경은 자동으로 내보내되 서비스 재시작은 엔지니어가 손으로 하거나 승인하도록 대기시켜 두었다면, 이 작업의 위험이 바로 드러났을 것이다. ZooKeeper 가 노드 하나의 장애를 견디도록 설계됐어도 여러 노드가 함께 죽는 일이 불가능하다고 여기면 안 된다. 큰 분산 시스템에서는 무엇이든 일어날 수 있으므로 시스템과 절차에 빠르게 복구할 대안을 늘 준비해 둬야 한다."},"related":[],"sources":[{"url":"https://www.parse.ly/postmortem-2016/","kind":"blog","archived":"https://web.archive.org/web/20260618022029/https://www.parse.ly/postmortem-2016/"}],"summary":{"en":"Parse.ly manages its fleet of over 200 production servers with Chef, which can upgrade software, change configuration cluster-wide and restart services when their configuration changes. To keep restarts from happening everywhere at once, Chef runs are jittered across machines, each node running at a different minute of the hour. One of Parse.ly's three-node ZooKeeper clusters, spread across data centers, holds a small amount of configuration for real-time data delivery; it keeps serving with one node down but refuses requests when two are down. A regular Chef run restarted two of its nodes at the same time, the cluster lost quorum, and the services that relied on it failed in a way that could not recover on its own. With hundreds of nodes, two runs coinciding is a real probability even at random minutes. Around 1pm, without yet knowing the root cause, the team chose a cold start: clearing a few hours of data from the live systems and bringing the clusters down and up from scratch. The pipeline worked again by 2pm and real-time functionality was restored by 2:30pm. The root cause was confirmed in the following days from monitoring data and system logs. No data was lost; the data from the 3-hour window arrived late through the historical rebuild.","ko":"Parse.ly 는 200대가 넘는 운영 서버를 Chef 로 관리한다. Chef 는 소프트웨어 버전을 올리고, 클러스터 전체의 설정을 바꾸고, 설정이 바뀌면 서비스를 재시작한다. 재시작이 한꺼번에 몰리지 않도록 장비마다 Chef 실행 시각을 흩어 두지만, 노드가 수백 대가 되면 두 실행이 겹칠 가능성이 실제로 생긴다. Parse.ly 의 ZooKeeper 클러스터 하나는 실시간 데이터 전달에 관련된 작은 설정만 맡고, 여러 데이터센터에 걸친 세 노드로 이루어진다. 한 노드가 꺼지면 나머지 두 노드가 쿼럼을 이뤄 요청을 처리하지만, 두 노드 이상이 꺼지면 쿼럼이 없어 요청을 거부한다.\n\n6월 9일 11:30am ET 에 정기 Chef 실행이 이 클러스터의 두 노드를 정확히 같은 시각에 재시작해 쿼럼이 깨졌고, 이 클러스터에 의존하는 서비스들이 한동안 복구할 수 없게 망가졌다. 대시보드로 가는 데이터 전달이 멈췄다. 팀은 워룸을 열고 Twitter 와 대시보드 알림으로 고객에게 알렸다. 클러스터 장비 재시작은 효과가 없는 것 같았다. 1pm 무렵 팀은 근본 원인을 몰랐지만 콜드 스타트로 관련 없는 변수를 없애기로 했다. 실시간 시스템에서 몇 시간치 데이터를 비우고, 클러스터를 내렸다가 처음부터 다시 올리는 방법이다. 2pm 에 데이터 파이프라인이 다시 돌기 시작했고 2:30pm 에 실시간 기능이 복구됐다. 근본 원인은 그 뒤 몇 시간과 며칠에 걸쳐 후보 셋을 지워 나가며 모니터링 데이터와 시스템 로그로 확인했다. 잃은 데이터는 없었고, 그 3시간치 데이터는 이력 재구축으로 늦게 대시보드에 반영됐다."},"trigger":{"en":"A regular Chef run that applied a configuration change restarted the service on two of the three nodes of a ZooKeeper cluster at the same moment.","ko":"2016년 6월 9일 정기적으로 도는 Chef 가 설정 변경에 따라 서비스를 재시작하면서, 세 노드로 된 ZooKeeper 클러스터의 두 노드를 정확히 같은 시각에 재시작했다."},"severity":"unknown","symptoms":["service-unavailable"],"timeline":{"detected_after":null,"resolved_after":"3h"},"date_kind":"incident","detection":{"en":"Parse.ly's data delivery monitors reported that data had stopped flowing to the dashboard; no other system reported a failure.","ko":"데이터 전달 모니터가 대시보드로 가는 데이터 전달이 멈춘 것을 알렸다. 다른 시스템은 장애를 알리지 않았다."},"components":["coordination-store"],"root_cause":"deploy-rollout","remediation":[{"text":{"en":"Cleared a few hours of data from the live systems and cold-started the clusters, taking them offline and bringing them back from scratch","ko":"실시간 시스템에서 몇 시간치 데이터를 비우고, 클러스터를 내렸다가 처음부터 다시 올리는 콜드 스타트를 했다."}},{"text":{"en":"Delivered the data from the outage window late through the historical rebuild process","ko":"멈춘 3시간치 데이터를 이력 재구축 과정으로 대시보드에 다시 넣었다."}}],"action_items":[{"text":{"en":"Separate production configuration changes from production node restarts","ko":"운영 환경의 설정 변경과 노드 재시작을 분리한다."}},{"text":{"en":"Always keep a plan B for rapid recovery in systems and processes, instead of treating multi-node failures as impossible","ko":"시스템과 절차에 빠르게 복구할 대안을 늘 준비해 둔다."}}],"contributing":["assumption-unverified","no-staged-rollout"],"recurrence_of":null,"symptoms_text":{"en":"On Thursday 9 June 2016 at 11:30am ET, real-time data suddenly stopped arriving in Parse.ly's dashboard. Only the data delivery monitors reported a failure; no hardware or machine had failed and no other system reported anything, so the cause was at first unclear.\n\nIn the war room some engineers restarted the cluster machines, which seemed to have no effect, while others read system logs and monitors. A monitoring graph later showed Chef run events lining up with the moment the real-time data lines dropped to zero.","ko":"2016년 6월 9일 목요일 11:30am ET 에 대시보드로 가는 데이터 전달이 갑자기 멈췄다. 데이터 전달 모니터 말고는 어떤 시스템도 장애를 알리지 않았다.\n\n망가진 하드웨어나 장비가 없어서 처음에는 원인이 분명하지 않았다.\n\n엔지니어 일부는 클러스터 장비를 재시작하는 것처럼 뻔한 조치를 해 봤지만 효과가 없는 것 같았다. 다른 엔지니어들은 시스템 로그와 모니터를 살펴 근본 원인을 찾았다.\n\n나중에 모니터링 그래프를 보니 Chef 실행 이벤트와 같은 시점에 실시간 데이터 흐름이 갑자기 0 으로 떨어져 있었다."},"updated_at":"2026-11-14T12:33:52.756194Z","url":"https://benchlet.com/incidentlib/app/cases/IL-0276","org_slug":"parse-ly"}