負載均衡知識總結

負載均衡知識總結前端

 

 

參考:mysql

微信公衆號:架構師之路linux

 

 

 

一分鐘瞭解負載均衡的一切

什麼是負載均衡nginx

負載均衡(Load Balance)是分佈式系統架構設計中必須考慮的因素之一,它一般是指,將請求/數據【均勻】分攤到多個操做單元上執行,負載均衡的關鍵在於【均勻】。web

 

常見的負載均衡方案sql


常見互聯網分佈式架構如上,分爲客戶端層、反向代理nginx層、站點層、服務層、數據層。能夠看到,每個下游都有多個上游調用,只須要作到,每個上游都均勻訪問每個下游,就能實現「將請求/數據【均勻】分攤到多個操做單元上執行」。數據庫

 

【客戶端層->反向代理層】的負載均衡apache


【客戶端層】到【反向代理層】的負載均衡,是經過「DNS輪詢」實現的:DNS-server對於一個域名配置了多個解析ip,每次DNS解析請求來訪問DNS-server,會輪詢返回這些ip,保證每一個ip的解析機率是相同的。這些ip就是nginx的外網ip,以作到每臺nginx的請求分配也是均衡的。後端

 

【反向代理層->站點層】的負載均衡瀏覽器


【反向代理層】到【站點層】的負載均衡,是經過「nginx」實現的。經過修改nginx.conf,能夠實現多種負載均衡策略:

1)請求輪詢:和DNS輪詢相似,請求依次路由到各個web-server

2)最少鏈接路由:哪一個web-server的鏈接少,路由到哪一個web-server

3)ip哈希:按照訪問用戶的ip哈希值來路由web-server,只要用戶的ip分佈是均勻的,請求理論上也是均勻的,ip哈希均衡方法能夠作到,同一個用戶的請求固定落到同一臺web-server上,此策略適合有狀態服務,例如session(58沈劍備註:能夠這麼作,但強烈不建議這麼作,站點層無狀態是分佈式架構設計的基本原則之一,session最好放到數據層存儲)

4)…

 

【站點層->服務層】的負載均衡


【站點層】到【服務層】的負載均衡,是經過「服務鏈接池」實現的。

上游鏈接池會創建與下游服務多個鏈接,每次請求會「隨機」選取鏈接來訪問下游服務。

上一篇文章《RPC-client實現細節》中有詳細的負載均衡、故障轉移、超時處理的細節描述,歡迎點擊link查閱,此處再也不展開。

 

【數據層】的負載均衡

在數據量很大的狀況下,因爲數據層(db,cache)涉及數據的水平切分,因此數據層的負載均衡更爲複雜一些,它分爲「數據的均衡」,與「請求的均衡」。

數據的均衡是指:水平切分後的每一個服務(db,cache),數據量是差很少的。

請求的均衡是指:水平切分後的每一個服務(db,cache),請求量是差很少的。

業內常見的水平切分方式有這麼幾種:

1、按照range水平切分


每個數據服務,存儲必定範圍的數據,上圖爲例:

user0服務,存儲uid範圍1-1kw

user1服務,存儲uid範圍1kw-2kw

這個方案的好處是:

(1)規則簡單,service只需判斷一下uid範圍就能路由到對應的存儲服務

(2)數據均衡性較好

(3)比較容易擴展,能夠隨時加一個uid[2kw,3kw]的數據服務

不足是:

(1)請求的負載不必定均衡,通常來講,新註冊的用戶會比老用戶更活躍,大range的服務請求壓力會更大

 

2、按照id哈希水平切分


每個數據服務,存儲某個key值hash後的部分數據,上圖爲例:

user0服務,存儲偶數uid數據

user1服務,存儲奇數uid數據

這個方案的好處是:

(1)規則簡單,service只需對uid進行hash能路由到對應的存儲服務

(2)數據均衡性較好

(3)請求均勻性較好

不足是:

(1)不容易擴展,擴展一個數據服務,hash方法改變時候,可能須要進行數據遷移

 

總結

負載均衡(Load Balance)是分佈式系統架構設計中必須考慮的因素之一,它一般是指,將請求/數據【均勻】分攤到多個操做單元上執行,負載均衡的關鍵在於【均勻】。

