基于diff的文件同步算法(上)

1.寫(xiě)在前面

文件同步的核心問(wèn)題是新舊版本的對(duì)比問(wèn)題匠题。這里所說(shuō)的版本是指用于區(qū)分文件變更的一種狀態(tài)標(biāo)記拯坟,它可以是我們通常所說(shuō)的版本號(hào),也可以是時(shí)間戳韭山,如修改時(shí)間郁季。本文介紹一種基于diff的文件同步算法,共分為兩篇钱磅,上篇介紹diff算法的服務(wù)端實(shí)現(xiàn)梦裂,下篇介紹diff算法的客戶端實(shí)現(xiàn)。

2.算法概述

從客戶端的角度來(lái)看盖淡,文件同步的本質(zhì)是本地文件集合與云端文件集合的對(duì)比年柠。從實(shí)現(xiàn)角度來(lái)講,客戶端會(huì)保存一份云端文件集合的快照褪迟,通過(guò)將快照和云端集合對(duì)比可以計(jì)算出云端文件變更冗恨,通過(guò)將快照和本地集合對(duì)比則可以計(jì)算出本地文件變更答憔。對(duì)于本地文件的變更,需要將文件提交至云端掀抹;對(duì)于云端文件的變更攀唯,需要將文件同步至本地。對(duì)于文件同步在云端和本地都有修改的情況下渴丸,就需要進(jìn)行沖突處理侯嘀。

如果每個(gè)同步周期需要獲取云端文件集合,文件量小還可以接受谱轨,文件量一大戒幔,對(duì)帶寬和服務(wù)器壓力都會(huì)存在瓶頸,而且很多文件可能根本就沒(méi)有變更土童,這會(huì)造成很多無(wú)效的對(duì)比诗茎,浪費(fèi)計(jì)算資源。所以需要一種增量機(jī)制献汗,用于增量拉取云端變更的文件敢订。

diff算法是利用修改時(shí)間作為增量機(jī)制,其核心是每次diff時(shí)會(huì)記錄下當(dāng)前diff的時(shí)間戳罢吃,客戶端下次diff時(shí)楚午,帶上上次diff時(shí)返回的時(shí)間戳(通常將時(shí)間戳編碼到cursor中),這樣就能增量獲取到一段時(shí)間內(nèi)的變更記錄了尿招。由于每次diff的變更文件集合可能非常大矾柜,所以需要進(jìn)行分頁(yè)操作,有兩個(gè)主要的問(wèn)題需要解決:

  • 首次diff問(wèn)題
  • 用時(shí)間維度獲取變更記錄時(shí)就谜,如(t1, t2]之間的文件變更怪蔑,由于t1、t2通常是使用秒作為精度丧荐,每次分頁(yè)diff出的文件記錄時(shí)缆瓣,如果存在閉區(qū)間t2時(shí)刻文件記錄,則無(wú)法判斷t2時(shí)刻是否存在更多的記錄虹统。

3.全量同步

首次diff通常發(fā)生在客戶端本地快照沒(méi)有數(shù)據(jù)且第一次請(qǐng)求時(shí)弓坞,這種情況通常指全量同步。服務(wù)器在處理全量同步時(shí)是希望盡量將當(dāng)時(shí)請(qǐng)求時(shí)刻以內(nèi)的所有文件數(shù)據(jù)都分頁(yè)吐給客戶端窟却。由于時(shí)間戳存在增量同步的問(wèn)題昼丑,可以使用文件惟一標(biāo)識(shí)迭代出全量數(shù)據(jù)。如果記文件的惟一標(biāo)識(shí)為fid夸赫,修改時(shí)間為mtime,分頁(yè)大小為pagesize咖城,SQL查詢具體做法為:

select fields from file_meta where fid>last_fid and mtime<=stime sort by fid ASC limit pagesize茬腿;

