只有累積,沒有奇蹟

2020年3月25日 星期三

[筆記] TGONext 架構組 - 高併發高流量

前言
在偶然的機會發現 TGONetworks 正在舉辦 TGONext 導師計畫 活動,活動邀請在 技術管理、技術創業技術架構有經驗的科技領袖 (大神) 擔任各組的老師,在五個月之間老師會帶領小組的組員深入討論相關的議題,身為一位打雜多年的工程師,看到可以與諸位大神近距離的學習的機會當然也不會錯過,運氣不錯的也順利通過兩階段的面試錄取,每個月都有小組的聚會討論,TGONext 也鼓勵不同組的組員彼此交流學習,有幸參加了由 Ant 帶領的技術架構一組聚會三月份討論主題是高併發高流量,當天討論議題如下
Database 跟高併發的關係(Ex. NoSQL / RDBMS 在不同場景的負載能力,然後討論到原本的問題要怎麼選擇跟評估)
Server 端口的集中管理 / 微服務的必要性及適用場景 的規劃(Ex. 已經了解整個 Application 的基本配置,要怎麼做出拓展然後發展出 SOA、微服務的架構)
Domain Driven Design 對拓展性的影響(Ex. 傳統單體式的設計跟 MVC 的相關性,要拆分成微服務後 DDD 的設計是否更有利、為什麼有些語言的框架設計都是採取 DDD 的方式)
如何設計一個電商系統,可承載 100 萬人同時在線上,SLA 可達到 99.9% 的架構?(回顧題)
請問 Computer Science 的 Bound Categories 有哪些?可以如何偵測出來?
Cache 的缺點有哪些?模式有哪些?什麼時候應該採用?
高併發高流量與程式語言的哪些特性有關?程式語言選用時可以注意什麼?
高併發高流量在各階段的架構演進可以如何設計?分布式模型的引用?一致性的需求? 
這篇是根據微薄的記憶整理旁聽的筆記,部分內容為了讓初老症狀越來越嚴重的自己更好理解加上自己說明與圖片,若有問題或是錯誤的地方歡迎各位大大一同討論或給予指導

架構的演進
在討論的一開始 Ant 先回覆同學們詢問開幕式提到的 SLA 的計算方式,接著進入到主題高併發高流量,請大家先思考應用程式架構是如何演進的,開始畫圖向大家說明常見的 Application 演進的過程

Monolithic Architecture
在初期 (可能) 會規劃 Application 與 Database 放置在同一台 Server,節省資源與費用避免不必要的浪費,也就是大家常聽到的傳統單體式設計 Monolithic Architecture

Application 與 Database 分離
當使用者逐漸變多時,由於 Application 與 Database 是存放在同一台伺服器主機,共用相同 CPU 與 Memory 資源,可以選擇將 Application 與 Database 分開存放在不同主機以避免資源互搶的狀況發生,以提高可負擔的 Request 請求量。
這時導師拋出一個問題讓大家思考
導師 : 假設單純的 Application 遇到性能瓶頸問題,一般來說第一件事會做甚麼 ? 
Cache Server
最常見的作法就是加上 Cache 機制,舉例來說電商平台首頁大多都有商品介紹,用戶在瀏覽商品資料或是相關頁面時,會發送讀取商品資料的請求至資料庫伺服器,如果同時有 100 位用戶在瀏覽就會有至少100+ 個 Request 請求發送至 Web Server,加上 cache server 可以考慮將這些資料異動不頻繁,或是不那麼重要的資料庫查詢結果資料放置在 Cache Server 中,以提高 Application 回應速度與分擔 Database loading。