(1)【客戶端層】到【反向代理層】的負載均衡,是經過「DNS輪詢」實現的

(2)【反向代理層】到【站點層】的負載均衡,是經過「nginx」實現的

(3)【站點層】到【服務層】的負載均衡,是經過「服務鏈接池」實現的

(4)【數據層】的負載均衡,要考慮「數據的均衡」與「請求的均衡」兩個點,常見的方式有「按照範圍水平切分」與「hash水平切分」

 

 

 

 

lvs爲什麼不能徹底替代DNS輪詢

上一篇文章「一分鐘瞭解負載均衡的一切」引發了很多同窗的關注,評論中你們爭論的比較多的一個技術點是接入層負載均衡技術,部分同窗持這樣的觀點:

1)nginx前端加入lvs和keepalived能夠替代「DNS輪詢」

2)F5能搞定接入層高可用、擴展性、負載均衡,能夠替代「DNS輪詢」

「DNS輪詢」到底是不是過期的技術,是否是能夠被其餘方案替代,接入層架構技術演進,是本文將要細緻討論的內容。

 

1、問題域

nginx、lvs、keepalived、f五、DNS輪詢,往往提到這些技術,每每討論的是接入層的這樣幾個問題:

1)可用性:任何一臺機器掛了,服務受不受影響

2)擴展性:可否經過增長機器,擴充系統的性能

3)反向代理+負載均衡:請求是否均勻分攤到後端的操做單元執行

 

2、上面那些名詞都是幹嗎的

因爲每一個技術人的背景和知識域不一樣,上面那些名詞縮寫(運維的同窗再熟悉不過了),仍是花1分鐘簡單說明一下(詳細請自行「百度」):

1)nginx:一個高性能的web-server和實施反向代理的軟件

2)lvs:Linux Virtual Server,使用集羣技術,實如今linux操做系統層面的一個高性能、高可用、負載均衡服務器

3)keepalived:一款用來檢測服務狀態存活性的軟件,經常使用來作高可用

4)f5:一個高性能、高可用、負載均衡的硬件設備(聽上去和lvs功能差很少?)

5)DNS輪詢:經過在DNS-server上對一個域名設置多個ip解析,來擴充web-server性能及實施負載均衡的技術

 

3、接入層技術演進

【裸奔時代(0)單機架構】


裸奔時代的架構圖如上:

1)瀏覽器經過DNS-server,域名解析到ip

2)瀏覽器經過ip訪問web-server

缺點

1)非高可用,web-server掛了整個系統就掛了

2)擴展性差,當吞吐量達到web-server上限時,沒法擴容

注:單機不涉及負載均衡的問題

 

【簡易擴容方案(1)DNS輪詢】

假設tomcat的吞吐量是1000次每秒,當系統總吞吐量達到3000時,如何擴容是首先要解決的問題,DNS輪詢是一個很容易想到的方案:


此時的架構圖如上:

1)多部署幾份web-server,1個tomcat抗1000,部署3個tomcat就能抗3000

2)在DNS-server層面,域名每次解析到不一樣的ip

優勢

1)零成本:在DNS-server上多配幾個ip便可,功能也不收費

2)部署簡單:多部署幾個web-server便可,原系統架構不須要作任何改造

3)負載均衡:變成了多機,但負載基本是均衡的

缺點

1)非高可用:DNS-server只負責域名解析ip,這個ip對應的服務是否可用,DNS-server是不保證的,假設有一個web-server掛了,部分服務會受到影響

2)擴容非實時:DNS解析有一個生效週期

3)暴露了太多的外網ip

 

【簡易擴容方案(2)nginx】

tomcat的性能較差,但nginx做爲反向代理的性能就強多了,假設線上跑到1w,就比tomcat高了10倍,能夠利用這個特性來作擴容:


此時的架構圖如上:

1)站點層與瀏覽器層之間加入了一個反向代理層,利用高性能的nginx來作反向代理

2)nginx將http請求分發給後端多個web-server

優勢

1)DNS-server不須要動

2)負載均衡:經過nginx來保證

3)只暴露一個外網ip,nginx->tomcat之間使用內網訪問

4)擴容實時:nginx內部可控,隨時增長web-server隨時實時擴容

