Cloudflare 前幾天 API 與 Dashboard 出事的 Post Mortem 記錄

前幾天 Cloudflare 的 API 與 dashboard 掛了一天多,少見的讓 Matthew Prince (CEO) 自己出來發 post mortem 記錄了:「Post Mortem on Cloudflare Control Plane and Analytics Outage」,在 Hacker News 上面也有蠻多討論的:「Post Mortem on Cloudflare Control Plane and Analytics Outage (cloudflare.com)」,這邊是整理我自己讀完後的感想。

從「Matthew Prince - The Cloudflare Blog」這邊可以看出來 Matthew Prince 上次是 2023/09/27 的公關文「Cloudflare’s 2023 Annual Founders’ Letter」,還有對應的多國翻譯,像是繁體中文的「Cloudflare 2023 年度創始人來信」,再往前的 2022/12/11 也是公關文「Welcome to Cloudflare’s Impact Week」(以及對應的繁體中文版本:「歡迎來到 Cloudflare 的 Impact Week」)。

這次的事情算是 Cloudflare 在 post-IPO 後很少見的長時間出事,就難得看到 Matthew Prince 自己出來坦了。為了重新建立信任,加上因為層級的關係,可以看到透漏出很多架構細節,算是這次可以窺視 Cloudflare 架構的一些資訊。

先大概提一下官方文章的著墨點:他們花了非常多的篇幅在機房服務商 Flexential 在處理 PDX-04 (這是 Cloudflare 訂的名稱) 機房電力問題的失職 (要注意這邊是 Cloudflare 的觀點,認為 Flexential 的失職,目前沒有從 Flexential 這邊的消息出來解釋),淡化掉了 Cloudflare 自己的設計問題,這邊在 Hacker News 上有蠻多人都有指出來的。

這次事件一切的起因是 Flexential 的 PDX-04 機房整個電力系統斷線 offline 導致的,屬於標準的 data center failure 的情況,像是 2013 年二月時是方機房的火災 (可以參考 iThome 的整理),或是 2021 年 OVH 的機房火災 (「去年 OVH 機房大火的部份情形最近被揭露」),是個在設計架構時一定會規劃進去的項目。

所以 Matthew Prince 先是解釋 Cloudflare 的 HA 作法,是直接在 Hillsboro, Oregon 租三個機房建立起 low-latency network:

Cloudflare's control plane and analytics systems run primarily on servers in three data centers around Hillsboro, Oregon. The three data centers are independent of one another, each have multiple utility power feeds, and each have multiple redundant and independent network connections.

但大家看到這計馬上就會去查,這個城市也才 66.9km2 的土地,大約是 1/4 個台北市 (約 291.8km2) 再小一些,拉了一下城市內的直線最遠距離,大約是 12km?

呃,這不是一個地震 (就在聖安地列斯斷層區域?) 或是一個核攻擊就把 Cloudflare 最核心的部分給擺平了嗎?

其中 analytics systems 就算了:整個 Hillsboro 掛了進入 gracefully degrading,我可以理解這個設計的考量,但 control plane 看起來不太妙?

雞蛋放在同一個籃子的問題裡先放著,雖然這個問題真的很...。

後續提到了有些重要的產品對沒有 HA 能力的服務上有相依性:

Unfortunately, we discovered that a subset of services that were supposed to be on the high availability cluster had dependencies on services exclusively running in PDX-04.

這邊沒有講是哪些服務的相依性,但文章其他地方有提到有些基礎服務是沒有跨機房 HA 架構的,只有在 PDX-04 有跑,包括了 KafkaClickHouse

In particular, two critical services that process logs and power our analytics — Kafka and ClickHouse — were only available in PDX-04 but had services that depended on them that were running in the high availability cluster.

這點讓人頗意外的,Kafka 因為自己架設 & 維護過,知道他的架構本身就很容易設計到跨機房的 case,而且這算是很基礎建設的東西,居然沒有跨機房 HA?

而 ClickHouse 只有研究過,沒有實際把 production 量丟上去跑,但從文件看到的東西,應該至少能做到 shared-everything 的架構,也居然沒有跨機房 HA?

這接基礎建設的問題,導致了雖然只是單一機房 PDX-04 掛掉,但在有重要基礎建設消失的情況下 (應該就是上面提到的 Kafka 與 ClickHouse),加上 Flexential 沒有給出恢復的時間,決定直接跑災難重建的 SOP (也就是 Hillsboro 的三個機房都回不來的情境)。

