Release It! 讀書摘要

Release It! 第一版出版於 2007,獲得了 2008 年的 Jolt Awards 獎。第二版是 2019 年出的,跟第一版差了11年,二版前半段講 Stability 的內容一樣,這也是我認為這本書最精彩的部分。而二版整個後半章節幾乎用全新的 DevOps 內容改寫了,十年間的變化還是很大的 :>

這裡摘要第一版 + 第二版上半的一些心得重點,第二版下半段講 DevOps 這幾年講很多了,很多知識點這幾年很熱門都知道了,就沒有細看了。

何謂 Stability

Resilient system 在當有突發流量或持續壓力時,用戶仍能完成任務不會全面崩潰。

Stability Anti-patterns

1. Integration Points 是頭號殺手

Socket 發現連不上,可能會花很長時間卡住
案例是因為流量小閒置被防火牆 drop packets,加上沒有 timeout,造成 connection pool 滿了卡住

Integration Points 可能協議不正常、慢響應或中止運作,如果你沒有做防禦,連結點的故障可能連帶讓整個系統一起連鎖故障

解法: Circuit breaker, Timeouts, Decoupling middleware

2. Chain Reactions 小心連鎖反應現象

一台死,其他台跟著負擔不了造成連鎖故障。其他台必須有保護機制。

解法: 可用 Bulkheads patterns

3. Cascading Failures

當 Caller 因為 resource pool 故障而跟著故障的現象
用 Circuit breaker, Timeouts 避免其他系統GG時,你不會跟著一起GG

4. Users

流量就代表會使用 memory,爬蟲會造成 session 佔用
這個主要風險是 DDoS。要做壓力測試囉

5. Blocked Threads

講執行緒開發的 synchronized thread 會造成 blocked
不要自己寫 connection pool 這很難
小心 vendor client 不一定寫得好

6. Attacks of Self-Denial

指自傷事故: 例如公司的營銷事件
你應該提前知道營銷事件,準備靜態的 landing page 甚至是專門的server,而不是進到深層的頁面耗費資源
避免一個共享資源GG造成全部GG,用 Shared-nothing architecture 或 fail fast 策略

7. Scaling Effects

小心 Peer-to-Peer 在多服務器的情況,可用 Pub/Sub 或 Message Queues。小心 Shared Resources 的瓶頸,需要壓力測試。這些在測試環境很少檢查到。

8. Unbalanced Capacities

在短期間內,硬件容量是固定的。前後端的能力要能隨時匹配是不可能的。這在測試環境很少檢查到,例如前端10台、後端1台的情況

9. Slow Responses

慢回應比拒絕連結更糟糕,Fail Fast 還比較好,不會佔用資源。
原因可能是 memory lead 或網路問題。慢回應也會產生網站更多流量,用戶會不斷刷新。

10. SLA Inversion

你的SLA只會是所有整合服務中最差的一個,任何調用第三方服務,SLA 只會下降。你需要確保你不應依賴 SLA 比你還低的服務

11. Unbounded Result Sets

開發環境資料少沒事,但是上 production 後,有些查詢因為沒有限制數量,回傳了過多的資料。造成 memory 用光…. 也造成 slow responses。

Caller API 應該要能指定只接受多少回傳量。

12. Dogpile (二版才有)

一群 servers 一起 transient load 瞬間載入,例如斷電後全部機器一起開機,然後又倒了。
又例如 cron job 一起跑、配置一起改,這會讓你 peak 需要的容量不必要增加,應避免這種情況。
解法: Retry 間隔時間設定不同、cron jobs 時間錯開等等方式

13. Force Multiplier (二版才有)

小心運用 Infrastructure Mangement 工具啊!

例如 Reditt.com 在 2016/8/11 的案例:
要升級 Zookeeper,關掉 autoscaler,升級過程 package management system 重開 autoscaler
Autoscaler 讀到不正確的 zookeeper 設定,決定關機器….. 就倒站了。於是人去開機器,但 cache 是空的,流量打到資料庫 dogfile…… 又倒了

Discovery service 因為部分線路不正常,造成 service 無法判斷是倒站還是他瞎了。如果依賴這種錯誤資訊,而自動做一些開機器或關機器的操作,就很危險了。