5)可以保證站點層的可用性:任何一臺tomcat掛了,nginx能夠將流量遷移到其餘tomcat

缺點

1)時延增長+架構更復雜了:中間多加了一個反向代理層

2)反向代理層成了單點,非高可用:tomcat掛了不影響服務,nginx掛了怎麼辦?

 

【高可用方案(3)keepalived】

爲了解決高可用的問題,keepalived出場了(以前的文章「使用shadow-master保證系統可用性」詳細介紹過):


此時:

1)作兩臺nginx組成一個集羣,分別部署上keepalived,設置成相同的虛IP,保證nginx的高可用

2)當一臺nginx掛了,keepalived可以探測到,並將流量自動遷移到另外一臺nginx上,整個過程對調用方透明


優勢

1)解決了高可用的問題

缺點

1)資源利用率只有50%

2)nginx仍然是接入單點,若是接入吞吐量超過的nginx的性能上限怎麼辦,例如qps達到了50000咧?

 

【scale up擴容方案(4)lvs/f5】

nginx畢竟是軟件,性能比tomcat好,但總有個上限,超出了上限,仍是扛不住。

lvs就不同了,它實施在操做系統層面;f5的性能又更好了,它實施在硬件層面;它們性能比nginx好不少,例如每秒能夠抗10w,這樣能夠利用他們來擴容,常見的架構圖以下:


此時:

1)若是經過nginx能夠擴展多個tomcat同樣,能夠經過lvs來擴展多個nginx

2)經過keepalived+VIP的方案能夠保證可用性

99.9999%的公司到這一步基本就能解決接入層高可用、擴展性、負載均衡的問題。

 

這就完美了嘛?還有潛在問題麼?

好吧,無論是使用lvs仍是f5,這些都是scale up的方案,根本上,lvs/f5仍是會有性能上限,假設每秒能處理10w的請求,一天也只能處理80億的請求(10w秒吞吐量*8w秒),那萬一系統的日PV超過80億怎麼辦呢?(好吧,沒幾個公司要考慮這個問題)

 

【scale out擴容方案(5)DNS輪詢】

如以前文章所述,水平擴展,纔是解決性能問題的根本方案,可以經過加機器擴充性能的方案才具有最好的擴展性。

facebook,google,baidu的PV是否是超過80億呢,它們的域名只對應一個ip麼,終點又是起點,仍是得經過DNS輪詢來進行擴容


此時:

1)經過DNS輪詢來線性擴展入口lvs層的性能

2)經過keepalived來保證高可用

3)經過lvs來擴展多個nginx

4)經過nginx來作負載均衡,業務七層路由

 

4、結論

聊了這麼多,稍微作一個簡要的總結:

1)接入層架構要考慮的問題域爲:高可用、擴展性、反向代理+擴展均衡

2)nginx、keepalived、lvs、f5能夠很好的解決高可用、擴展性、反向代理+擴展均衡的問題

3)水平擴展scale out是解決擴展性問題的根本方案,DNS輪詢是不能徹底被nginx/lvs/f5所替代的

 

末了,上一篇文章有同窗留言問58到家採用什麼方案,58到家目前部署在阿里雲上,前端購買了SLB服務(能夠先粗暴的認爲是一個lvs+keepalived的高可用負載均衡服務),後端是nginx+tomcat。

 

5、挖坑

接入層講了這麼多,下一章,準備講講服務層「異構服務的負載均」(牛逼的機器應該分配更多的流量,如何作到?)。

 

 

 

 

如何實施異構服務器的負載均衡及過載保護?

零、需求緣起

第一篇文章「一分鐘瞭解負載均衡」和你們share了互聯網架構中反向代理層、站點層、服務層、數據層的經常使用負載均衡方法。

第二篇文章「lvs爲什麼不能徹底代替DNS輪詢」和你們share了互聯網接入層負載均衡須要解決的問題及架構演進。

在這兩篇文章中,都強調了「負載均衡是指,將請求/數據【均勻】分攤到多個操做單元上執行,負載均衡的關鍵在於【均勻】」。

 

然而,後端的service有可能部署在硬件條件不一樣的服務器上

1)若是對標最低配的服務器「均勻」分攤負載,高配的服務器的利用率不足;

2)若是對標最高配的服務器「均勻」分攤負載,低配的服務器可能會扛不住;