而這也可以看到恢復時間比較久,從決定切到歐洲的 DR site 到整個切過去花了四個多小時:

Because more services were offline than we expected, and because Flexential could not give us a time for restoration of our services, we made the call at 13:40 UTC to fail over to Cloudflare's disaster recovery sites located in Europe.

By 17:57 UTC, the services that had been successfully moved to the disaster recovery site were stable and most customers were no longer directly impacted.

因為 Kafka 與 ClickHouse 在 Hillsboro 只有單一機房有服務,那就不確定歐洲 DR site 平常有沒有建起來,也許這邊的四個多小時有不少是在歐洲 DR site 把 Kafka 與 ClickHouse 建起來?(這個就只能猜測了)

回到 Flexential 這邊,在恢復供電的過程發現 Cloudflare 這邊迴路用的 breaker 掛了,直到十個小時後才供電,但也因為大家都忙了一整天,Matthew Prince 決定讓大家先回去休息,隔天早上再從歐洲的 DR site 切回 Hillsboro,也因此拉長了恢復的時間:

At 12:48 UTC, Flexential was able to get the generators restarted. [...] When Flexential attempted to power back up Cloudflare's circuits, the circuit breakers were discovered to be faulty.

Flexential replaced our failed circuit breakers, restored both utility feeds, and confirmed clean power at 22:48 UTC. Our team was all-hands-on-deck and had worked all day on the emergency, so I made the call that most of us should get some rest and start the move back to PDX-04 in the morning. That decision delayed our full recovery, but I believe made it less likely that we’d compound this situation with additional mistakes.

要注意報告慣例是用 UTC 時間 (這又是另外一個主題了,先前 HN 上也有其他文章討論過...),而 Hillsboro 在美西,要減八個小時,所以 22:48 UTC 是下午兩點多左右,美東與歐洲的團隊時間則會更晚。

目前看起來 Cloudflare 的設計與流程有很大的改善空間?之後看看有沒有其他的八卦消息出來?

這次 Jira 雲端版相關的服務炸鍋的情況 (還在進行中...)

Atlassian 最近好像把 Jira 雲端版相關的服務給炸了,本來想等到差不多告一段落再來看看發生什麼事情,直到看到這則推說預估還要兩個星期,看起來還是先寫下來好了,不然會忘記...:

在「Multiple sites showing down/under maintenance」這邊可以看到從清明節開始炸,到昨天的報告裡面可以看到受到影響的客戶裡面他們只恢復了 35%:

A small number of Atlassian customers continue to experience service outages and are unable to access their sites. Our global engineering teams are working 24/7 to make progress on this incident. At this time, we have rebuilt functionality for over 35% of the users who are impacted by the service outage, with no reported data loss. The rebuild stage is particularly complex due to several steps that are required to validate sites and verify data. These steps require extra time, but are critical to ensuring the integrity of rebuilt sites. We apologize for the length and severity of this incident and have taken steps to avoid a recurrence in the future.

Posted 19 hours ago. Apr 11, 2022 - 08:27 UTC

所以炸掉一個禮拜後大概恢復 1/3,所以的確官方預估還需要兩個禮拜應該差不多?另外在 Hacker News 上也有炸鍋的討論:「Atlassian products have been down for 4 days (atlassian.com)」。

另外在 The Register 上也有一系列的報導,裡面透漏的比官方的更多:「Atlassian Jira, Confluence outage persists two days on」、「Atlassian outage lingers, sparking data loss fears」、「Day 7 of the great Atlassian outage: IT giant still struggling to restore access」、「At last, Atlassian sees an end to its outage ... in two weeks」。

第一篇的副標題有提到原因:

'Routine maintenance script' blamed for derailed service for unlucky customers

第二篇則是提到大約 400 個客戶受到影響:

We were also told that the incident affects a relatively small number of Atlassian customers: about 400. That's only 0.18 per cent of the company's 226,000 customers, which isn't much consolation to the several hundred who still can't access their data.

之後再回頭來看所謂的 routine maintenance script 是什麼好了...

這個月 GitHub 的不穩問題,都是 mysql1 這個 cluster 的鍋...