其中:

  • stime是第一次全量同步時(shí)呼奢,記錄下當(dāng)前請(qǐng)求的時(shí)間戳,主要是明確一個(gè)時(shí)間限界內(nèi)的全量數(shù)據(jù)切平,防止在全量同步過(guò)程中又出現(xiàn)新的變更握础;
  • last_fid為最近一次查詢結(jié)果中最后一條記錄的fid,首次查詢last_fid為0悴品;
  • 判斷是否有更多數(shù)據(jù)通常采用多取一條記錄進(jìn)行判斷禀综;
  • 由于并不知道全量同步過(guò)程中是否有新的文件變更,需要進(jìn)行一次增量同步苔严;

4.增量同步

前面說(shuō)到在按時(shí)間維度進(jìn)行增量同步時(shí)定枷,由于需要分頁(yè),并不知道閉區(qū)間內(nèi)是否有更多文件變更記錄届氢。舉個(gè)粟子欠窒,當(dāng)我們查詢出(t1, t2]的文件集合時(shí),如果恰好有幾個(gè)文件的修改時(shí)間等于t2退子,而且本次分頁(yè)并沒(méi)有拉取完岖妄。下次diff時(shí)會(huì)查詢(t3, t4]時(shí)間區(qū)間內(nèi)的文件(t3>t2),由于上次并沒(méi)有拉取完寂祥,即t2時(shí)間可能還有更多數(shù)據(jù)荐虐,如果直接查詢(t3, t4]時(shí)間區(qū)間的文件,那么可能會(huì)丟失t2時(shí)間的文件記錄丸凭。

對(duì)于以上情況衙传,當(dāng)查詢(t1, t2]時(shí)間區(qū)間內(nèi)的文件時(shí),針對(duì)返回的文件遵班,我們需要對(duì)最后一秒的文件進(jìn)行單獨(dú)處理瘾婿。如果返回的文件的修改時(shí)間均是在一秒內(nèi),那么稱為單秒增量同步向拆,其它情況稱為正常增量同步亚茬。

4.1.正常增量同步

對(duì)于正常增量同步雖然所有文件的mtime不是在同一秒內(nèi),但需要處理最后一秒問(wèn)題浓恳,就像前面的例子刹缝,當(dāng)分頁(yè)未完成時(shí),我們沒(méi)辦判斷最后一秒是否還有更多數(shù)據(jù)颈将,所以一個(gè)簡(jiǎn)單的做法是從本次查詢的文件記錄中梢夯,從最后一個(gè)文件開(kāi)始,移除mtime相同的文件晴圾,即把最后一秒的文件留到下次進(jìn)行查詢颂砸。當(dāng)最后一秒的文件足夠多,比如超過(guò)一個(gè)分頁(yè)時(shí),就會(huì)觸發(fā)單秒增量同步人乓。正常增量同步查詢SQL表示:

select fields from file_meta where mtime>t1 and mtime<=t2 sort by mtime DESC limit pagesize;

4.2.單秒增量同步

單秒增量同步是指查詢一秒內(nèi)的文件記錄勤篮,這種查詢比較簡(jiǎn)單,如果用SQL表示如下:

select fields from file_meta where mtime=xxx sort limit pagesize;

5.其它工程問(wèn)題

在工程實(shí)現(xiàn)上還需要注意很多問(wèn)題色罚,比如主從同步碰缔、頻率控制、數(shù)據(jù)重置等戳护。

5.1.主從同步

對(duì)服務(wù)器來(lái)講金抡,文件數(shù)據(jù)的存儲(chǔ)量通常都比較大,不可能采用單機(jī)就能搞定腌且,一般都會(huì)采用分布式進(jìn)行存儲(chǔ)梗肝,對(duì)于分布存儲(chǔ)就會(huì)存儲(chǔ)主從同步問(wèn)題。當(dāng)寫(xiě)操作完成后切蟋,馬上讀取统捶,如果主從同步未完成,并不能讀取出數(shù)據(jù)柄粹。所以在diff的時(shí)間滑動(dòng)窗口中喘鸟,需要做一定的延遲處理,延遲時(shí)間肯定需要大于主從同步的時(shí)間驻右。

5.2.頻率控制