可否根據異構服務器的處理能力來動態、自適應進行負載均衡及過載保護,是本文要討論的問題。

 

1、service層的負載均衡一般是怎麼作的


一分鐘瞭解負載均衡」中提到,service層的負載均衡,通常是經過service鏈接池來實現的,調用方鏈接池會創建與下游服務多個鏈接,每次請求「隨機」獲取鏈接,來保證service訪問的均衡性。

RPC-client實現細節」中提到,負載均衡、故障轉移、超時處理等細節也都是經過調用方鏈接池來實現的。

這個調用方鏈接池可否實現,根據service的處理能力,動態+自適應的進行負載調度呢?

 

2、經過「靜態權重」標識service的處理能力


調用方經過鏈接池組件訪問下游service,一般採用「隨機」的方式返回鏈接,以保證下游service訪問的均衡性。

 

要打破這個隨機性,最容易想到的方法,只要爲每一個下游service設置一個「權重」,表明service的處理能力,來調整訪問到每一個service的機率,例如:

假設service-ip1,service-ip2,service-ip3的處理能力相同,能夠設置weight1=1,weight2=1,weight3=1,這樣三個service鏈接被獲取到的機率分別就是1/3,1/3,1/3,可以保證均衡訪問。

 

假設service-ip1的處理能力是service-ip2,service-ip3的處理能力的2倍,能夠設置weight1=2,weight2=1,weight3=1,這樣三個service鏈接被獲取到的機率分別就是2/4,1/4,1/4,可以保證處理能力強的service分別到等比的流量,不至於資源浪費。

 

使用nginx作反向代理與負載均衡,就有相似的機制。

這個方案的優勢是:簡單,可以快速的實現異構服務器的負載均衡。

缺點也很明顯:這個權重是固定的,沒法自適應動態調整,而不少時候,服務器的處理能力是很難用一個固定的數值量化。

 

3、經過「動態權重」標識service的處理能力

提問:經過什麼來標識一個service的處理能力呢?

回答:其實一個service能不能處理得過來,能不能響應得過來,應該由調用方說了算。調用服務,快速處理了,處理能力跟得上;調用服務,處理超時了,處理能力頗有可能跟不上了。

 

動態權重設計

1)用一個動態權重來標識每一個service的處理能力,默認初始處理能力相同,即分配給每一個service的機率相等;

2)每當service成功處理一個請求,認爲service處理能力足夠,權重動態+1

3)每當service超時處理一個請求,認爲service處理能力可能要跟不上了,權重動態-10(權重降低會更快)

4)爲了方便權重的處理,能夠把權重的範圍限定爲[0, 100],把權重的初始值設爲60分

 

舉例說明:

假設service-ip1,service-ip2,service-ip3的動態權重初始值weight1=weight2=weight3=60,剛開始時,請求分配給這3臺service的機率分別是60/180,60/180,60/180,即負載是均衡的。

 

隨着時間的推移,處理能力強的service成功處理的請求愈來愈多,處理能力弱的service偶爾有超時,隨着動態權重的增減,權重可能變化成了weight1=100,weight2=60,weight3=40,那麼此時,請求分配給這3臺service的機率分別是100/200,60/200,40/200,即處理能力強的service會被分配到更多的流量。

 

4、過載保護

提問:什麼是過載保護?

圖示:過載保護的負載與處理能力圖(會掉底)

回答:互聯網軟件架構設計中所指的過載保護,是指當系統負載超過一個service的處理能力時,若是service不進行自我保護,可能致使對外呈現處理能力爲0,且不能自動恢復的現象。而service的過載保護,是指即便系統負載超過一個service的處理能力,service讓能保證對外提供有損的穩定服務。

圖示:過載保護的負載與處理能力圖(不會掉底)

提問:如何進行過載保護?

回答:最簡易的方式,服務端設定一個負載閾值,超過這個閾值的請求壓過來,所有拋棄。這個方式不是特別優雅。

 

5、如何藉助「動態權重」來實施過載保護

動態權重是用來標識每一個service的處理能力的一個值,它是RPC-client客戶端鏈接池層面的一個東東。服務端處理超時,客戶端RPC-client鏈接池都可以知道,這裏只要實施一些策略,就可以對「疑似過載」的服務器進行降壓,而不用服務器「拋棄請求」這麼粗暴的實施過載保護。

 

