讲一点分布式的基础知识,图解!
故事還是得從單機(jī)開(kāi)始,沒(méi)有單機(jī)哪兒來(lái)的分布式?
在IT世界,二進(jìn)制的數(shù)據(jù)是我們最寶貴的資產(chǎn),必須要把它保存在斷電也不怕的硬盤上。
但是只用一塊硬盤很危險(xiǎn),萬(wàn)一壞了數(shù)據(jù)就徹底沒(méi)了。于是人們就想了個(gè)辦法,把兩塊硬盤組織了起來(lái),互為備份。
這種方式有個(gè)專門的術(shù)語(yǔ),叫RAID ,就是冗余磁盤陣列的意思。
上圖中兩個(gè)磁盤互為備份,是RAID 1 , 數(shù)據(jù)會(huì)被同時(shí)寫到兩塊硬盤中,安全性大大提高。
需要提醒的是,雖然這里有兩塊硬盤,但是從用戶角度,只能看到一個(gè)邏輯的硬盤,操作系統(tǒng)已經(jīng)把底層的兩塊硬盤給隱藏了。
RAID 1 的不爽之處是浪費(fèi)了一個(gè)硬盤的容量, 改進(jìn)方案可以用RAID 5:
RAID5 并沒(méi)有像RAID 1那樣對(duì)數(shù)據(jù)做備份, 它引入了一個(gè)叫做奇偶校驗(yàn)的東西(上圖的黃色部分),? 這樣當(dāng)一個(gè)磁盤壞的時(shí)候,就可以利用其它磁盤的數(shù)據(jù)進(jìn)行恢復(fù)。
?
具體的計(jì)算如下(略繁瑣,可以跳過(guò))。
奇偶校驗(yàn)是用異或(xor)來(lái)實(shí)現(xiàn)的,簡(jiǎn)單的說(shuō),相同為0,不同為
?
比如, 磁盤1保存 的數(shù)值是7(二進(jìn)制?0111), 磁盤2 保存的是數(shù)值是8(二進(jìn)制1000), 做一個(gè)xor操作
0111 xor 1000 ?=> 1111
那磁盤3保存的值就是二進(jìn)制1111。
現(xiàn)在假設(shè)磁盤2壞掉了,換了個(gè)新磁盤,那根據(jù)磁盤1 中的 0111 和磁盤3中的1111,就可以計(jì)算出磁盤2的值是:
0111 xor 1111 => ?1000
于是磁盤2的值就可以恢復(fù)了!
但是, 如果在恢復(fù)的時(shí)候,又有一個(gè)盤壞掉了,那就悲催了。
使用RAID 5,寫入時(shí)需要做計(jì)算,性能受到一定影響。
?
聰明的你肯定可以想到,除了RAID 1, 5, 還有其他方式, 例如RAID 0, 2,3,6,7, 5E 等,八仙過(guò)海,各顯神通。
主從備份
但是在互聯(lián)網(wǎng)應(yīng)用中,RAID用的越來(lái)越少了,更常用的是跨越機(jī)器的備份。
?
這種方式不會(huì)把數(shù)據(jù)分散地寫到各個(gè)機(jī)器的硬盤中,而是整體地寫到一個(gè)機(jī)器中,然后整體地復(fù)制到其他機(jī)器。
由于跨越了網(wǎng)絡(luò),這種備份通常是異步的。
副本多了,還帶來(lái)了一個(gè)好處,可以把讀操作發(fā)到副本機(jī)器上去讀,主庫(kù)只負(fù)責(zé)寫操作, 壓力就降低了。
這就是常見(jiàn)的MySQL主從復(fù)制,讀寫分離。
可是,由于時(shí)間差的關(guān)系, 副本的數(shù)據(jù)可能會(huì)落后于主庫(kù), 產(chǎn)生讀寫不一致的問(wèn)題,需要程序員想辦法來(lái)解決。
(注:具體的復(fù)制細(xì)節(jié),請(qǐng)移步《MySQL:硬盤在24 * 7工作中罷工了,我該怎么辦?》)
分區(qū)
備份問(wèn)題解決了, 如果你的數(shù)據(jù)越來(lái)越多,馬上就會(huì)面對(duì)另外一個(gè)問(wèn)題:一個(gè)機(jī)器無(wú)論如何也放不下了,怎么辦?
解決辦法就是分區(qū), 把邏輯上是整體的數(shù)據(jù),分別存儲(chǔ)到不同的物理機(jī)器上去。
(不同的系統(tǒng)稱呼不同,Elasticsearch 把它稱為Shard,即分片, HBase把他稱為Region)
可以這么分:
每個(gè)機(jī)器保存一段數(shù)據(jù),?Redis的Cluster就采用了類似的方式,每個(gè)服務(wù)器負(fù)責(zé)一段Hash槽。
?
還可以這么分:
這種方式稱為Round-Robin ,也是Kafka默認(rèn)的分區(qū)策略
Elasticsearch 則采用了另外一種辦法:余數(shù)算法
?
余數(shù)算法簡(jiǎn)單明了, 非常容易確定一個(gè)數(shù)據(jù)保存在哪個(gè)機(jī)器上, 存取都非常地方便。
但是弱點(diǎn)也非常明顯:如果數(shù)據(jù)更多了,想增加分區(qū)怎么辦?
對(duì)不起,增加不了!?因?yàn)橐坏┰黾臃謪^(qū),余數(shù)就會(huì)發(fā)生變化,數(shù)據(jù)就找不到了。
分區(qū)+備份
僅僅把數(shù)據(jù)做了分區(qū)還不夠,如果分區(qū)所在的節(jié)點(diǎn)如果壞了,數(shù)據(jù)就丟了。
為了可靠性,數(shù)據(jù)必須得有備份,像這樣:
?
?
每個(gè)機(jī)器上都有一個(gè)分區(qū)的主副本,每個(gè)主副本都有兩個(gè)從副本(保存在不同的機(jī)器上),數(shù)據(jù)安全多了。
這是個(gè)非常常見(jiàn)的復(fù)制方式,Kafka和Elastic search 都在使用,需要注意的是:復(fù)制的最小單位是分區(qū),而不是節(jié)點(diǎn)。
比如機(jī)器1掛掉了, 分區(qū)1的主副本丟掉了, 不用怕, 分區(qū)1還有兩個(gè)從副本,分別保存在機(jī)器2和機(jī)器3上, 可以從他們那里去讀數(shù)據(jù)。
問(wèn)題是現(xiàn)在有兩個(gè)從副本,他們都想當(dāng)主副本,承擔(dān)起主副本的職責(zé),到底誰(shuí)來(lái)當(dāng)?
這是個(gè)非常麻煩的問(wèn)題,把問(wèn)題抽象一下:這相當(dāng)于在一個(gè)分布式環(huán)境下(通常有著不可靠的網(wǎng)絡(luò)),各個(gè)節(jié)點(diǎn)要達(dá)成共識(shí):同意一個(gè)節(jié)點(diǎn)當(dāng)老大。
解決這個(gè)問(wèn)題,必須要利用一些共識(shí)算法(Raft, Paxos 等), ?這些算法都很復(fù)雜,可以自己去實(shí)現(xiàn),但是最好還是利用現(xiàn)成的組件,例如Zookeeper,讓這個(gè)穩(wěn)定可靠的“黑盒子”來(lái)幫忙吧。
總結(jié)
以上是生活随笔為你收集整理的讲一点分布式的基础知识,图解!的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一次服务器CPU占用率高的定位分析
- 下一篇: 从工具到社区,美图秀秀大规模性能优化实践