GitHub 針對了這個月的四次 downtime 說明,大致上都跟 mysql1 這組 cluster 有關:「An update on recent service disruptions」,這是 Keith Ballinger 發的文章,找了一下掛的頭銜是 SVP of Engineering at GitHub。

文章裡提到的 mysql1 在「Partitioning GitHub’s relational databases to handle scale」這邊可以看到一些資訊 (我在「GitHub 的 MySQL 架構與數字」這邊也有提到),基本上有 ProxySQL + Vitess 兩套方案在 scale,但可以看出來主資料庫本身還是有很大的 loading 在上面跑。

這次的問題是 mysql1 看起來這次遇到了效能上的瓶頸,不過還是沒找到原因,這可以從這幾次的說明看出來,從第一次的 outage:

The incident appeared to be related to peak load combined with poor query performance for specific sets of circumstances.

第二次的:

The following day, we saw the same peak traffic pattern and load on mysql1. We were not able to pinpoint and address the query performance issues before this peak, and we decided to proactively failover before the issue escalated.

第三次的:

While we had reduced load seen in the previous incidents, we were not fully confident in the mitigations.

In this third incident, we enabled memory profiling on our database proxy in order to look more closely at the performance characteristics during peak load.

到最近第四次的:

In order to reduce load, we throttled webhook traffic and will continue to use that as a mitigation to prevent future recurrence during peak load times as we continue to investigate further mitigations.

可以看到基本上還沒完,之後再遇到問題時應該還是會把 webhook traffic 拿出來開刀...

AWS 的 us-west-1 與 us-west-2 炸掉

AWS 又炸了,不過這次不是死在 us-east-1,在 Hacker News 上的討論「AWS appears to be down again」可以看一看...

話說回來,前幾天在「前幾天 AWS 的 us-east-1 出事報告」才提到可以放到 us-west-2,怎麼就炸了...

手上的 SmokePing 也可以看到一些資訊,像是 HiNet 到 dynamodb.us-west-1.amazonaws.com:

HiNet 到 dynamodb.us-west-2.amazonaws.com 的:

第四台 (APOL 線路) 到 dynamodb.us-west-1.amazonaws.com 的:

第四台 (APOL 線路) 到 dynamodb.us-west-2.amazonaws.com 的:

可以看出來從網路層就了出問題,再等幾天看 AWS 出報告吧...

前幾天 AWS 的 us-east-1 出事報告

AWS 放出前幾天 us-east-1 出事的報告了:「Summary of the AWS Service Event in the Northern Virginia (US-EAST-1) Region」,Hacker News 上的討論「Summary of the AWS Service Event in the Northern Virginia (US-East-1) Region (amazon.com)」也可以看一下,裡面也有人提到儘量閃開 us-east-1

而爆炸當天的討論「AWS us-east-1 outage (amazon.com)」也可以看一看,裡面還有聊到企業文化的問題...

AWS 的 us-east-1 除了是 AWS 最早的區域以外,也是目前 AWS 內功能最多的區域 (大多數新功能在第一波都會開放 us-east-1 使用),然後也是最便宜的區域,所以會有很多人都用這個區域提更服務。

也因為這樣,這個區域也是 AWS 內最大的區域,加上 AWS 是目前最大的公有雲,導致了這個區域的很多東西會遇到以前的人都沒遇過的問題,大概每年 (或是每兩年) 就會有一次比較嚴重的 outage,算是為了價錢而選擇 us-east-1 的人要注意的。

說到價錢,如果是為了找價錢比較低的區域,另外一個可以考慮選擇是 us-west-2,出新功能與新產品時也常常會被放進第一波,目前看起來的歷史記錄應該是比 us-east-1 好不少...

這次出問題的主要是內部控制用的網路 (被稱為 internal network) 擁塞,而非客戶在用的網路 (被稱為 main network):

To explain this event, we need to share a little about the internals of the AWS network. While the majority of AWS services and all customer applications run within the main AWS network, AWS makes use of an internal network to host foundational services including monitoring, internal DNS, authorization services, and parts of the EC2 control plane.

後面也有提到因為壅塞而導致 monitoring 系統受到影響,只能就手上的 log 去分析猜測,然後逐步排除問題,而 deployment 系統也使用內部網路,所以更新的速度也快不起來...

不過基本上可以預期明年或是後年應該還是會再來一波...

Fastly 服務掛掉的事件