導師 : Cache 的優缺點是什麼 ? 什麼時候該採用呢 ? 
Cache 優點部分主要可以降低伺服器的負擔與增加回應速度,還可以減少網路頻寬的浪費與保護資料庫的功能;但在導入之前團隊也必須要了解 Cache 的問題不能只靠乖乖保佑,避免異常發生時不知道該如何處理只能大眼瞪小眼,可能需要注意的有下列幾點
  • 適合情境 : 什麼樣的資料需要放在 Cache 中 ? 假設今天 Database 資料已更新的時候,快取內的就會是未更新的資料(贓資料),用戶讀取到舊的資料影響會是甚麼? 
  • 資料一致性 : 當資料發生不一致時,更新快取的策略是甚麼 ? 是使用 CronJob 排程定時去資料庫更新快取、還是設定快取有效時間讓快取自動失效、或是更新資料庫時同步更新快取內容、或是先淘汰快取後再寫到資料庫 (小弟目前是使用這種方式)。
  • 異常處理 : 當快取 Server 發生異常或是故障時,團隊是否了解該如何快速恢復,如何在一開始建立快取的 HA 機制 ? (如果是使用 Redis 可以設定 master-Slave 與 Sentinel,透過 Sentinel 的哨兵機制,可以在 master 發生異常時快速切換到 slave instance 機器,不用手動進行切換;如果沒有設定 master-Slave 機制,可以使用 Redis 的持久化設定 進行還原的動作 )

  • 雪崩效應 (Avalanche effect)
    在討論的過程中,導師也提到了高併發高流量可能會遇到的雪崩效應,發生情境可能是單一時間同時湧入大量的請求(ex : 五月天搶票),當 cache server 無法承受發生異常或重啟時,由於 Application 是先打 cache server 取得資料,當 Cache server 重啟後沒有資料時會先向 Database 資料庫撈取相關資料再存放到 cache (或是排程固定撈資料),如果程式判斷沒有處理好或是資料庫語法沒寫好的情況下,有可能就會發送多個請求向 Database 撈取同樣的 cache 資料,資料庫同時接受到大量的 cache 資料處理請求短時間無法回應,使用者同時又不斷點擊向 Web Server 送出更多的請求,最後造成 Database 無法提供服務,接著 Web Server 跟 Cache 也因為前面的 Request 請求未處理完塞車的關係相繼的無法使用,應用程式被用戶各個擊破(誤,示意圖如下
    在討論時導師拋出了這些引入 Cache 快取可能存在的問題,因此提醒學員開發團隊在使用前必須先釐清上述可能會遇到的問題,像是Cache 資料的一致性或是更新策略,到後來 Cache 異常時處理方式,團隊成員如果對於 cache 解決方案不夠熟悉而盲目導入的話,又不巧的遇到高流量的請求時 cache server 異常,就會發生團隊無法處理而延長了網站恢復的時間的憾事發生。

    Microservice 微服務
    隨著新的商業需求越來越多,開發者會不斷的在原本的 Application 添加新功能,原先的代碼可能會隨著時間的關係變得更加龐大難以維護,結構變得模糊質量也隨著下降,代碼的建置與部屬周期時間都相對的拉長,單體架構的問題會陸續浮上檯面,為了解決此問題,有人提出使用最近幾年很流行的微服務來解決此問題,世界上有些著名的公司也在使用微服務架構像是 Netflix、eBay和 Paypal。接著導師請大家思考下列的問題,希望決定架構前,必須先了解架構本質上的問題以及導入後帶來的影響
    導師 : 微服務的本質是什麼 ? 什麼時候需要導入微服務呢 ? 
    在討論微服務時前導師先提到 Performance 鐵三角 觀念
    Throughput 
    Latency 
    Memory footprint 
    如同三角形的三邊,任何一邊的改變都會影響到另外兩邊。Microservices 將系統拆分為多個部分將職責相同的功能或模組區分為單一個服務,提高內聚力與降低彼此耦合度,開發與布署時不在互相依賴,各自服務可獨立擴充與伸縮,可使用不同的語言進行開發或合適的資料庫存放資料。了解完本質之後,接著來看導入微服務會帶來哪些挑戰
  • 服務如何拆分 : 首先遇到的問題會是系統要如何拆分為不同的服務,服務之間的業務領域守備範圍該如何定義,如何界定服務的系統邊界 ? 這幾個問題可能會是設計階段需要討論的,因此,在 InfoQ Using Domain-Driven Design When Creating Microservices 文章中提到在微服務使用 領域驅動設計 ( Domain-Driven Design DDD ) 在架構設計上會幫助。
  • 服務之間如何溝通 : 在過去單體式架構可能起一個 Thread 或是 Task 就可以完成的事情,在微服務中可能變為呼叫多個服務才有機會取得結果,在服務之間的通訊機制(溝通)方式是什麼 ? HTTP、TCP 或是其他更適合的溝通方式 ?
  • 部署與監控方式 : 在微服務的架構下服務數量也相對提升,代碼的建置到部署到也隨之變的複雜,如何做到每個服務的監控,像是取得應用程式CPU、記憶體、網路傳輸量等基本資訊,甚至到業務邏輯點的應用程式 Request 執行成功或錯誤率,是否有 Log 視覺化工具可以協助快速將問題定位 ?並在服務發生異常時,並第一時間做出處理與事後根本問題分析。

  • 基礎建設也是微服務重要的環節之一,導師接著提到在微服務中常見的名詞像是 Service Mesh、API Gateway、Zookeeper 等基礎建設,並請學員們思考這些服務/Pattern 分別是為了解決甚麼問題,優缺點是什麼 ? 

    Service Mesh
    在微服務中服務可以使用不同的程式語言來進行開發,但使用不同的程式語言會發現有些 [功能] 是可以共用的,像是驗證機制、監控方式、配置設定、Logging、流量控管、Healthcheck、Circuit Breaking 等功能,以上功能都需要使用各自的程式語言實作出符合某項規範,緊密的耦合相對了也增加了應用程式的整體複雜性,Service Mesh 可以將這種複雜性與應用程式分離開來,提供像是流量管理、Logging、監控、身分驗證、Circuit Breaking 等基礎(通用)功能,讓應用程式可以專心關注處理負責業務邏輯。可以透過設計模式中的 Sidecar Pattern 實現,如果有看過美國隊長電影的人可以回想有一幕美國隊長騎著軍用摩托車,旁邊有加裝一台沒有輪子的側車依附在軍用摩托車上,這是所謂的 sidecar,同樣的在軟體結構中 sidecar 也連結到主應用程式並擴充與增強其功能,示意圖如下
    如果對 Service Mesh 演進有興趣可以參考 Pattern: Service Mesh;另外 The Rise of Service Mesh Architecture 與 Sidecar Design Pattern in your Microservices Ecosystem 對於 Service Mesh 與 Sidecar 優缺點都有更進一步的說明,有興趣的彭油可以參考看看。

    另外,在 Martin fowler 部落格有篇文章 MicroservicePrerequisites 也有提到,建議沒有具備 Basic Monitoring、Rapid provisioning、Rapid application deployment 這三種能力之前,不應該考慮使用微服務架構;另外在 MicroservicePremium 文章也提到微服務帶來的複雜性,當盲目導入可能會帶來更大的麻煩,舉例來說如果今天遇到的問題是系統效能不佳,閉著眼睛導入微服務架構不會改善問題 (加了K8S也不會!!),微服務解決的 Throughput 無法降低 Lateency。因此,架構師或是技術團隊高層必須謹慎的評估,在組織定的商業目標與技術發展兼做出抉擇,選定適合的技術解決方案。

    補充 : Monolithic > SOA > Microservice 
    在提到簡化系統的方法也會讓人聯想到 SOA (Service Oriented Architecture) 架構模型,將可重用的部分抽成服務 Service,降低其複雜性與提高服務的可重用性,在找尋相關資料中幸運發現 Best Architecture for an MVP: Monolith, SOA, Microservices, or Serverless? 文章中解釋 Monolithic、SOA 與微服務三個架構簡單的示意圖


    架構與組織的關係
    系統架構與公司的組織的關係也是密不可分的,也是所謂的康威定律 ( Conaway's Law),wiki 說明如下
    設計系統的架構受制於產生這些設計的組織的溝通結構。  
    舉例來說,當系統規模不大時可能初期會使用單體式架構(Monolithic),背後開發人員會是有一個團隊擔任維護與開發的動作,隨著生意越做越大組織架構可能會跟著調整,陸續因為需求量越來越大而開發團隊加入更多的開發人員(新鮮的肝),接著代碼越來越雜亂與溝通成本越來越高,演變為每個服務後面都會是一個團隊 Team 來進行開發,以加速整體的開發速度,示意圖如下
    同樣的,如果今天是跨國企業不同國開發人員都會有不同的開發專案,彼此要溝通時會透過討論定義 API 簽章內容,降低直接在不熟的情況下修改對方專案造成改A壞B或是資料異常的延伸問題。

    資料庫選擇
    在討論資料庫時候提出下列問題
  • RMDBS、NoSQL、NewSQL 本質的差異 ?
  • RMDBS、NoSQL、NewSQL 優缺點是甚麼 ?
  • NoSQL 興起的原因為何 ? 優於 RMDBS 的原因是什麼 ? 
  • 如何選擇資料庫 ? 
  • 這部分的討論由於小弟在處理公司事務,因此筆記可以參考兩位認真上的同學的筆記內容(被打
  • TGONext: 從缺點選擇架構
  • TGONext - 高併發高流量 

  • 心得
    在討論架構演進的過程中很多名詞過去可能在 meetup 都曾經聽過,可以觀察到在這次的討論中導師不斷引導在場的同學們,希望大家思考這些名詞與技術《本質》是甚麼 ? 解決什麼樣的問題 ? 學習或是引進一門技術時不只是要看它的優點,還要了解它帶來的影響或 side effect 是什麼,可以提出他的優缺點才算是真正了解。也因為如此讓我在寫這篇旁聽筆記時花更多時間思考關於《本質》這件事,學習到用不同的角度來看待事情,謝謝 TGONext 讓我們有這機會可以與技術領域的高手們學習的機會,也期許自己在每次的聚會中學到更多的知識可以分享給更多需要的朋友 :)

    參考
    martinfowler microservice 系列文章
    Microservice Trade-Offs
    How to extract a data-rich service from a monolith
    Microservices and the First Law of Distributed Objects
    Best Architecture for an MVP: Monolith, SOA, Microservices, or Serverless?
    Microservices - Not A Free Lunch!
    Microservices Journey from Netflix OSS to Istio Service Mesh
    瞭解 Microservices 架構
    什么是Service Mesh
    微服務架構 #1, WHY Microservices?
    微服務架構應用指南

    Copyright © m@rcus 學習筆記 | Powered by Blogger

    Design by Anders Noren | Blogger Theme by NewBloggerThemes.com