應該實施一些什麼樣的策略呢,例如:

1)若是某一個service的鏈接上,連續3個請求都超時,即連續-10分三次,客戶端就能夠認爲,服務器慢慢的要處理不過來了,得給這個service緩一小口氣,因而設定策略:接下來的若干時間內,例如1秒(或者接下來的若干個請求),請求再也不分配給這個service;

2)若是某一個service的動態權重,降爲了0(像連續10個請求超時,中間休息了3次還超時),客戶端就能夠認爲,服務器徹底處理不過來了,得給這個service喘一大口氣,因而設定策略:接下來的若干時間內,例如1分鐘(爲何是1分鐘,根據經驗,此時service通常在發生fullGC,差很少1分鐘能回過神來),請求再也不分配給這個service;

3)能夠有更復雜的保護策略…

 

這樣的話,不但能借助「動態權重」來實施動態自適應的異構服務器負載均衡,還能在客戶端層面更優雅的實施過載保護,在某個下游service快要響應不過來的時候,給其喘息的機會。

 

須要注意的是:要防止客戶端的過載保護引發service的雪崩,若是「總體負載」已經超過了「service集羣」的處理能力,怎麼轉移請求也是處理不過來的,還得經過拋棄請求來實施自我保護。

 

6、總結

1)service的負載均衡、故障轉移、超時處理一般是RPC-client鏈接池層面來實施的

2)異構服務器負載均衡,最簡單的方式是靜態權重法,缺點是沒法自適應動態調整

3)動態權重法,能夠動態的根據service的處理能力來分配負載,須要有鏈接池層面的微小改動

4)過載保護,是在負載太高時,service爲了保護本身,保證必定處理能力的一種自救方法

5)動態權重法,還能夠用作service的過載保護

 

 

 

 

單點系統架構的可用性與性能優化

1、需求緣起

明明架構要求高可用,爲什麼系統中還會存在單點?

回答:單點master的設計,會大大簡化系統設計,況且有時候避免不了單點

 

在哪些場景中會存在單點?先來看一下一個典型互聯網高可用架構。


典型互聯網高可用架構:

(1)客戶端層,這一層是瀏覽器或者APP,第一步先訪問DNS-server,由域名拿到nginx的外網IP

(2)負載均衡層,nginx是整個服務端的入口,負責反向代理與負載均衡工做

(3)站點層,web-server層,典型的是tomcat或者apache

(4)服務層,service層,典型的是dubbo或者thrift等提供RPC調用的後端服務

(5)數據層,包含cache和db,典型的是主從複製讀寫分離的db架構

在這個互聯網架構中,站點層、服務層、數據庫的從庫均可以經過冗餘的方式來保證高可用,但至少

(1)nginx層是一個潛在的單點

(2)數據庫寫庫master也是一個潛在的單點

 

再舉一個GFS(Google File System)架構的例子。


GFS的系統架構裏主要有這麼幾種角色:

(1)client,就是發起文件讀寫的調用端

(2)master,這是一個單點服務,它有全局事業,掌握文件元信息

(3)chunk-server,實際存儲文件額服務器

這個系統裏,master也是一個單點的服務,Map-reduce系統裏也有相似的全局協調的master單點角色。

 

系統架構設計中,像nginx,db-master,gfs-master這樣的單點服務,會存在什麼問題,有什麼方案來優化呢,這是本文要討論的問題。

 

2、單點架構存在的問題

單點系統通常來講存在兩個很大的問題:

(1)非高可用:既然是單點,master一旦發生故障,服務就會受到影響

(2)性能瓶頸:既然是單點,不具有良好的擴展性,服務性能總有一個上限,這個單點的性能上限每每就是整個系統的性能上限

 

接下來,就看看有什麼優化手段能夠優化上面提到的兩個問題

 

3、shadow-master解決單點高可用問題

shadow-master是一種很常見的解決單點高可用問題的技術方案。

「影子master」,顧名思義,服務正常時,它只是單點master的一個影子,在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(virtual-IP)

 


當發現master異常時:

shadow-master會自動頂上成爲master,虛IP機制能夠保證這個過程對調用方是透明的

 