解法: 需要時做一些 safeguard 保護機制,例如如果回報 80%機器都壞了,可能監控自己壞掉的機率還比較大。預期跟觀察情況差太多,要有通知讓人來確認。

Stability Patterns

都不是幫助你通過QA的,而是幫助你晚上睡好覺的。

請不要預期系統不會失效,而是這些模式可以幫助你減輕單個失效帶來的破壞

1. Use Timeouts

網路是不可靠的,用 Timouts 可以隔離故障,讓別人的問題不會害死你。Integration points, blocked threads, slow responses 等問題都可用這招。關於重試也要考慮 retry 時間和頻率,因爲他故障可能會持續一陣子。

2. Circuit Breaker 斷路器

如果失敗太多次,就先關掉。用在 Integration points。
另外要紀錄開關狀態給 Operation team 看。
搭配 Timeouts 使用

3. Bulkheads

將系統分隔,切開保留一部分的資源給關鍵的需求。例如 Virtual server 是個方法。

4. Steady State

系統應可以獨立運作,不需要人為干預。
其中最常見的人為干預就是去處理 data purging 資源滿了 (硬碟 log, database, 內存 caching)。而且 data purging 清除無用的數據的功能通常在軟體第一版不會開發。

Log 不應留在 production,依該搬到另外的地方做分析
緩存要限制大小

5. Fail Fast

慢響應比沒有響應更糟,而失敗的慢響應是最糟糕的。儘早判斷會不會失敗。
大部分失敗的問題是 資源不可用 resource availability 的問題。
在此在交易前可以先確保所有需要的資源,並先做好輸入驗證,若有一個不可用就回應失敗了,不要浪費時間做一半

6. Handshaking

底層常用的握手協議,在應用層卻很少人做。握手可以實現 client <-> server 的限制機制。若沒有握手協議,也可以考慮做 health check 機制來補救。

7. Test Harness

分布式系統的失效很難在本機觸發。整合測試 Integration Tests 也只是測試一種成功情境,你需要建構測試機制去模擬每個 integration point 失效的情境。例如產生慢回應、不回應、垃圾回應等等。可以共用測試裝置。

8. Decoupling Middleware

同步的 middleware 邏輯比較簡單,但失效時會引起放大衝擊,coupling 高。而異步的 middleware 不會引起 cascading failure,coupling 低,但是實作比較難,整體架構都會不同。跟本章其他解法不同,這招成本比較高。

9. Let It Crash (二版才有)

像 Erlang 哲學,設計 supervision 有能力可以放棄獨立的 component,可能是 process 或一個一台機器 重開來救整個 system。如果是 monoliths 系統這招就不適用了,因為重開會太久。

10 .Shed Load (二版才有)

系統外部來的流量太高時,有防禦機制可以回應 503 來阻擋過多的連線,避免 slow responses。系統內部流量,用下一招來做 flow control機制

11.  Create Back Pressure (二版才有)

Flow control 流量控制(需要多少,就生產多少)來平衡 producuer 和 consumer。Queue 要限制大小,能處理 queue 滿載情況,例如 block 掉。參考 TCP flow control。

例如,你的 API service 的處理速度是有上限的,如果超過這個速度,怎麼辦? 可用 Rate limit 暫時 block HTTP 503 掉 client
或是有個 queue 先暫存回傳 HTTP 202,變成 async

12. Governor (二版才有)

自動化如果出錯了,會錯得非常快XD
危險操作(關機器、刪除資料)不要自動地太快,要有通知跟彈性讓人工可以有機會介入。例如自動開機很快,但自動關機要慢,只能讓程式自動一次關多少比例的機器。

Capacity

Performance != Throughput(or capacity) 老闆關心後者、但用戶關心前者。

Capacity 不是線性的,例如 CPU 50% -> 100% 不代表可以處理兩倍用戶。

限制理論: 首先達到極限的限制決定了系統容量。因此要識別出關鍵限制。

Scalability 水平擴展跟垂直擴展: 前者例如 shared-nothing 的 web servers,後者例如 database server。

另外還有一種 cluster server,雖然也算水平擴展但不是線性的,因為有極群管理負擔。

Application server 的 CPU usages 是會影響 memory usages 的。

Capacity Anti-patterns