對(duì)于diff接口什黑,可能會(huì)調(diào)用的比較頻繁,如果不進(jìn)行頻率控制堪夭,高峰期時(shí)可能會(huì)造成雪崩效率愕把,diff接口需要有降級(jí)和頻控處理。diff接口一般來(lái)說(shuō)是一種后臺(tái)行為森爽,并不需要進(jìn)行實(shí)時(shí)調(diào)用恨豁,當(dāng)客戶端進(jìn)行增量同步時(shí),如果在一段很短的時(shí)間內(nèi)連續(xù)調(diào)用爬迟,應(yīng)觸發(fā)頻控策略橘蜜。

5.3.數(shù)據(jù)重置

由于客戶端會(huì)緩存云端數(shù)據(jù)快照,如果客戶端存在臟數(shù)據(jù)付呕,將導(dǎo)致同步算法失敗计福。服務(wù)器應(yīng)該和客戶端約定一種數(shù)據(jù)重置機(jī)制,當(dāng)服務(wù)器端數(shù)據(jù)升級(jí)或出現(xiàn)臟數(shù)據(jù)時(shí)徽职,服務(wù)端可以下發(fā)數(shù)據(jù)重置命令象颖,客戶端收到數(shù)據(jù)重置命令后應(yīng)該清空本地緩存,重新進(jìn)行全量同步姆钉。

6.總結(jié)

diff算法需要處理全量同步和增量同步的情況说订。全量同步按照文件id維度排序分頁(yè)下發(fā)抄瓦;增量同步按照時(shí)間維度分頁(yè)下發(fā),由于分頁(yè)原因以及時(shí)間精度問(wèn)題克蚂,不能判斷最后一秒內(nèi)是否存在更多的數(shù)據(jù)需要查詢闺鲸,因?yàn)榘炎詈笠幻氲臄?shù)據(jù)進(jìn)行單獨(dú)查詢筋讨。最后就是需要考慮一些工程上的問(wèn)題埃叭,如主從同步、頻率控制悉罕、接口降級(jí)赤屋、數(shù)據(jù)重置等問(wèn)題。

--- 上篇完 ---

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末壁袄,一起剝皮案震驚了整個(gè)濱河市类早,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌嗜逻,老刑警劉巖涩僻,帶你破解...
    沈念sama閱讀 206,378評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異栈顷,居然都是意外死亡逆日,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)萄凤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)室抽,“玉大人,你說(shuō)我怎么就攤上這事靡努∑夯” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,702評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵惑朦,是天一觀的道長(zhǎng)兽泄。 經(jīng)常有香客問(wèn)我,道長(zhǎng)漾月,這世上最難降的妖魔是什么病梢? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,259評(píng)論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮栅屏,結(jié)果婚禮上飘千,老公的妹妹穿的比我還像新娘。我一直安慰自己栈雳,他們只是感情好护奈,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,263評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著哥纫,像睡著了一般霉旗。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,036評(píng)論 1 285
  • 那天厌秒,我揣著相機(jī)與錄音读拆,去河邊找鬼。 笑死鸵闪,一個(gè)胖子當(dāng)著我的面吹牛檐晕,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播蚌讼,決...
    沈念sama閱讀 38,349評(píng)論 3 400
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼辟灰,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了篡石?” 一聲冷哼從身側(cè)響起芥喇,我...
    開(kāi)封第一講書(shū)人閱讀 36,979評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎凰萨,沒(méi)想到半個(gè)月后继控,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,469評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡胖眷,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,938評(píng)論 2 323
  • 正文 我和宋清朗相戀三年武通,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瘦材。...
    茶點(diǎn)故事閱讀 38,059評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厅须,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出食棕,到底是詐尸還是另有隱情朗和,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評(píng)論 4 323
  • 正文 年R本政府宣布簿晓,位于F島的核電站眶拉,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏憔儿。R本人自食惡果不足惜忆植,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,257評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望谒臼。 院中可真熱鬧朝刊,春花似錦、人聲如沸蜈缤。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,262評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)底哥。三九已至咙鞍,卻和暖如春房官,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背续滋。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工翰守, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人疲酌。 一個(gè)月前我還...
    沈念sama閱讀 45,501評(píng)論 2 354
  • 正文 我出身青樓蜡峰,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親徐勃。 傳聞我的和親對(duì)象是個(gè)殘疾皇子事示,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,792評(píng)論 2 345

推薦閱讀更多精彩內(nèi)容