除了GFS與MapReduce系統中的主控master,nginx亦可用相似的方式保證高可用,數據庫的主庫master(主庫)亦可用相似的方式來保證高可用,只是細節上有些地方要注意:


傳統的一主多從,讀寫分離的db架構,只能保證讀庫的高可用,是沒法保證寫庫的高可用的,要想保證寫庫的高可用,也可使用上述的shadow-master機制:


(1)兩個主庫設置相互同步的雙主模式

(2)平時只有一個主庫提供服務,言下之意,shadow-master不會往master同步數據

(3)異常時,虛IP漂移到另外一個主庫,shadow-master變成主庫繼續提供服務

須要說明的是,因爲數據庫的特殊性,數據同步須要時延,若是數據尚未同步完成,流量就切到了shadow-master,可能引發小部分數據的不一致。

 

4、減小與單點的交互,是存在單點的系統優化的核心方向

既然知道單點存在性能上限,單點的性能(例如GFS中的master)有可能成爲系統的瓶頸,那麼,減小與單點的交互,便成了存在單點的系統優化的核心方向。

怎麼來減小與單點的交互,這裏提兩種常見的方法。

批量寫

批量寫是一種常見的提高單點性能的方式。

例如一個利用數據庫寫單點生成作「ID生成器」的例子:


(1)業務方須要ID

(2)利用數據庫寫單點的auto increament id來生成和返回ID

這是一個很常見的例子,不少公司也就是這麼生成ID的,它利用了數據庫寫單點的特性,方便快捷,無額外開發成本,是一個很是帥氣的方案。

潛在的問題是:生成ID的併發上限,取決於單點數據庫的寫性能上限。

如何提高性能呢?批量寫

 


(1)中間加一個服務,每次從數據庫拿出100個id

(2)業務方須要ID

(3)服務直接返回100個id中的1個,100個分配完,再訪問數據庫

這樣一來,每分配100個纔會寫數據庫一次,分配id的性能能夠認爲提高了100倍。

 

客戶端緩存

客戶端緩存也是一種下降與單點交互次數,提高系統總體性能的方法。

仍是以GFS文件系統爲例:


(1)GFS的調用客戶端client要訪問shenjian.txt,先查詢本地緩存,miss了

(2)client訪問master問說文件在哪裏,master告訴client在chunk3上

(3)client把shenjian.txt存放在chunk3上記錄到本地的緩存,而後進行文件的讀寫操做

(4)將來client要訪問文件,從本地緩存中查找到對應的記錄,就不用再請求master了,能夠直接訪問chunk-server。若是文件發生了轉移,chunk3返回client說「文件不在我這兒了」,client再訪問master,詢問文件所在的服務器。

 

根據經驗,這類緩存的命中很是很是高,可能在99.9%以上(由於文件的自動遷移是小几率事件),這樣與master的交互次數就下降了1000倍。

 

5、水平擴展是提高單點系統性能的好方案

不管怎麼批量寫,客戶端緩存,單點畢竟是單機,仍是有性能上限的。

千方百計水平擴展,消除系統單點,理論上纔可以無限的提高系統系統。

以nginx爲例,如何來進行水平擴展呢?


第一步的DNS解析,只能返回一個nginx外網IP麼?答案顯然是否認的,「DNS輪詢」技術支持DNS-server返回不一樣的nginx外網IP,這樣就能實現nginx負載均衡層的水平擴展。

 


DNS-server部分,一個域名能夠配置多個IP,每次DNS解析請求,輪詢返回不一樣的IP,就能實現nginx的水平擴展,擴充負載均衡層的總體性能。

 

數據庫單點寫庫也是一樣的道理,在數據量很大的狀況下,能夠經過水平拆分,來提高寫入性能。

 

遺憾的是,並非全部的業務場景均可以水平拆分,例如秒殺業務,商品的條數可能很少,數據庫的數據量不大,就不能經過水平拆分來提高秒殺系統的總體寫性能(總不能一個庫100條記錄吧?)。

 

6、總結

今天的話題就討論到這裏,內容不少,佔用你們寶貴的時間深表內疚,估計大部分都記不住,至少記住這幾個點吧:

(1)單點系統存在的問題:可用性問題,性能瓶頸問題

