1. 引言
今天有朋友問萌叔,consul能否在大規模生產環境下進行應用。場景是總計大約10w+台機器,分為3 ~ 4個機房,單個機房最多3w萬+機器。這個問題大的,可把萌叔嚇了跳,部門里面consul集群的規模也就是1k+, 還分好幾個機房。
不過他的問題確實也讓我十分好奇,consul是否有能力支撐這么規模,我決定針對每個可能性能瓶頸進行定量分析
2. 分析
在進行分析前,我們來看看可能遇到瓶頸有哪些?
下圖是consul在多DC情況下的體系架構圖
2.1 明確一些概念
- consul agent分2種模式server模式和client模式。在每個機房
consul server
(以下簡稱為server
)會部署3 ~ 5台, 其余的consul節點都是consul client
(以下簡稱為server
)。server
的數量不宜過多,否則選主的速度會變慢 - 數據(包括kv數據,service信息,node信息)都是分機房存儲的,由所在機房的
server
負責。如果需要請求其它機房的數據,則server
會將請求轉發到對應的機房。
比如dc1的某個應用app1
想要獲取dc2中key “hello”對應的值
過程如下
app1 --> client --> server(dc1) --> server(dc2)
如果讀者仔細觀察會發現,consul中,很多api都是可以加上dc參數的
consul kv get hello -datacenter dc2
- 每個dc的所有
server
構成一個raft集群,client不參與選主。注意上圖的leader
和follower
標識。 - 單個機房內部consul節點之間有gossip(端口8301)
- 機房與機房之間
server
節點之間有gossip(端口8302)
2.2 可能的瓶頸
2.2.1 client對server的RPC請求
client使用server的TCP/8300端口發起RPC請求, 管理service、kv都要通過這個端口,它們之間是長連接。
1個機房如果有3w+機器,則client和server至少要建立3w+長連接。
不過萌叔觀察了一下,3w+長連接是相對均勻的分布在多個server
上的,也就是說如果你有6台consul server
, 那么每個server
最多處理5k個長連接。還是可以接收的。
對於server
的處理能力我簡單壓測了一下。大約是15k qps
Intel(R) Xeon(R) CPU E5-2650 v3 @ 2.30GHz
4核CPU 8G內存
╰─$ wrk -t10 -c500 -d30s http://dev2:8500/v1/health/service/consul
Running 30s test @ http://dev2:8500/v1/health/service/consul
10 threads and 500 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 33.15ms 17.65ms 209.29ms 77.50%
Req/Sec 1.56k 330.91 2.46k 66.33%
464810 requests in 30.03s, 1.06GB read
Requests/sec: 15476.11
Transfer/sec: 36.31MB
如果只是把consul作為注冊中心,client
與server
主要是long polling
,假定1分鍾1個請求、1000個微服務、3w台機器、5個server
30000 * 1000 / 60 / 5 = 100,000
server
如果不做擴容,可能有風險
2.2.2 Lan Gossip
很多人會擔心局域網內部的Gossip帶來的網絡風暴。
- 筆者抓包看了一下,雖然consul節點同時監聽TCP和UDP的8301端口,但實際上Gossip的數據包都是UDP包。每秒只有幾個。
- Gossip包分為2類,一類是probe探針用於探活,一類是push/pull 用於交換信息
- 來看一下Gossip的默認參數
GossipLANGossipInterval 200ms // push/pull間隔
GossipLANGossipNodes 3 // push/pull選擇的node數量
GossipLANProbeInterval 1s // probe間隔,其實probe node數量為1
GossipWANGossipInterval 500ms
GossipWANGossipNodes 3
所以QPS是各位數,對性能沒有影響
參考筆者的文章 聊聊GOSSIP的一個實現
2.2.3 跨DC的RPC請求
這個可能是大問題,每個跨DC的RPC請求,將會導致本機房的server
和目標機房的server
各處理一個請求,請求壓力相當於翻倍。不過還好可以通過水平擴展server
來解決