掃二維碼與項(xiàng)目經(jīng)理溝通
我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流
作者:少強(qiáng) 2019-09-10 09:25:27
開發(fā)
架構(gòu)
服務(wù)器
分布式 分布式系統(tǒng)類型多,涉及面非常廣,不同類型的系統(tǒng)有不同的特點(diǎn),批量計(jì)算和實(shí)時(shí)計(jì)算就差別非常大。

分布式系統(tǒng)類型多,涉及面非常廣,不同類型的系統(tǒng)有不同的特點(diǎn),批量計(jì)算和實(shí)時(shí)計(jì)算就差別非常大。
這篇文章會(huì)重點(diǎn)討論分布式數(shù)據(jù)系統(tǒng)的設(shè)計(jì),比如分布式存儲(chǔ)系統(tǒng),分布式搜索系統(tǒng),分布式分析系統(tǒng)等。我們先來簡(jiǎn)單看下 Elasticsearch 的架構(gòu)。
Elasticsearch 集群架構(gòu)
Elasticsearch 是一個(gè)非常著名的開源搜索和分析系統(tǒng),目前被廣泛應(yīng)用于互聯(lián)網(wǎng)多種領(lǐng)域中。
尤其是以下三個(gè)領(lǐng)域特別突出:
Elasticsearch 的詳細(xì)介紹可以到官網(wǎng)查看。我們先來看一下 Elasticsearch 中幾個(gè)關(guān)鍵概念:
一個(gè)節(jié)點(diǎn)(Node)一般會(huì)管理多個(gè)分片,這些分片可能是屬于同一份索引,也有可能屬于不同索引,但是為了可靠性和可用性,同一個(gè)索引的分片盡量會(huì)分布在不同節(jié)點(diǎn)(Node)上。分片有兩種,主分片和副本分片。
如上圖,用圖形表示出來可能是這樣子的:
基于系統(tǒng)可用性的考慮,同一個(gè) Shard 的 Primary 和 Replica 不能位于同一個(gè) Node 中。
這里 Shard1 的 P1 和 R1 分別位于 Node3 和 Node2 中,如果某一刻 Node2 發(fā)生宕機(jī),服務(wù)基本不會(huì)受影響,因?yàn)檫€有一個(gè) P1 和 R2 都還是可用的。
因?yàn)槭侵鱾浼軜?gòu),當(dāng)主分片發(fā)生故障時(shí),需要切換,這時(shí)候需要選舉一個(gè)副本作為新主,這里除了會(huì)耗費(fèi)一點(diǎn)點(diǎn)時(shí)間外,也會(huì)有丟失數(shù)據(jù)的風(fēng)險(xiǎn)。
Index 流程
建索引(Index)的時(shí)候,一個(gè) Doc 先是經(jīng)過路由規(guī)則定位到主 Shard,發(fā)送這個(gè) Doc 到主 Shard 上建索引,成功后再發(fā)送這個(gè) Doc 到這個(gè) Shard 的副本上建索引,等副本上建索引成功后才返回成功。
在這種架構(gòu)中,索引數(shù)據(jù)全部位于 Shard 中,主 Shard 和副本 Shard 各存儲(chǔ)一份。
當(dāng)某個(gè)副本 Shard 或者主 Shard 丟失(比如機(jī)器宕機(jī),網(wǎng)絡(luò)中斷等)時(shí),需要將丟失的 Shard 在其他 Node 中恢復(fù)回來。
這時(shí)候就需要從其他副本(Replica)全量拷貝這個(gè) Shard 的所有數(shù)據(jù)到新 Node 上構(gòu)造新 Shard。
這個(gè)拷貝過程需要一段時(shí)間,這段時(shí)間內(nèi)只能由剩余主副本來承載流量,在恢復(fù)完成之前,整個(gè)系統(tǒng)會(huì)處于一個(gè)比較危險(xiǎn)的狀態(tài),直到 Failover 結(jié)束。
這里就體現(xiàn)了副本(Replica)存在的一個(gè)理由,避免數(shù)據(jù)丟失,提高數(shù)據(jù)可靠性。
副本(Replica)存在的另一個(gè)理由是讀請(qǐng)求量很大的時(shí)候,一個(gè) Node 無法承載所有流量,這個(gè)時(shí)候就需要一個(gè)副本來分流查詢壓力,目的就是擴(kuò)展查詢能力。
角色部署方式
接下來再看看角色分工的兩種不同方式:
Elasticsearch 支持上述兩種方式:
混合部署(如左圖):
這種部署模式下,這兩種不同類型 Node 角色都位于同一個(gè) Node 中,相當(dāng)于一個(gè) Node 具備兩種功能:Data 和 Transport。
這臺(tái) Node 中會(huì)持有一個(gè)全局的路由表,通過路由表選擇合適的 Node,將請(qǐng)求發(fā)送給這些 Node,然后等所有請(qǐng)求都返回后,合并結(jié)果,然后返回給用戶。一個(gè) Node 分飾兩種角色。
這種情況下,每個(gè) Node 都需要和其他所有 Node 保持連接,而一個(gè)系統(tǒng)的連接數(shù)是有上限的,這樣連接數(shù)就會(huì)限制集群規(guī)模。
分層部署(如右圖):
而 Data Node 由于處理數(shù)據(jù),很容易出現(xiàn)單機(jī)資源被占滿,比如 CPU,網(wǎng)絡(luò),磁盤等。
一個(gè)集群中 Data Node 的數(shù)量遠(yuǎn)大于 Transport Node,這樣集群的規(guī)??梢愿?。
另外,還可以通過分組,使 Transport Node 只連接固定分組的 Data Node,這樣 Elasticsearch 的連接數(shù)問題就徹底解決了。
上面介紹了 Elasticsearch 的部署層架構(gòu),不同的部署方式適合不同場(chǎng)景,需要根據(jù)自己的需求選擇適合的方式。
Elasticsearch 數(shù)據(jù)層架構(gòu)
接下來我們看看當(dāng)前 Elasticsearch 的數(shù)據(jù)層架構(gòu)。
數(shù)據(jù)存儲(chǔ)
Elasticsearch 的 Index 和 Meta,目前支持存儲(chǔ)在本地文件系統(tǒng)中,同時(shí)支持 niofs,mmap,simplefs,smb 等不同加載方式,性能最好的是直接將索引 LOCK 進(jìn)內(nèi)存的 mmap 方式。
默認(rèn),Elasticsearch 會(huì)自動(dòng)選擇加載方式,另外可以自己在配置文件中配置。這里有幾個(gè)細(xì)節(jié),具體可以看官方文檔。
索引和 Meta 數(shù)據(jù)都存在本地,會(huì)帶來一個(gè)問題:當(dāng)某一臺(tái)機(jī)器宕機(jī)或者磁盤損壞的時(shí)候,數(shù)據(jù)就丟失了。為了解決這個(gè)問題,可以使用 Replica(副本)功能。
副本(Replica)
可以為每一個(gè) Index 設(shè)置一個(gè)配置項(xiàng):副本(Replicda)數(shù),如果設(shè)置副本數(shù)為 2,那么就會(huì)有 3 個(gè) Shard,其中一個(gè)是 Primary Shard,其余兩個(gè)是 Replica Shard。
這三個(gè) Shard 會(huì)被 Mater 盡量調(diào)度到不同機(jī)器,甚至機(jī)架上,這三個(gè) Shard 中的數(shù)據(jù)一樣,提供同樣的服務(wù)能力。
副本(Replica)的目的有三個(gè):
問題
上面說了一些優(yōu)勢(shì),這種架構(gòu)同樣在一些場(chǎng)景下會(huì)有些問題。Elasticsearch 采用的是基于本地文件系統(tǒng),使用 Replica 保證數(shù)據(jù)可靠性的技術(shù)架構(gòu),這種架構(gòu)一定程度上可以滿足大部分需求和場(chǎng)景。
但是也存在一些遺憾:
上面介紹了 Elasticsearch 數(shù)據(jù)層的架構(gòu),以及副本策略帶來的優(yōu)勢(shì)和不足,下面簡(jiǎn)單介紹了幾種不同形式的分布式數(shù)據(jù)系統(tǒng)架構(gòu)。
分布式系統(tǒng)
基于本地文件系統(tǒng)的分布式系統(tǒng)
上圖中是一個(gè)基于本地磁盤存儲(chǔ)數(shù)據(jù)的分布式系統(tǒng)。Index 一共有 3 個(gè) Shard,每個(gè) Shard 除了 Primary Shard 外,還有一個(gè) Replica Shard。
當(dāng) Node 3 機(jī)器宕機(jī)或磁盤損壞的時(shí)候,首先確認(rèn) P3 已經(jīng)不可用,重新選舉 R3 位 Primary Shard,此 Shard 發(fā)生主備切換。然后重新找一臺(tái)機(jī)器 Node 7,在 Node 7 上重新啟動(dòng) P3 的新 Replica。
由于數(shù)據(jù)都會(huì)存在本地磁盤,此時(shí)需要將 Shard 3 的數(shù)據(jù)從 Node 6 上拷貝到 Node 7 上。
如果有 200G 數(shù)據(jù),千兆網(wǎng)絡(luò),拷貝完需要 1600 秒。如果沒有 Replica,則這 1600 秒內(nèi)這些 Shard 就不能服務(wù)。
為了保證可靠性,就需要冗余 Shard,會(huì)導(dǎo)致更多的物理資源消耗。這種思想的另外一種表現(xiàn)形式是使用雙集群,集群級(jí)別做備份。
在這種架構(gòu)中,如果你的數(shù)據(jù)是在其他存儲(chǔ)系統(tǒng)中生成的,比如 HDFS/HBase,那么你還需要一個(gè)數(shù)據(jù)傳輸系統(tǒng),將準(zhǔn)備好的數(shù)據(jù)分發(fā)到相應(yīng)的機(jī)器上。
這種架構(gòu)中為了保證可用性和可靠性,需要雙集群或者 Replica 才能用于生產(chǎn)環(huán)境,優(yōu)勢(shì)和副作用在上面介紹 Elasticsearch 的時(shí)候已經(jīng)介紹過了,這里就不贅述了。Elasticsearch 使用的就是這種架構(gòu)方式。
基于分布式文件系統(tǒng)的分布式系統(tǒng)
針對(duì)第一種架構(gòu)中的問題,另一種思路是:存儲(chǔ)和計(jì)算分離。
第一種思路的問題根源是數(shù)據(jù)量大,拷貝數(shù)據(jù)耗時(shí)多,那么有沒有辦法可以不拷貝數(shù)據(jù)?
為了實(shí)現(xiàn)這個(gè)目的,一種思路是底層存儲(chǔ)層使用共享存儲(chǔ),每個(gè) Shard 只需要連接到一個(gè)分布式文件系統(tǒng)中的一個(gè)目錄/文件即可,Shard 中不含有數(shù)據(jù),只含有計(jì)算部分。
相當(dāng)于每個(gè) Node 中只負(fù)責(zé)計(jì)算部分,存儲(chǔ)部分放在底層的另一個(gè)分布式文件系統(tǒng)中,比如 HDFS。
上圖中,Node 1 連接到第一個(gè)文件;Node 2連接到第二個(gè)文件;Node 3 連接到第三個(gè)文件。
當(dāng) Node 3 機(jī)器宕機(jī)后,只需要在 Node 4 機(jī)器上新建一個(gè)空的 Shard,然后構(gòu)造一個(gè)新連接,連接到底層分布式文件系統(tǒng)的第三個(gè)文件即可,創(chuàng)建連接的速度是很快的,總耗時(shí)會(huì)非常短。
這種是一種典型的存儲(chǔ)和計(jì)算分離的架構(gòu),優(yōu)勢(shì)有以下幾個(gè)方面:
這種架構(gòu)同時(shí)也有一個(gè)不足:訪問分布式文件系統(tǒng)的性能可能不及訪問本地文件系統(tǒng)。
在上一代分布式文件系統(tǒng)中,這是一個(gè)比較明顯的問題,但是目前使用了各種用戶態(tài)協(xié)議棧后,這個(gè)差距已經(jīng)越來越小了。HBase 使用的就是這種架構(gòu)方式,Solr 也支持這種形式的架構(gòu)。
總結(jié)
上述兩種架構(gòu),各有優(yōu)勢(shì)和不足,對(duì)于某些架構(gòu)中的不足或缺陷,思路不同,解決的方案也大相徑庭,但是思路跨度越大,收益一般也越大。
上面只是介紹了分布式數(shù)據(jù)(存儲(chǔ)/搜索/分析等等)系統(tǒng)在存儲(chǔ)層的兩種不同架構(gòu)方式,希望能對(duì)大家有用。
但是分布式系統(tǒng)架構(gòu)設(shè)計(jì)所涉及的內(nèi)容廣,細(xì)節(jié)多,權(quán)衡點(diǎn)眾,如果大家對(duì)某些領(lǐng)域或者方面有興趣,也可以留言,后面再探討。

我們?cè)谖⑿派?4小時(shí)期待你的聲音
解答本文疑問/技術(shù)咨詢/運(yùn)營(yíng)咨詢/技術(shù)建議/互聯(lián)網(wǎng)交流