一個(gè)企業(yè)級(jí)高并發(fā)短鏈接服務(wù)項(xiàng)目分享
這個(gè)項(xiàng)目我在企業(yè)做過(guò)的一個(gè)高并發(fā)服務(wù),功能很簡(jiǎn)單,但有很多技術(shù)難點(diǎn)和技術(shù)細(xì)節(jié)。沒(méi)有做過(guò)企業(yè)級(jí)項(xiàng)目的同學(xué)可以好好看看,想想怎么挖掘自己項(xiàng)目的亮點(diǎn)。也歡迎各位同學(xué)跟我討論,大家理解透徹后,完全可以實(shí)操一下這個(gè)項(xiàng)目,寫(xiě)在簡(jiǎn)歷中。
1 目標(biāo)
生產(chǎn)級(jí)別的互聯(lián)網(wǎng)應(yīng)用的架構(gòu)、設(shè)計(jì)思路、原理及調(diào)優(yōu)、演進(jìn)思路。
涉及到三高:高可用、高性能、高并發(fā)。
廣度和深度覆蓋全面,能夠全面體現(xiàn)出程序員的能力水平。
2 使用場(chǎng)景
電商推廣:短信、郵件
一般來(lái)說(shuō),一條短信最多70個(gè)漢字,140個(gè)字節(jié)。如果超出一般會(huì)被運(yùn)營(yíng)商自動(dòng)拆分為2條短信,增加了運(yùn)營(yíng)成本。
社交網(wǎng)絡(luò)分享:微博和Twitter都有140字?jǐn)?shù)的限制,如果分享一個(gè)長(zhǎng)鏈接,很容易就超出限制。短鏈接服務(wù)可以把一個(gè)長(zhǎng)鏈接變成短鏈接,方便在社交網(wǎng)絡(luò)上傳播。
3 真實(shí)案例
我們看到短信里面的URI是數(shù)字加子母組成的字符,跟我們平時(shí)寫(xiě)代碼時(shí)的URI不太一樣。
實(shí)際上這就是一個(gè)短鏈接,其實(shí)原始的內(nèi)部長(zhǎng)鏈接可能長(zhǎng)這樣:
https://dpubstatic.udache.com/static/dpubimg/d4c0e518e95afb4e669affa6eb15d1d6/index.html
3.1 工作流程
用戶點(diǎn)擊這個(gè)短鏈接后,會(huì)跳轉(zhuǎn)到內(nèi)部的長(zhǎng)鏈接?;玖鞒虉D:
客戶端-->發(fā)出短鏈接請(qǐng)求--> 重定向跳轉(zhuǎn)--->長(zhǎng)鏈接
3.1.1 為什么使用302重定向
301 | 永久 | 第一次會(huì)重定向,下次直接從瀏覽器緩存拿到長(zhǎng)鏈接就可跳轉(zhuǎn) | 效率高 |
302 | 臨時(shí) | 每次請(qǐng)求都會(huì)請(qǐng)求短鏈接服務(wù)器,瀏覽器不會(huì)緩存 | 方便統(tǒng)計(jì)入口鏈接的訪問(wèn)次數(shù),短鏈接服務(wù)商主要盈利方式之一 |
4 軟件詳細(xì)設(shè)計(jì)
4.1 功能性需求
1.給定原始的Long URL,短鏈服務(wù)能生成比它短且唯一的Short URL
2.用戶點(diǎn)擊Short URL, 能跳轉(zhuǎn)到Long URL
3.有效期/過(guò)期機(jī)制
4.Short URL越短越好
4.2 非功能性需求
1.高可用:服務(wù)不能存在單點(diǎn)故障,用冗余來(lái)解決高可用問(wèn)題。
2.高性能:生成Short URL以及從Short URL 跳轉(zhuǎn)到Long URL 要近實(shí)時(shí)。讀寫(xiě)比預(yù)估100:1
3.安全:短鏈不可被猜測(cè)(防止被攻擊和濫用,引發(fā)不可知的情況)
4.3 短鏈生成
短鏈接的原理其實(shí)就是:將長(zhǎng)鏈接通過(guò)一定的算法生成一個(gè)短鏈接。訪問(wèn)短鏈接時(shí)實(shí)際訪問(wèn)的是短鏈接服務(wù)器,然后根據(jù)短鏈接的參數(shù)找回對(duì)應(yīng)的長(zhǎng)鏈接重定向跳轉(zhuǎn)。短URL包含一個(gè)短鏈接網(wǎng)站+短連接key。
系統(tǒng)本質(zhì)上包含一個(gè)短鏈算法模塊和一個(gè)Hash表。
長(zhǎng)URL通過(guò)短鏈算法生成短URL。將短URL作為key,長(zhǎng)URL作為value,保存到Hash表中。
用戶輸入短URL,直接從Hash表中查找并返回長(zhǎng)URL。
4.4 算法選擇
4.4.1 算法要求
- 生成值比原始值短
- 唯一性
- 高效、低CPU內(nèi)存消耗
- 安全不可預(yù)測(cè)
4.4.2 常見(jiàn)Hash算法
4.4.2.1 MD5
準(zhǔn)確說(shuō)它是一種信息摘要算法,從一個(gè)字符串或一個(gè)文件中按照一定的規(guī)律生成一個(gè)特殊的字符串。
生成的字符串是滿足唯一性的,但輸出是128位的,還是比較長(zhǎng)
4.4.2.2 SHA
SHA家族的五個(gè)算法,分別是SHA-1、SHA-224、SHA-256、SHA-384,和SHA-512,由美國(guó)國(guó)家安全局(NSA)所設(shè)計(jì),并由美國(guó)國(guó)家標(biāo)準(zhǔn)與技術(shù)研究院(NIST)發(fā)布;是美國(guó)的政府標(biāo)準(zhǔn)。
生成的字符串是滿足唯一性的。輸出長(zhǎng)度還是較大,而且這類(lèi)算法屬于加密型HASH算法,本質(zhì)是為了數(shù)據(jù)加密傳輸,后續(xù)需要能夠逆向得到原始字符串,相應(yīng)的算法性能比較低。
評(píng)價(jià)一個(gè)哈希算法的好壞,人們通常會(huì)引用 SMHasher 測(cè)試集的運(yùn)行結(jié)果。 Smhasher 測(cè)試Hash函數(shù)的功能,測(cè)試包括以下幾個(gè)方面:
- Sanity 是不是可以使用的
- Performance 完成一個(gè)散列需要多長(zhǎng)時(shí)間
- Differentials 產(chǎn)生相同哈希的概率,可能導(dǎo)致相同的的最小差異
- Keysets 分布均勻程度
一系列的測(cè)試方式具體可參考:https://github.com/aappleby/smhasher/wiki/SMHasher
4.4.2.3 MurmurHash
隨機(jī)分布特征表現(xiàn)更良好,發(fā)生 Hash 碰撞的幾率更低。比起 MD5它的性能至少提升了一個(gè)數(shù)量級(jí)。生成的結(jié)果為32bit或64bit相比MD5的長(zhǎng)度縮短了一個(gè)量級(jí)。
MurmurHash在很多現(xiàn)代KV型存儲(chǔ)中間件中被廣泛使用,如在Redis中當(dāng)字典被用作數(shù)據(jù)庫(kù)的底層實(shí)現(xiàn)或者哈希鍵的底層實(shí)現(xiàn)時(shí),Redis 使用 MurmurHash2 算法來(lái)計(jì)算鍵的哈希值。
算法主頁(yè): http://code.google.com/p/smhasher/
4.4.3 如何做到最短
1000萬(wàn)用戶平均每個(gè)月10條短信 每個(gè)月基本上1億個(gè)短鏈接即可。
預(yù)估未來(lái)五年增長(zhǎng)到5000萬(wàn)用戶,5億短鏈接基本夠用。
通常短鏈?zhǔn)怯?[0-9], [a-z], [A-Z] 這 62 個(gè)字符的組合來(lái)表示的,我們可以選擇用這62個(gè)字符對(duì)MurmurHash的結(jié)果做base62編碼,那么長(zhǎng)度是 N 的短鏈可以映射的 URL 數(shù)量如下圖:
5位長(zhǎng)度基本滿足未來(lái)五年需求,6位一定滿足,按照6位來(lái)設(shè)計(jì)(擴(kuò)展性更強(qiáng),余地更多)。
4.4.4 如何解決HASH沖突
4.4.4.1 沖突識(shí)別
方案1:先根據(jù)短鏈接查詢數(shù)據(jù)庫(kù),如果不存在則插入;
問(wèn)題:先查再插入,涉及兩次網(wǎng)絡(luò)請(qǐng)求及可能的磁盤(pán)調(diào)度
方案2:短鏈接字段建立唯一索引,直接插入,通過(guò)數(shù)據(jù)庫(kù)唯一索引檢測(cè)判斷重復(fù)
方案3:通過(guò)布隆過(guò)濾器快速判斷短鏈不存在,不需要唯一索引,可消除磁盤(pán)IO調(diào)度影響
但這個(gè)看似挺好,實(shí)際由于布隆過(guò)濾器數(shù)據(jù)易丟失,造成短鏈生成沖突
4.4.4.2 解決沖突
盡管 MurmurHash 算法,沖突的概率非常低。但是,一旦沖突,就會(huì)導(dǎo)致兩個(gè)原始鏈接被轉(zhuǎn)化成同一個(gè)短鏈接。可以給原始鏈接拼接一串特殊字符,比如“[REPEAT]”,然后跟再重新計(jì)算哈希值,兩次哈希計(jì)算都沖突的概率,顯然是非常低的。
4.4.5 如何解決重復(fù)長(zhǎng)地址轉(zhuǎn)換攻擊
用戶連續(xù)發(fā)起對(duì)同樣的長(zhǎng)地址轉(zhuǎn)換請(qǐng)求
服務(wù)端處理邏輯:
1)長(zhǎng)地址 -> 短地址
2)短地址沖突
3)長(zhǎng)地址疊加隨機(jī)值 -> 短地址
4)入庫(kù)
在大量請(qǐng)求下,一個(gè)長(zhǎng)地址對(duì)應(yīng)多個(gè)短地址,消耗數(shù)據(jù)庫(kù)資源,并造成數(shù)據(jù)庫(kù)操作效率降低。
解決方案:
1)給長(zhǎng)地址也加唯一索引
有沒(méi)更高效的辦法?
2)使用布隆過(guò)濾器存儲(chǔ)長(zhǎng)地址,每次轉(zhuǎn)換前先判斷下長(zhǎng)地址是否已經(jīng)轉(zhuǎn)換過(guò)。
這種方法效率高,雖然有布隆過(guò)濾器數(shù)據(jù)丟失后造成長(zhǎng)地址對(duì)應(yīng)多個(gè)短地址,但在高可用Redis集群模式下,丟失的不會(huì)太多,對(duì)應(yīng)多個(gè)短地址也不影響用戶使用
4.4.6 總結(jié)
采用計(jì)算速度快、沖突概率小的Murmur-Hash 算法,通過(guò)hash得到10進(jìn)制數(shù),然后轉(zhuǎn)化成 62 進(jìn)制表示法,進(jìn)一步減小短鏈接的長(zhǎng)度。對(duì)于哈希算法的哈希沖突問(wèn)題,我們通過(guò)給原始網(wǎng)址添加特殊前綴字符,重新計(jì)算哈希值的方法來(lái)解決。
4.5 短鏈接過(guò)期解決方案
短鏈接數(shù)據(jù)多為短時(shí)效存儲(chǔ)數(shù)據(jù),不需要永久保存,如優(yōu)惠券、促銷(xiāo)活動(dòng)等,之前的設(shè)計(jì)中短地址是永久保存在數(shù)據(jù)庫(kù)和分布式緩存中,會(huì)帶來(lái)數(shù)據(jù)庫(kù)和Redis的存儲(chǔ)資源容量持續(xù)增長(zhǎng),最終導(dǎo)致訪問(wèn)數(shù)據(jù)庫(kù)速度下降以及Redis的OOM問(wèn)題。
解決方案:設(shè)置過(guò)期時(shí)間,惰性刪除 + 定時(shí)刪除
1、接口層面
需要再重載一個(gè)接口,提供timeout字段可讓用戶自行決定保留時(shí)間,沒(méi)有提供timeout可根據(jù)公司的業(yè)務(wù)場(chǎng)景給定一個(gè)默認(rèn)保留時(shí)間
2、Redis層面
數(shù)據(jù)入Redis時(shí)設(shè)置過(guò)期時(shí)間,按照二八原則定律,百分之八十的數(shù)據(jù)會(huì)在存入數(shù)據(jù)后的百分之二十的過(guò)期時(shí)間內(nèi)訪問(wèn)。
1)為減少內(nèi)存消耗,Redis中數(shù)據(jù)的過(guò)期時(shí)間為數(shù)據(jù)庫(kù)中相應(yīng)數(shù)據(jù)剩余保留時(shí)間的一定比例
2)為避免緩存雪崩問(wèn)題,保留比例設(shè)置為(0.2, 0.5)范圍內(nèi)的隨機(jī)值。同時(shí)為避免Redis崩潰帶來(lái)的雪崩問(wèn)題,對(duì)Redis集群應(yīng)做高可用處理
3、數(shù)據(jù)庫(kù)層面
需加入createdTime,expiredTime兩個(gè)數(shù)據(jù)類(lèi)型為時(shí)間戳的字段,
參考Redis的數(shù)據(jù)過(guò)期處理原理 =》惰性+定時(shí)刪除相結(jié)合。
1)數(shù)據(jù)庫(kù)數(shù)據(jù)惰性刪除
查詢數(shù)據(jù)時(shí)判斷已過(guò)期,則同步刪除,返回提示用戶短地址已失效。
2)數(shù)據(jù)庫(kù)數(shù)據(jù)定時(shí)刪除
通過(guò)定時(shí)任務(wù),如每天凌晨掃描數(shù)據(jù)庫(kù)中expiredTime < now()的數(shù)據(jù)。
為避免鎖表:讀已提交隔離級(jí)別 + expiredTime設(shè)置索引。
3)定時(shí)任務(wù)框架選擇:
1)JDK自帶ScheduledExecutorService
微服務(wù)多節(jié)點(diǎn)部署下重復(fù)執(zhí)行的問(wèn)題,不會(huì)出現(xiàn)業(yè)務(wù)問(wèn)題,但浪費(fèi)數(shù)據(jù)庫(kù)性能
2)分布式任務(wù)調(diào)度框架
框架選型可參考:https://cloud.tencent.com/developer/article/2046586
考慮到Saturn、ElasticJob需要額外依賴Zookeeper增加維護(hù)成本,XXL-JOB作為初學(xué)者部署及開(kāi)發(fā)難度相對(duì)較大,
數(shù)據(jù)庫(kù)定時(shí)刪除對(duì)于可用性和性能要求較低,這里選用Quartz作為調(diào)度框架
4.6 數(shù)據(jù)庫(kù)設(shè)計(jì)
4.6.1 建表語(yǔ)句
4.6.2 分庫(kù)分表
單表按照1800W數(shù)據(jù)來(lái)計(jì)算,3.6億/1800W = 20張表。
單庫(kù)按照8000W數(shù)據(jù)計(jì)算,3.6億/8000W = 5個(gè)庫(kù)。
url_mapping 分表的 key 可以使用短鏈 Key 或創(chuàng)建時(shí)間來(lái)計(jì)算 hash,通過(guò)一致性 Hash 算法把記錄路由到對(duì)應(yīng)的分表。
url_0 url_mapping_0 ~ url_mapping_3
url_1 url_mapping_4 ~ url_mapping_7
url_2 url_mapping_8 ~ url_mapping_11
url_3 url_mapping_12 ~ url_mapping_15
url_4 url_mapping_16 ~ url_mapping_19
4.7 性能極致優(yōu)化
4.7.1 全局自增ID
所謂的全局自增ID:我們的服務(wù)是集群模式,全局自增意味著此ID在該集群內(nèi)唯一且自增。
去掉Hash的過(guò)程,同時(shí)預(yù)生成一批短鏈接,請(qǐng)求來(lái)了直接建立映射關(guān)系。
不同于 Hash 算法,全局自增 ID 的方案不需要對(duì)長(zhǎng) URL 進(jìn)行 Hash 轉(zhuǎn)換。因?yàn)?ID 全局自增且唯一,能確保一個(gè) ID 只映射一個(gè)長(zhǎng) URL,不存在Hash 算法中存在的多個(gè)長(zhǎng) URL 可能映射到同一個(gè)短鏈的問(wèn)題。基于全局自增 ID 的方案,依賴自增ID產(chǎn)生的效率。
可以選用無(wú)需即時(shí)生成的分布式ID解決方案,如美團(tuán)的leaf開(kāi)源組件,百度Uidgenerator開(kāi)源組件,都有批量號(hào)段緩存及緩存預(yù)加載機(jī)制,ID的獲取操作就是一個(gè)簡(jiǎn)單的數(shù)據(jù)GET操作,輕松可以達(dá)到十萬(wàn)級(jí)生成效率。
缺點(diǎn):生成的短鏈接是自增的,用戶方可以猜測(cè)到業(yè)務(wù)的交易流水量,流水量對(duì)于很多互聯(lián)網(wǎng)公司是機(jī)密敏感數(shù)據(jù),會(huì)帶來(lái)不安全性??梢钥紤]通過(guò)接口字段讓用戶自定義選擇短鏈生成方式,同時(shí)短鏈服務(wù)本身也得做好功能可擴(kuò)展性的設(shè)計(jì)。
4.7.2 查詢優(yōu)化
一般的短鏈系統(tǒng),基本都是讀多寫(xiě)少,對(duì)于高頻操作(讀),如果每次都從數(shù)據(jù)庫(kù)取,開(kāi)銷(xiāo)較大,通常采用緩存技術(shù)來(lái)解決。
4.8 服務(wù)高可用設(shè)計(jì)
短鏈接服務(wù)是一個(gè)高并發(fā)項(xiàng)目,需保證高性能的同時(shí),也要保證服務(wù)不間斷。
總體思路: Keepalive + Nginx + 多節(jié)點(diǎn)容器化部署 + Redis Sentinel + Mysql半同步
4.8.1 負(fù)載均衡器選擇
4.8.1.1 DNS輪詢
優(yōu)點(diǎn)
- 低成本:只需要在DNS服務(wù)器上把域名綁定多個(gè)A記錄即可。域名注冊(cè)商一般都免費(fèi)提供此類(lèi)解析服務(wù)。
- 部署簡(jiǎn)單:部署多個(gè)web應(yīng)用實(shí)例,然后在DNS服務(wù)器上添加A記錄。
缺點(diǎn)
- 可靠性低:業(yè)務(wù)機(jī)器出現(xiàn)問(wèn)題,沒(méi)有故障轉(zhuǎn)移機(jī)制
- 負(fù)載分配問(wèn)題:緩存綁定,負(fù)載不均衡
4.8.1.2 硬件負(fù)載
優(yōu)點(diǎn)
- 高性能:硬件負(fù)載均衡器可以處理大量的網(wǎng)絡(luò)請(qǐng)求,具有很高的性能,可以滿足高流量負(fù)載的需求。
- 高可靠性:硬件負(fù)載均衡器通常具有冗余的硬件和軟件,可以提供高可靠性,防止單點(diǎn)故障導(dǎo)致整個(gè)系統(tǒng)崩潰。
- 高擴(kuò)展性:硬件負(fù)載均衡器可以輕松地?cái)U(kuò)展和升級(jí),以應(yīng)對(duì)增加的網(wǎng)絡(luò)負(fù)載。
- 安全性:硬件負(fù)載均衡器通常具有內(nèi)置的安全特性,如DDoS攻擊防御、SSL加速和安全連接等,可以保護(hù)網(wǎng)絡(luò)安全。
缺點(diǎn)
- 成本高:硬件負(fù)載均衡器通常價(jià)格昂貴,需要更多的預(yù)算。
- 管理復(fù)雜:硬件負(fù)載均衡器的安裝、配置和管理需要技術(shù)人員進(jìn)行,需要較高的技術(shù)水平和時(shí)間投入。
- 靈活性差:硬件負(fù)載均衡器通常需要進(jìn)行預(yù)配置,而且不太靈活,無(wú)法快速適應(yīng)變化的網(wǎng)絡(luò)環(huán)境。
4.8.1.3 LVS
LVS是Linux Virtual Server的縮寫(xiě),是一個(gè)基于Linux內(nèi)核的負(fù)載均衡器軟件,旨在為高性能、高可用性和可擴(kuò)展性的應(yīng)用程序提供負(fù)載均衡和高可用性服務(wù)。
優(yōu)點(diǎn)
- LVS是一個(gè)內(nèi)核級(jí)別的負(fù)載均衡器,運(yùn)行時(shí)不存在用戶態(tài)、內(nèi)核態(tài)上下文切換的消耗,因此具有很高的性能和吞吐量。
- LVS支持多種負(fù)載均衡算法和協(xié)議,可以根據(jù)實(shí)際需求進(jìn)行配置。
- LVS具有較好的可靠性和可擴(kuò)展性,可以通過(guò)增加后端服務(wù)器來(lái)增加負(fù)載容量。
缺點(diǎn):
- LVS的安裝和配置比較復(fù)雜,使用門(mén)檻較高,需要有一定的Linux系統(tǒng)和網(wǎng)絡(luò)知識(shí)。
- LVS的管理和維護(hù)成本比較高,需要專(zhuān)門(mén)的管理人員來(lái)進(jìn)行操作和維護(hù)。
- LVS的負(fù)載均衡器只能工作在內(nèi)核空間中,不支持靈活的配置。
4.8.1.4 NGINX
優(yōu)點(diǎn)
- 靈活性:Nginx支持多種負(fù)載均衡策略,可以根據(jù)請(qǐng)求的源IP地址、目標(biāo)IP地址、源端口號(hào)、目標(biāo)端口號(hào)等信息來(lái)判斷請(qǐng)求的目標(biāo)服務(wù)器,并將請(qǐng)求轉(zhuǎn)發(fā)到合適的服務(wù)器上。
- 易于配置:Nginx的配置文件簡(jiǎn)單易懂,可以快速配置和部署,同時(shí)支持熱部署,可以在不停止服務(wù)的情況下更新配置文件。
- 支持緩存。
4.8.1.5 總結(jié)
短鏈接服務(wù)預(yù)期QPS不會(huì)過(guò)萬(wàn),Nginx作為負(fù)載均衡已經(jīng)足夠了
4.8.2 負(fù)載均衡器高可用
Nginx作為負(fù)載均衡器,掛掉則服務(wù)整體不可用。這里選擇用KeepAlive軟件做Nginx高可用
基本原理:通過(guò)建立主備兩臺(tái)服務(wù)器,保證一臺(tái)服務(wù)掛了后另外一臺(tái)還能提供服務(wù)。
4.8.2.1 宕機(jī)檢測(cè)
主節(jié)點(diǎn)和從節(jié)點(diǎn)維護(hù)心跳,從節(jié)點(diǎn)通過(guò)心跳檢測(cè)主節(jié)點(diǎn)掛機(jī),主節(jié)點(diǎn)掛機(jī)后,從節(jié)點(diǎn)升級(jí)為主節(jié)點(diǎn)
4.8.2.2 故障轉(zhuǎn)移
從節(jié)點(diǎn)升級(jí)為主節(jié)點(diǎn)后,如何將用戶訪問(wèn)轉(zhuǎn)到新的主節(jié)點(diǎn)呢。用戶訪問(wèn)的是短鏈接域名,通過(guò)DNS協(xié)議映射到負(fù)載均衡器節(jié)點(diǎn)。這里主備服務(wù)器會(huì)通過(guò)虛擬網(wǎng)卡技術(shù)生成同樣的虛擬IP,DNS映射為該虛擬IP,那么理論上在IP協(xié)議層ARP協(xié)議會(huì)同時(shí)廣播到這兩臺(tái)機(jī)器,但KeepAlive軟件會(huì)只讓主節(jié)點(diǎn)回復(fù)ARP包。這樣當(dāng)原主節(jié)點(diǎn)掛機(jī)后,用戶訪問(wèn)的就是新的主節(jié)點(diǎn)。
4.8.3 Redis高可用
為避免單機(jī)Redis掛機(jī)導(dǎo)致緩存雪崩等問(wèn)題,需建立Redis集群機(jī)制,常見(jiàn)的解決方案是搭建Redis Sentinel集群來(lái)做節(jié)點(diǎn)宕機(jī)檢測(cè)及故障轉(zhuǎn)移。這里注意不同的哨兵最好部署在不同的機(jī)房,進(jìn)行隔離,以免沒(méi)有足夠的哨兵存活(<quorun),無(wú)法進(jìn)行故障轉(zhuǎn)移。
4.8.4 數(shù)據(jù)庫(kù)高可用
常見(jiàn)的方案為建立主從集群,但注意數(shù)據(jù)庫(kù)默認(rèn)的復(fù)制為異步復(fù)制。主節(jié)點(diǎn)磁盤(pán)損壞,從節(jié)點(diǎn)未來(lái)得及復(fù)制時(shí),數(shù)據(jù)會(huì)出現(xiàn)丟失。
可采取數(shù)據(jù)同步復(fù)制方案,主節(jié)點(diǎn)將數(shù)據(jù)同步到從節(jié)點(diǎn),從節(jié)點(diǎn)返回?cái)?shù)據(jù)重放成功后,主節(jié)點(diǎn)才返回用戶成功。數(shù)據(jù)在主或從數(shù)據(jù)丟失后,用戶是能實(shí)時(shí)感知的,可以通過(guò)選擇重試來(lái)保證數(shù)據(jù)的可靠性。
在企業(yè)級(jí)生產(chǎn)中,一般會(huì)采取同步加異步復(fù)制相結(jié)合的方案,簡(jiǎn)稱半同步復(fù)制。主節(jié)點(diǎn)和同步復(fù)制的從節(jié)點(diǎn)會(huì)部署在同一地點(diǎn)的不同機(jī)房,異步復(fù)制的從節(jié)點(diǎn)部署在另外的機(jī)房,這樣可以避免極低概率下同一地點(diǎn)的數(shù)據(jù)中心出現(xiàn)著火、網(wǎng)絡(luò)中斷等數(shù)據(jù)中斷異常。