Hacker News 上看到「Summary of June 8 outage (fastly.com)」這邊的討論,連結是 Fastly 官方先發布的說明:「Summary of June 8 outage」。

其中提到了是因為客戶的某些設定造成的:

10:27 Fastly Engineering identified the customer configuration

另外特別提到了 Fastly 的 WebAssembly 與 Compute@Edge,看起來應該就是這邊炸鍋:

Broadly, this means fully leveraging the isolation capabilities of WebAssembly and Compute@Edge to build greater resiliency from the ground up. We’ll continue to update our community as we make progress toward this goal.

我猜基本的資源保護機制應該有上 (像是在程式裡面自己 call 自己之類的,Fork bomb 之類的),可能是這兩個東西互串的某些部份沒有保護到,就一路把資源吃完炸掉。

看起來後續會有比較完整的報告,到時候再來看看會透露出多少東西...

斷線討論的 mailing list

Hacker News 的首頁上看到的,昨天 Level3 看起來有大規模異常:「[outages] Level3 (globally?) impacted (IPv4 only)」,對應的討論串在「Level 3 Global Outage (nether.net)」這邊。

參考「AS Rank: A ranking of the largest Autonomous Systems (AS) in the Internet.」這邊可以看到 Level 3 目前的排名是 #1,這次大規模故障影響的範圍會讓很多人都有感覺...

比較好玩的是有個 mailing list 在討論這種狀況的:「Outages -- Outages (planned & unplanned) Reporting.」,雖然上面的人看起來不多就是了...

Cloudflare 因為 Regular Expression 炸掉的問題

先前 Cloudflare 就有先說明七月二日的 outage 是因為 regular expression 造成的 (ReDoS),不過昨天發的文章更完整了,導致爆炸的 regular expression 都給出來了:「Details of the Cloudflare outage on July 2, 2019」。

ReDoS 不算是新的問題,但卻是不太好避免的問題,因為需要有經驗的工程師 (中過獎的工程師) 才比較容易知道哪些 regular expression 是有問題的... 另外就是有花時間研究 regular expression 演算法的工程師也比較容易避開。

也因次,ReDoS 算是這十年來大家在還的債,各家 framework 都因為這個問題改寫了不少 regular expression。

這次的重點在這串式子導致了 ReDoS:

(?:(?:\"|'|\]|\}|\\|\d|(?:nan|infinity|true|false|null|undefined|symbol|math)|\`|\-|\+)+[)]*;?((?:\s|-|~|!|{}|\|\||\+)*.*(?:.*=.*)))

通常容易中獎的地方就是無限制字元與 * & + 連發的地方,後面這塊 )*.*(?:.*=.*))) 看起來就不太妙,果然在後面的分析也有提到:

The critical part is .*(?:.*=.*).

以前應該是在 Formal language 裡學到的,在課堂裡面其實會學到不少業界常用工具的基礎理論...

Stream 對 .io 的感冒

Stream 的人寫了一篇「Why Stream Stopped Using .IO Domain Names for Production Traffic」表達他們對 .io 的感冒...

主要是因為 9/20 爛掉的情況不太妙。第一個是 .io 爛掉了兩個小時 (以月來算 SLA 就等於直接掉了 0.2% uptime,變成不到 99.8%),第二個是爛掉時 server 傳回的不是 SERVFAIL,而是 NXDOMAIN

The outage lasted for almost 2 hours, during which 1/5th of DNS queries for any .getstream.io record would fail.

他們的解法是改到 .com 上,畢竟影響的時候應該會修得比較快。另外文章裡也有延伸提到 Amazon Route 53 爛掉時要怎麼辦,如果他們真的決定要解決的話,應該是會拿出像「StackOverflow 對於多 DNS 商的同步方式...」或是「GitHub 也自己搞了一套管理多家 DNS 的程式...」的搞法吧。

不過這的確是當初選 .io 沒預料到的...

Cloudflare 看這次 815 斷電的網路使用變化

Cloudflare 分析了這次 815 停電對網路造成的影響:「Power outage hits the island of Taiwan. Here’s what we learned.」。

以 Cloudflare 在是方機房的 QPS 來看,停電後反而沒有太大變化:

把裝置種類拆開來看,可以看到桌機的使用量下降,但手機的使用量上升:

這點從 HiNet 的使用頻寬也可以看出來,頻寬使用量降了 25% (從光世代與 ADSL/VDSL 換到行動網路上?):