一、為什么要采用混合云的架構
在過去很長的時間內,大部分稍大些的互聯網系統包括微博都是基于私有體系的架構,可以在某種程度理解成私有云系統。混合云,顧名思義就是指業務同時部署在私有云和公有云,并且支持在云之間切換。實際上“為什么要采用混合云”這個問題,就等于“為什么要上公有云”。我們的考慮點主要有四個方面
業務場景
隨著微博活躍度的提升,以及push常規化等運營刺激,業務應對短時極端峰值挑戰,主要體現在兩個方面:
時間短,業務需要應對分鐘級或者小時級。
高峰值,例如話題經常出現10到20倍流量增長。
成本優勢
對于短期峰值應對,常規部署,離線計算幾個場景,我們根據往年經驗進行成本對比發現公有云優勢非常明顯
效率優勢
公有云可以實現5分鐘千級別節點的彈性調度能力,對比我們目前的私有云5分鐘百級別節點的調度能力,也具有明顯優勢。
業界趨勢
“Amazon首次公布AWS業績:2014年收入51.6億美元,2015年1季度AWS收入15.7億美元,年增速超40%。”“阿里巴巴旗下云計算業務阿里云營收6.49億元,比去年同期增長128%,超越亞馬遜和微軟的云計算業務增速,成為全球增速最快的云計算服務商。”
我們預計未來產品技術架構都會面臨上云的問題,只是時間早晚問題。
安全性
基于數據安全的考慮,我們現階段只會把計算和緩存節點上云,核心數據還放在私有云;另外考慮到公有云的技術成熟度,需要支持在多個云服務直接進行業務靈活遷移。
基于上述幾點考慮,我們今年嘗試了以私有云為主,公有云為輔的混合云架構。核心業務的峰值壓力,會在公有云上實現,業務部署形態可參考下圖
下面介紹介紹技術實現。整體技術上采用的是Docker Machine + Swarm + Consul的框架。系統分層如下圖
二、跨云的資源管理與調度
跨云的資源管理與調度(即上圖中的pluto部分)的作用是隔離云服務差異,對上游交付統一的Docker運行環境,支持快速彈性擴縮容及跨云調度。功能上主要包括:
系統初始化
元數據管理
鏡像服務
網絡
云服務選型
命令行工具
其他
系統界面如下圖:
系統初始化
最初技術選型時認為Machine比較理想,僅需要SSH通道,不依賴任何預裝的Agent。我們也幾乎與阿里云官方同時向Docker Machine社區提交了Driver的PR,然后就掉進了大坑中不能自拔。
例舉幾個坑:
無法擴展,Machine的golang函數幾乎都是小寫,即內部實現,無法調用其API進行功能擴展。
不支持并發,并發創建只能通過啟動多個Machine進程的方式,數量多了無法承載。
不支持自定義,Machine啟動Docker Daemon是在代碼中寫死的,要定義Daemon的參數就非常ugly。
目前我們采用的是Puppet的方案,采用去Master的結構。配置在GitLab上管理,變更會通過CI推送到pluto系統,然后再推送到各實例進行升級。在基礎資源層面,我們目前正在進行大范圍基礎環境從CentOS 6.5升級到CentOS 7的工作。做這個升級的主要原因是由于上層基于調度系統依賴Docker新版本,而新版本在CentOS 6.5上會引發cgroup的bug,導致Kernel Panic問題。
元數據的管理
調度算法需要根據每個實例的情況進行資源篩選,這部分信息目前是通過Docker Daemon的Label實現的,這樣做的好處是資源和調度可以Docker Daemon解耦。例如我們會在Daemon上記錄這個實例的歸屬信息:
—label idc=$provider #記錄云服務提供商
—label ip=$eth0 #記錄ip信息
—label srv=$srv #記錄所屬業務
—label role=ci/test/production…
…
目前Docker Daemon最大的硬傷是任何元數據的改變都需要重啟。所以我們計劃把元數據從Daemon遷移到我們的系統中,同時嘗試向社區反饋這個問題,比如動態修改Docker Daemon Label的接口(PR被拒,官方雖然也看到了問題,但是比較糾結是否要支持API方式),動態修改registry(PR被拒,安全因素),動態修改 Docker Container Expose Port(開發中)。
鏡像服務
為了提升基礎資源擴縮容的效率,我們正在構建虛機鏡像服務。參考Dockerfile的思路,通過描述文件定義定義虛機的配置,支持繼承關系,和簡單的初始化指令。通過預先創建好的鏡像進行擴縮容,可以節省大約50%的初始化時間。
描述文件示意如下:
centos 7.0:
– dns: 8.8.8.8
– docker:
– version: 1.6
– net: host
meta:
– service: $SRV
puppet:
– git: git.intra.weibo.com/docker/puppet/tags/$VERSION
entrypoint:
– init.sh
不過虛機鏡像也有一些坑,例如一些云服務會在啟動后自行修改一部分配置,例如router, dns, ntp, yum等配置。這就是上面entrypoint的由來,部分配置工作需要在實例運行后進行。
網絡
網絡的互聯互通對業務來說非常關鍵,通常來說有三種方案:公網,VPC+VPN,VPC+專線。公網因為性能完全不可控,而且云服務通常是按照出帶寬收費,所以比較適合相互通信較少的業務場景。VPC+VPN實際鏈路也是通過公網,區別是安全性更好,而且可以按照私有云的IP段進行網絡規劃。專線性能最好,但是價錢也比較好,且受運營商政策影響的風險較大。
網絡上需要注意的是包轉發能力,即每秒可以收發多少個數據包。一些云服務實測只能達到10萬的量級,而且與CPU核數、內存無 關。也就是說你花再多的錢,轉發能力也上不去。猜測是云廠商出于安全考慮在虛機層面做了硬性限制。我們在這上面也中過槍,比如像Redis主從不同步的問題等等。建議對于QPS壓力比較重的實例進行拆分。
云服務選型
我們主要使用的是虛機和軟負載兩種云服務。因為微博對緩存服務已經構建一套高可用架構,所以我們沒有使用公有云的緩存服務,而是在虛機中直接部署緩存容器。
虛機的選型我們重點關注CPU核數,內存,磁盤幾個方面。CPU調度能力,我們測試總結公有云是私有云的1.2倍,即假設業務在私有云上需要6個核,在公有云上則需要8個。
內存寫入速度和帶寬都不是問題,我們測試發現甚至還好于私有云,MEMCPY的帶寬是私有云的1.2倍,MCBLOCK是1.7倍。所以內存主要考慮的是價錢問題。
磁盤的性能也表現較好,順序讀寫帶寬公有云是私有云的1.4倍,隨機寫是1.6倍。唯一要注意的是對于Redis這種業務,需要使用I/O優化型的虛機。
以上數據僅供參考,畢竟各家情況不一樣,我們使用的性能測試工具:sysbench, mbw, fio,可自行測試。
CLI客戶端(命令行工具)
為了伺候好工程師們,我們實現了簡單的命令行客戶端。主要功能是支持創建Docker容器(公有云或私有云),支持類SSH登陸。因為我們要求容器本身都不提供SSH(安全考慮),所以我們是用Ruby通過模擬docker client的exec命令實現的,效果如下圖:
其他方面
跨域的資源管理和調度還有很多技術環節需要處理,比如安全,基礎設施(DNS、YUM等),成本核算,權限認證,由于這部分通用性不強,這里就不展開了。
三、容器的編排與服務發現
提到調度就離不開發現,Swarm是基于Consul來做節點發現的。Consul采用raft協議來保證server之間的數據一致性,采用 gossip協議管理成員和傳播消息,支持多數據中心。Consul集群中的所有請求都會重定向到server,對于非leader的server會將寫請求轉發給leader處理。
Consul對于讀請求支持3種一致性模式:
default :給leader一個time window,在這個時間內可能出現兩個leader(split-brain情況下),舊的leader仍然支持讀的請求,會出現不一致的情況。
consistent :完全一致,在處理讀請求之前必須經過大多數的follower確認leader的合法性,因此會多一次round trip。
stale :允許所有的server支持讀請求,不管它是否是leader。
我們采用的是default模式。
除了Swarm是基于Consul來做發現,業務直接也是通過Consul來做發現。我們服務采用Nginx來做負載均衡,開源社區的方案例如 Consul Template,都需要進行reload操作,而reload過程中會造成大量的失敗請求。我們現在基于Consul實現了一個nginx- upsync-module。
Nginx僅需在upstream配置中聲明Consul集群即可完成后端服務的動態發現
upstream test {
# fake server otherwise ngx_http_upstream will report error when startup
server 127.0.0.1:11111;
# all backend server will pull from consul when startup and will delete fake server
consul 127.0.0.1:8500/v1/kv/upstreams/test update_timeout=6m update_interval=500ms strong_dependency=off;
upstream_conf_path /usr/local/nginx/conf/upstreams/upstream_test.conf;
}
這個模塊是用C語言實現的,效率已經經過線上驗證,目前驗證在20W QPS壓力沒有問題。而且這個模塊代碼已經開源在Github上,也歡迎大家提Issue:https://github.com/weibocom/nginx-upsync-module。
下圖是我們做的幾種方案的性能對比:
當然我們的RPC框架motan也會支持Consul,實現機制同樣也是利用Consul的long polling機制,等待直到監聽的X-Consul-Index位置發生變化,這個功能已經在我們內網驗證通過,不過由于依賴整個motan框架,所以目前還沒有開源。
Consul的監控
由于Consul處于系統核心位置,一旦出現問題會導致整體所有集群失聯,所以我們對Consul做了一系列保障措施,其中所有Consul Server節點監控指標如下
Leader節點監控指標如下圖
Consul的坑
除了使用不當導致的問題之外,Consul Server節點通信通道UDP協議,偶發會出現server不停被摘除的現象,這個問題官方已在跟進,計劃會增加TCP的通道保證消息的可靠性。
容器調度
容器調度基于Swarm實現,依賴Consul來做節點發現(話說Swarm才剛剛宣布Production Ready)。容器調度分為三級,應用-應用池-應用實例,一個應用下有多個應用池,應用池可以按機房和用途等來劃分。一個應用池下有多個Docker容器形式的應用實例。
我們利用Swarm的Filter機制,實現了適應業務的調度算法。整個調度過程分為兩步:主機過濾:指定機房、內存、CPU、端口等條件,篩選出符合條件的主機集合;策略選擇:對符合條件的主機集合進行打分,選擇出最合適的主機,在其上創建容器以部署應用。調度子系統Roam實現了批量的容器調度與編排。
業務調度
容器調度是于業務無關,具體串聯起資源管理,容器調度,發現等系統,完成業務容器最終跨云部署的是我們的JPool系統。JPool除了完成日常的業務容器上線發布之外,最重要的是完成動態擴縮容功能,使業務實現一鍵擴容、一鍵縮容,降低快速擴容成本。一次擴容操示意圖如下
圍繞這調度和發現,需要很多工具的支撐:
例如為了使業務接入更加方便,我們提供了自動打包工具,它包括代碼打包、鏡像打包的解決方案,支持svn、gitlab等代碼倉庫,業務僅需要在工程中定義pom.xml和Dockerfile即可實現一鍵打包代碼,一鍵打包鏡像,過程可控,接入簡單。
我們還對Docker的Registry,我們進行了一些優化,主要是針對混合云跨機房場景,提供跨機房加速功能,整個服務架構如下:
四、混合云監控體系
微博體系在經歷了多年的IT建設過程后,已經初步建立了一套完整的信息化管理流程,極大地提升了微博業務能力。同時微博開展了大量的IT基礎設施建設(包括網絡、機房、服務器、存儲設置、數據庫、中間件及各業務應用系統等)。
針對于混合云體系,我們提供了一套完整的監控告警解決方案,實現對于云上IT基礎架構的整體監控與預警機制,最大程度地保證了微博體系能夠穩定地運行在混合云體系上,不間斷地為用戶提供優質的服務。監控告警解決方案實現了四個級別上的監控與預警:
系統級監控
業務級監控
資源級監控
專線網絡監控
系統級監控
混合云體系支持的系統級監控(與新浪sinawatch系統的對接)包括:CPU,磁盤,網卡,IOPS,Load,內存
業務監控
混合云體系集成了目前微博業務監控平臺Graphite,自動提供了業務級別(SLA)的實時監控與告警。所有的配置與操作都是系統自動完成的,不需要用戶進行額外的配置操作。
業務級別的監控包括:
JVM監控: 實時監控堆、棧使用信息、統計gc收集時間、檢查JVM瓶頸等。
吞吐量監控: 實時監控業務系統吞吐量(QPS或TPS)。
平均耗時監控: 實時監控業務系統接口的平均耗時時間。
單機性能監控: 實時監控單臺服務器的各種業務指標。
Slow監控: 監控服務器集群,實時顯示當前業務系統中最慢的性能瓶頸。
資源監控
混合云體系集成了目前微博資源監控平臺sinadsp,自動提供了對各種底層資源的實時監控與告警。所有的配置與操作都是系統自動完成的,不需要用戶進行額外的配置操作。
具體的監控指標包括:命中率,QPS/TPS,連接數,上行/下行帶寬,CPU,內存。
五、前進路上遇到的那些坑
需要注意的坑,實際在各部分中都有提及。今天分享的主要內容就是這些了,當然業務上云,除了上面這些工作之外,還存在很多技術挑戰要解決。比如跨云的消息總線,緩存數據同步,容量評估,流量調度,RPC框架,微服務化等。
Q&A
Q1 : 為什么選Consul?看中有對比Zookeeper、etcd,尤其是etcd?
我們有對比etcd和consul,主要還是看重了consul基于K-V之外額外功能,比如支持DNS,支持ACL。另外etcd不對get request做超時處理,Consul對blocking query有超時機制。
Q2 : 上面提到的方案主要是Java體系, 對于其他語言(php, nodejs, golang)體系系統的是否有很好的支持(開發、測試、發布部署、監控等)?
已經在開始php的支持。其實容器化之后,所有語言都是適用的。
Q3 : Docker registry底層存儲用的是什么,怎么保障高可用的?
底層使用的Ceph,前端無狀態,通過DNS做跨云智能解析,加速下載。
Q4 : Consul temple reload nginx時為什么會造成大量請求失敗呢,不是graceful的嗎?
是graceful的,在QPS壓力較大的情況下,由于需要進行大量重連,過程中會產生較多失敗請求。
Q5 : 剛才提到的調度系統是自己開發的?還是基于開源改的?
是基于Swarm二次開發的。
Q6 : 容器跨主機通信是host網絡嗎?
對,目前線上采用的是host網絡。
Q7 : Ceph IO情況怎么?高IO的是不是不太適合用Ceph?
針對Registry場景Ceph IO是可以勝任的。不過Ceph暫時還沒有宣布Production Ready,所以對于極端業務場景,請謹慎。
關于作者
微博研發中心技術經理及高級技術專家。2008年畢業于北京郵電大學,碩士學位。畢業后就職華為北研。2012年加入新浪微博,負責微博Feed、用戶關 系和微博容器化相關項目,致力于Docker技術在生產環境中的規模化應用。2015年3月,曾在QClub北京Docker專場分享《大規模 Docker集群助力微博迎接春晚峰值挑戰》。