消除單點,一篇搞定(架構設計篇)
系統架構中,為什麼會存在單點?
(1)存在 設計缺陷 ,出現了單點;
(2)能大大簡化系統設計, 有意為之 ,設定單點 ;
典型網際網路高可用架構,哪些地方可能存在潛在單點?
典型網際網路高可用架構:
(1) 端 ,通過DNS,由域名拿到nginx的外網IP;
(2) 反向代理 , nginx 是後端入口;
(3) 站點應用 ,典型的是tomcat或者apache;
(4) 服務 ,典型的是dubbo提供RPC服務呼叫;
(5) 資料層 ,典型的是 讀寫分離 的db架構;
在這個網際網路架構中, 站點、服務、資料庫的從庫 都容易通過 冗餘 的方式來保證高可用,但:
(1) nginx 是一個潛在的單點;
(2)資料庫 寫庫 也是一個潛在的單點;
哪些例子,因為設計需要,有意設定的單點?
先看GFS (Google File System) 架構的例子:
GFS的系統架構裡主要有這麼幾種角色:
(1)client,就是發起檔案讀寫的呼叫端;
(2)master,這是一個單點服務,它有全域性視野,掌握檔案元資訊;
(3)chunk-server,實際儲存檔案的伺服器;
在GFS系統裡,master是一個單點服務。
Map-reduce系統裡也有類似的角色,協調 全域性 的master就是單點,它的存在,能夠 大大的簡化系統架構設計 。
不管是設計缺陷,還是有意為之,像nginx,db-master,GFS-master這樣的單點服務,會存在什麼問題呢?
兩個大問題:
(1) 高可用問題 :單點一旦發生故障,服務就會受到影響;
(2) 效能瓶頸 :單點不具備良好的擴充套件性, 單點的效能上限往往就是整個系統的效能上限 ;
“高可用”問題通常怎麼優化?
shadow-master是一種很常見的解決單點高可用問題的技術方案。
shadow-master ,顧名思義,它只是單點master的一個shadow(影子):
(1)master工作時,shadow-master只備份;
(2)master出現故障時,shadow-master會自動變成master,繼續提供服務;
shadow-master它能夠解決高可用的問題,並且故障的轉移是自動的,不需要人工介入,但不足是它使 資源的利用率降為了50% ,業內經常使用keepalived+vip的方式實現這類單點的高可用。
以GFS的master為例,master正常時:
(1)client會連線正常的master,shadow-master不對外提供服務;
(2)master與shadow-master之間有一種存活探測機制;
(3)master與shadow-master有相同的虛IP ;
當發現master異常時:
shadow-master會自動頂上成為master,虛IP機制可以保證這個過程對呼叫方是透明的。
除了GFS與MapReduce系統中的主控master,nginx和資料庫的 主庫 master亦可用類似的方式來保證高可用:
(1)兩個主庫設定相互同步的雙主模式;
(2)平時只有一個主庫提供服務;
(3)異常時,虛IP漂移到另一個主庫,shadow-master變成主庫繼續提供服務;
關於高可用,更多詳細的內容,可參考《 ofollow,noindex">究竟啥才是網際網路架構“高可用” 》。
“效能瓶頸”問題通常怎麼優化?
有時候,單點設計是有意為之,此時單點的效能(例如GFS中的master)有可能成為系統的瓶頸,那麼, 減少與單點的互動 ,便成了存在單點的系統優化的核心方向。
如何來減少與單點的互動,有兩種常見的方法:
(1) 批量寫 ;
(2) 客戶端快取 ;
如何利用“批量寫”減少與單點的互動,提升整體效能?
舉一個單點“ID生成器”的例子,很多公司會利用資料庫的auto-inc-id,來作為一個嚴格遞增的ID生成工具。
Line"/> 其互動流程是:
(1)呼叫方需要ID;
(2)插入記錄,利用auto-inc-id來生成和返回ID;
此時,ID 生成 的併發上限,取決於單點資料庫的插入效能上限。
如何利用“ 批量寫” 提升效能呢?
優化如下:
(1)增加一個服務,每次從DB拿出100個id;
(2)呼叫方需要ID;
(3)服務直接返回100個id中的1個,100個分配完,再訪問DB;
這樣一來,每分配100個才會寫資料庫一次,分配id的效能提升了100倍。
如何利用“客戶端快取”減少與單點的互動,提升整體效能?
還是舉GFS檔案系統的栗子。
GFS檔案讀取的流程如下:
(1)GFS的呼叫客戶端client要訪問shenjian.txt,先查詢本地快取,miss了;
(2)client訪問master問說檔案在哪裡,master告訴client在chunk3上;
(3)client把shenjian.txt存放在chunk3上記錄到本地的快取,然後進行檔案的讀寫操作;
(4)未來client要訪問檔案,從本地快取中查詢到對應的記錄,就不用再請求master了,可以直接訪問chunk-server;
這類快取的命中非常非常高,在99%以上(因為檔案的自動遷移是小概率事件),這樣與master的互動次數就降低了100倍。
批量寫,客戶端快取,對效能的提升也有極限,單點效能優化還有沒有其他方法?
無論怎麼批量寫,客戶端快取,單點畢竟是單機,還是有效能上限的。
水平擴充套件 ,才能夠無限的提升系統性能。
以nginx為例,如何來進行水平擴充套件呢?
第一步的DNS解析,只能返回一個nginx外網IP麼?
通過 DNS輪詢 ,在DNS-server,一個域名可以配置多個IP,每次DNS解析請求,輪詢返回不同的IP,就能實現nginx的水平擴充套件,擴充負載均衡層的整體效能。
資料庫單點寫庫也是同樣的道理,在資料量很大的情況下,可以通過水平拆分,來提升寫入效能。
關於效能擴充套件,更多詳細的內容,可參考 《 究竟啥才是網際網路架構“可擴充套件” 》 。
總結
今天的內容很多,希望行文有邏輯:
(1) 單點系統存在的問題 : 可用性問題 , 效能瓶頸問題 ;
(2) shadow-master 是一種常見 高可用 方案;
(3) 減少與單點的互動 ,是 單點系統優化的核心方向 ,常見方法有: 批量寫 , 客戶端快取 ;
(4) 水平擴充套件 ,才能做到理論上的 無限效能 ;
思路 比結論重要。
架構師之路 -分享 可落地 的技術文章
推薦閱讀:
《 究竟啥才是網際網路架構“一致性” 》
《 究竟啥才是網際網路架構“高可用” 》