(2)shadow-master是一種常見的解決單點系統可用性問題的方案

(3)減小與單點的交互,是存在單點的系統優化的核心方向,常見方法有批量寫,客戶端緩存

(4)水平擴展也是提高單點系統性能的好方案

 

 

 

 

 

集羣信息管理,架構設計中最容易遺漏的一環

準備系統性介紹「技術體系規劃」了,這是第一篇。

 

監控平臺,服務治理,調用鏈跟蹤,數據收集中心,自動化運維,自動化測試… 不少要講,卻沒想好從哪裏入手。

 

講Z平臺,可能須要提早介紹Y服務;講Y服務,可能須要提早介紹X知識。

 

思來想去,準備從技術體系裏,最容易被遺漏,很是基礎,卻又很是重要的「集羣信息管理」開始介紹。

 

因爲基礎,可能部分同窗會以爲簡單;因爲你們所在公司處於不一樣階段,因此在實現上會介紹不一樣階段的公司應該如何來實現。

 

仍是一如既往的按照「架構師之路」的思路:

  • 是什麼

  • 什麼場景,爲何會用到,存在什麼問題

  • 常見方案及痛點

  • 不一樣階段公司,不一樣實現方案

但願大夥有收穫。

 

1、啥是集羣?

互聯網典型分層架構以下:

  • web-server層

  • service層

  • db層與cache層

 

爲了保證高可用,每個站點、服務、數據庫、緩存都會冗餘多個實例,組成一個分佈式的系統,集羣則是一個分佈式的物理形態。

 

額,好拗口,通俗的說,集羣就是一堆機器,上面部署了提供類似功能的站點,服務,數據庫,或者緩存。

如上圖:

  • web集羣,由web.1和web.2兩個實例組成

  • service集羣,由service.1/service.2/service.3三個實例組成

  • db集羣,由mysql-M/mysql-S1/mysql-S2三個實例組成

  • cache集羣,由cache-M/cache-S兩個實例組成

 

與「集羣」相對應的是「單機」。

畫外音:關於高可用架構,詳見文章《究竟啥纔是互聯網架構「高可用」》。

畫外音:緩存若是沒有高可用要求,多是單機架構,而不是集羣。

 

2、集羣信息

什麼是集羣信息?

一個集羣,會包含若干信息(額,這tm算什麼解釋),例如:

  • 集羣名稱

  • IP列表

  • 二進制目錄

  • 配置目錄

  • 日誌目錄

  • 負責人列表

畫外音:集羣IP列表不建議直接使用IP,而建議使用內網域名,詳見文章《小小的IP,大大的耦合》。

 

何時會用到集羣信息呢?

不少場景,特別是線上操做,都會使用到各類集羣信息,例如:

  • 自動化上線

  • 監控

  • 日誌清理

  • 二進制與配置的備份

  • 下游的調用(額,這個最典型)

 

這些場景,分別都是如何讀取集羣信息的?

通常來講,早期會把集羣信息寫在配置文件裏。

 

例如,自動化上線,有一個配置文件,deploy.user.service.config,其內容是:

name : user.service

ip.list : ip1, ip2, ip3

bin.path : /user.service/bin/

ftp.path : ftp://192.168.0.1/USER_2_0_1_3/user.exe

 

自動化上線的過程,則是:

  • 把可執行文件從ftp拉下來

  • 讀取集羣IP列表

  • 讀取二進制應該部署的目錄

  • 把二進制部署到線上

  • 逐臺重啓

畫外音:啥,尚未實現自動化腳本部署?還處在運維ssh到線上,手動執行命令,逐臺機器人肉部署的刀耕火種階段?趕忙照着這個方案,作自動化改造吧。

 

又例如,web-X調用下游的user服務,又有一個配置文件,web-X.config,其內容配置了:

service.name : user.service

service.ip.list : ip1, ip2, ip3

service.port : 8080

 

web-X調用user服務的過程,則是:

  • web-X啓動

  • web-X讀取user服務集羣的IP列表與端口

  • web-X初始化user服務鏈接池

  • web-X拿取user服務的鏈接,經過RPC接口調用user服務

 

日誌清理,服務監控,二進制備份的過程,也都與上述相似。

 

3、存在什麼問題?