一版的這章很多內容有點過時太保守了 XD 就不筆記了

只有一條值得一記: Transaction 交易用途和 Reporting 報表用途的資料庫不要放在一起。

Capacity Patterns

  1. 過早最佳化是一切罪惡的根源,這句話變成爛設計的藉口… XD 常常就變成沒有任何優化。
  2. Pool connections 連結池必用的基本技術,要注意大小監控連線時間跟數量。

  3. Caching 要限制緩存大小、監控命中率決定大小。

  4. Precompute Content 預計算 render HTML,特別是流量高的頁面 (除了個人化內容),修改頻率遠低於顯示頻率。這跟 caching 不一樣,這是先算好的不需要預熱。

  5. Tune GC 根據用戶模式,最優設置會有不同,因此要在 production 上調整。重大更新後也要調整。

Security

最少特權原則: process 只需要它需要的最少的權限、每個重要的 app 有自己的 user。

保護好密碼: 特別是資料庫密碼、密碼只有需要的用戶可讀。

Availability

要保證可用性就一定會提高成本。

每提高一個9,會提高 10%開發成本,和每年20%運營成本。你可以拿來和停機帶來的損失相比。

SLA 要定義清楚是哪些功能可用才算,還要排除外部系統,還要有個監控系統。

水平擴展會用到 Load balancing:

DNS round-robin 不好,客戶可能會快取 DNS,造成不夠平衡和彈性
Reverse Proxy 例如 Apache mod_proxy, Squid, Akamai 也算,可以順便做 static caching
Hardware Load Balancer 最厲害,但是一台很貴

Clustering 也可以用來 load balancing, 例如 active-active clusters,或是支援 redundancy 叫做 active-passive clusters。
集群容量低於線性擴展,因為有控制節點是弱點。但配置集群比較複雜,很可能在 active-passive 時雖然可以做到 redundancy 但是 availability 會失敗。

Administration

這章談如何讓系統跟 administrators 配合好,對他好用系統才會運行良好。

QA 環境和 Production 環境不同的問題:

最常見出錯的地方不是配置 configurations 差異,而是 servers topology 不同,例如 QA 時所有程式共用一台主機,上線時才拆開 servers 運行。

解法: 如果 QA 時 sevrer 不能拆開,至少也用 VM 拆開。

0, 1 跟 many 有本質上的區別: QA 時只開一台,而 Production 有很多台。

你不一定需要跟 Production 一樣多台,但至少要不只一台。
Production 會用到設備也需要,不一定需要一樣,但至少可以買同一家廠商和產品線的產品來做 QA。

配置跟程式要分開,也不要跟程式放一起,不然怕 admin 不小心改壞會覆蓋掉,配置文件也建議用版本控制。

第一版這章講的有點簡略落伍了,新時代的 DevOps 在這塊琢磨更多。

Operations

Instrumentation、系統監控、Log、Dashboard (定義紅燈、黃燈、綠燈)、報告通知 等告訴我們系統發生了什麼事,有透明性的系統才好調教。

系統第一次發布後,會發生的成本佔全部成本的 40%~90%,這可能是維護或新功能開發。因為改變系統就會有成本,如果太難改就會不去改。而一個具有適應性的軟體設計,會用到 1.DI 2. OO 3. XP, Refactors, Unit Test 4. Agile DB (schema 版控) 等等技巧,能更好響應客戶需求,就是一個有適應性的架構。

第二版後半

第二版的後半改寫好多,有更多的 DevOps 實務。參考書目多了 Continuous delivery 跟 The DevOps Handbook。

後半內容大致有

  1. Foundations: Container, 12-Factor App
  2. Processes on Machines: Deploy Pipeline, Immutable and Disposable Infrastructure
  3. Interconnect: DNS, Load Balancing, Routing
  4. Control Plane: Log, Metrics, Configuration service, Autoscaler….
  5. Security: 比第一版多講了 OWASP
  6. Design for Deployment: Automated/Continuous Deployments
  7. Handling Versions: 升級、API 升級
  8. Chaos Engineering 和 Netflix 的 Chaos Monkey

如果你有跟上了解 2014 年開始的 DevOps 和 SRE 工具知識,我想這些你都知道了。

 

發佈留言

發表迴響