上述業務場景,對於集羣信息的使用,有兩個最大的特色

  • 每一個應用場景,所需集羣信息都不同(A場景須要集羣abc信息,B場景須要集羣def信息)

  • 每一個應用場景,集羣信息都寫在「本身」的配置文件裏

 

一句話總結:集羣信息管理分散化。

 

這裏最大的問題,是耦合,當集羣的信息發生變化的時候,有很是多的配置須要修改:

  • deploy.user.service.config

  • clean.log.user.service.config

  • backup.bin.user.service.config

  • monitor.config

  • web-X.config

 

這些配置裏,user服務集羣的信息都須要修改:

  • 隨着研發、測試、運維人員的流動,不少配置放在哪裏,逐步就被遺忘了

  • 隨着時間的推移,一些配置就被改漏了

  • 逐漸的,莫名其妙的問題出現了

畫外音:ca,誰痛誰知道

 

如何解決上述耦合的問題呢?

一句話回答:集羣信息管理集中化。

 

4、如何集中化管理集羣信息

如何集中化管理集羣配置信息,不一樣發展階段的公司,實現的方式不同。

 

早期方案

經過全局配置文件,實現集羣信息集中管理,舉例global.config以下:

[user.service]

ip.list : ip1, ip2, ip3

port : 8080

bin.path : /user.service/bin/

log.path : /user.service/log/

conf.path : /user.service/conf/

ftp.path :ftp://192.168.0.1/USER_2_0_1_3/user.exe

owner.list : shenjian, zhangsan, lisi

 

[passport.web]

ip.list : ip11, ip22, ip33

port : 80

bin.path : /passport.web/bin/

log.path : /passport.web/log/

conf.path : /passport.web/conf/

ftp.path :ftp://192.168.0.1/PST_1_2_3_4/passport.jar

owner.list : shenjian, zui, shuaiqi

 

集中維護集羣信息以後:

  • 任何須要讀取集羣信息的場景,都從global.config裏讀取

  • 任何集羣信息的修改,只須要修改global.config一處

  • global.config會部署到任何一臺線上機器,維護和管理也很方便

畫外音:額,固然,信息太多的話,global.config也要垂直拆分

 

中期方案

隨着公司業務的發展,隨着技術團隊的擴充,隨着技術體系的完善,經過集羣信息管理服務,來維護集羣信息的訴求原來越強烈。

畫外音:慢慢的,配置太多了,經過global.config來修改配置太容易出錯了

如上圖,創建集羣信息管理服務

  • info.db :存儲集羣信息

  • info.cache :緩存集羣信息

  • info.service :提供集羣信息訪問的RPC接口,以及HTTP接口

  • info.web :集羣信息維護後臺

 

服務的核心接口是:

Info InfoService::getInfo(String ClusterName);

Bool InfoService::setInfo(String ClusterName, String key, String value);

 

而後,統一經過服務來獲取與修改集羣信息:

  • 全部須要獲取集羣信息的場景,都經過info.service提供的接口來讀取集羣信息

  • 全部須要修改集羣信息的場景,都經過info.web來操做

 

長期方案

集羣信息服務能夠解決大部分的耦合問題,但仍然有一個不足:集羣信息變動時,沒法反向實時通知關注方,集羣信息發生了改變。更長遠的,要引入配置中心來解決。

配置中心的細節,網上的分析不少,以前也撰文寫過,細節就再也不本文展開。

 

5、總結

集羣信息管理,是架構設計中很是容易遺漏的一環,但又是很是基礎,很是重要的基礎設施,必定要在早期規劃好:

  • 傳統的方式,分散化管理集羣信息,容易致使耦合

  • 集中管理集羣信息,有全局配置,信息服務,配置中心三個階段

 

6、調研

調研一、對於集羣信息管理,你的感覺是:

  • ca,沒考慮過這個問題,一直是分散式管理

  • 在使用全局配置文件

  • 在使用信息管理服務

  • 在使用配置中心

 

調研二、對於自動化運維,你的感覺是:

  • ca,啥是運維,都是研發在線上亂搞

  • 有專門的運維,但一直是人肉運維

  • 運維在使用腳本,實現了自動化

  • 運維都下崗了,在使用平臺,實現了平臺化

相關文章
相關標籤/搜索