一種分布式存儲ceph的糾刪碼覆蓋寫方法
【專利摘要】本發(fā)明公開一種分布式存儲CEPH的糾刪碼覆蓋寫方法,首先客戶端節(jié)點發(fā)送寫請求到Ceph的存儲節(jié)點中的主OSD,主OSD自動選擇最優(yōu)編碼方案后計算需要讀取的數(shù)據(jù)塊,并根據(jù)客戶端id和對象id,從緩存中讀取數(shù)據(jù)塊返回主OSD;接著主OSD在接收完所有需要的讀數(shù)據(jù)塊后,更新數(shù)據(jù)塊和校驗塊,發(fā)送到需要更新的對應OSD;然后數(shù)據(jù)塊節(jié)點和校驗塊節(jié)點接收寫請求,分配原始數(shù)據(jù)塊附近的新存儲位置存儲新更新,并記錄本次寫請求元數(shù)據(jù)到日志PGLOG,數(shù)據(jù)和日志落盤后發(fā)送ACK給主OSD;最后主OSD接收所有更新節(jié)點的ACK后,記錄本次更新元數(shù)據(jù)到內(nèi)存,并回復ACK給客戶端完成寫請求。本發(fā)明解決了分布式存儲系統(tǒng)CEPH不支持糾刪碼覆蓋寫的問題。
【專利說明】
_種分布式存儲GEPH的糾刪碼覆蓋寫方法
技術(shù)領(lǐng)域
[0001]本發(fā)明涉及分布式存儲領(lǐng)域,特別涉及一種分布式存儲CEPH的糾刪碼覆蓋寫方法。
【背景技術(shù)】
[0002]傳統(tǒng)分布式存儲采用多副本的存儲技術(shù),通過一份數(shù)據(jù)保存多份來提供高可靠性。多副本帶來高可靠性的同時,存儲代價也是多倍的。糾刪碼作為以更小的存儲代價獲得相同可靠性的方法,已經(jīng)得到越來越多的應用。
[0003]目前糾刪碼的主要應用領(lǐng)域是冷數(shù)據(jù)存儲,讀寫模式多為一次寫多次讀,文件只支持在末尾添加數(shù)據(jù)的追加模式。追加寫的修改模式和寫全新文件類似,而糾刪碼的覆蓋寫,涉及到數(shù)據(jù)塊的更新和校驗塊的更新,數(shù)據(jù)塊的更新替換對應偏移數(shù)據(jù)即可,校驗塊的更新有兩種方式:I)重構(gòu)寫:讀取更新數(shù)據(jù)對應編碼條帶中不涉及更新的數(shù)據(jù),合并新數(shù)據(jù)后重新編碼,得到新的校驗塊,需要讀一次數(shù)據(jù)塊,寫一次數(shù)據(jù)塊和一次校驗塊;2)增量寫:利用糾刪碼的線性性,讀取更新數(shù)據(jù)范圍的原始數(shù)據(jù),計算原始數(shù)據(jù)塊和更新數(shù)據(jù)差值并乘以編碼系數(shù)得到A P,再讀取校驗塊P,計算他們的和得到新校驗塊數(shù)據(jù)P’,即P’=Ρ+Δ P,需要讀取一次數(shù)據(jù)塊和校驗塊,寫一次數(shù)據(jù)塊和一次校驗塊。兩種更新方式中,都需要先讀取部分數(shù)據(jù),才能重新計算新的校驗塊。
[0004]在分布式系統(tǒng)中,通常采用RS(k,m)的糾刪碼,即原始數(shù)據(jù)切片k塊,編碼出m塊校驗塊,分別存儲到k+m個節(jié)點中。糾刪碼覆蓋寫,需要至少m+1個節(jié)點的參與,包括I個數(shù)據(jù)節(jié)點,m個校驗塊節(jié)點。當覆蓋數(shù)據(jù)范圍變大時,需要的節(jié)點數(shù)也會更多。RS(k,m)的糾刪碼至多容忍m個節(jié)點丟失,需要k個節(jié)點才能解碼原始數(shù)據(jù),所以覆蓋寫更新需要保持至少k個節(jié)點數(shù)據(jù)版本一致,才能保證更新不會造成數(shù)據(jù)丟失。
[0005]糾刪碼的復雜更新方式使其很少在實際分布式系統(tǒng)中,但隨著糾刪碼越來越多的應用于多讀多寫的場景,將傳統(tǒng)的將覆蓋寫轉(zhuǎn)化成追加或者全讀全覆蓋的方式,耗費大量磁盤開銷和網(wǎng)絡開銷。
【發(fā)明內(nèi)容】
[0006]發(fā)明目的:針對現(xiàn)有技術(shù)中存在的問題,本發(fā)明提供一種基于分布式存儲CEPH的糾刪碼覆蓋寫方法,解決了分布式存儲系統(tǒng)CEPH不支持糾刪碼覆蓋寫的問題。
[0007]技術(shù)方案:為實現(xiàn)上述目的,本發(fā)明提出一種分布式存儲CEPH的糾刪碼覆蓋寫方法,包括以下步驟:
[0008]步驟I:客戶端節(jié)點發(fā)送寫請求到Ceph的存儲節(jié)點中的主OSD,主OSD自動選擇最優(yōu)編碼方案(重構(gòu)寫或者增量寫)后,計算需要讀取的數(shù)據(jù)塊,并根據(jù)客戶端id和對象id,從緩存中讀取數(shù)據(jù)塊返回主OSD ;
[0009]該方法確定最優(yōu)編碼方案的具體步驟為:
[0010]I)計算寫請求涉及的編碼條帶范圍:首先對齊寫請求偏移到所在編碼條帶的首位置;然后根據(jù)寫請求長度計算寫范圍的末尾偏移,并對齊到所在條帶的末位置;最后根據(jù)對齊后的首偏移和尾偏移,得到覆蓋寫請求的條帶覆蓋范圍偏移和長度;
[0011]2)根據(jù)寫請求的偏移和長度結(jié)合條帶覆蓋范圍,計算不同編碼方案需要預先讀取的數(shù)據(jù)量:重構(gòu)寫需要讀取數(shù)據(jù)量=對齊后計算得到的范圍減去實際更新數(shù)據(jù)量;增量寫需要讀取數(shù)據(jù)量=實際更新數(shù)據(jù)量;
[0012]3)根據(jù)需要讀取的數(shù)據(jù)量動態(tài)選擇編碼方案:若對齊后計算得到的范圍超過2個編碼條帶且至少有I個條帶已經(jīng)全覆蓋,或者重構(gòu)讀取數(shù)據(jù)量小于增量寫讀取數(shù)據(jù)量,則采用重構(gòu)寫;否則,采用增量寫。
[0013]該方法主OSD從緩存中讀取數(shù)據(jù)塊的具體方法為:
[0014]I)根據(jù)請求客戶端cid檢索緩存組,如果存在,則直接提取,如果沒有則分配新的緩存組,如果空間足夠,則直接分配,如果已分配數(shù)超過預定客戶端緩存數(shù)時,從LRU鏈表中刪除末尾客戶端id,新建當前客戶端cid的緩存組索引,并加入LRU結(jié)構(gòu);
[0015]2)從緩存組中,根據(jù)對象oid和讀取范圍對應的數(shù)據(jù)塊序號num檢索Hashmap的索引結(jié)構(gòu),如果存在對應數(shù)據(jù)塊,則直接返回;如果不存在,則發(fā)起讀請求,在讀數(shù)據(jù)返回后將數(shù)據(jù)塊加入緩存組,在緩存滿時,根據(jù)LRU算法刪除最近最久未使用的數(shù)據(jù)塊。
[0016]步驟2:主OSD在接收完所有需要的讀數(shù)據(jù)塊后,將數(shù)據(jù)塊存入緩存結(jié)構(gòu),并根據(jù)對應編碼方法計算校驗塊更新所需的數(shù)據(jù),然后更新數(shù)據(jù)塊和校驗塊,發(fā)送到需要更新的對應 0SD;
[0017]該方法選擇不同的編碼方案時,更新校驗塊所需的數(shù)據(jù)量和方法不同,具體為:采用重構(gòu)寫時,讀取覆蓋寫范圍以外的條帶數(shù)據(jù),在讀取對應數(shù)據(jù)后,和覆蓋數(shù)據(jù)合并成新的完整塊,編碼出新的校驗塊;采用增量寫時,讀取覆蓋寫范圍以內(nèi)的條帶數(shù)據(jù),直接讀取新數(shù)據(jù)并返回,在讀取對應數(shù)據(jù)后,計算覆蓋數(shù)據(jù)D ’和原始數(shù)據(jù)D的有限域差值△ D,然后計算△ D乘以對應編碼系數(shù)的有限域乘后發(fā)送到對應的校驗塊存儲節(jié)點。
[0018]步驟3:數(shù)據(jù)塊節(jié)點和校驗塊節(jié)點接收寫請求,分配原始數(shù)據(jù)塊附近的新存儲位置存儲新更新,并記錄本次寫請求元數(shù)據(jù)到日志PGLOG,數(shù)據(jù)和日志落盤后發(fā)送ACK給主OSD。[0019 ]步驟4:主OSD接收所有更新節(jié)點的ACK后,記錄本次更新元數(shù)據(jù)到內(nèi)存,并回復ACK給客戶端,完成寫請求。
[0020]當主OSD接收所有更新節(jié)點的ACK回復超,即更新失敗時,該方法還包括恢復數(shù)據(jù)的步驟,采用基于PGLOG日志的回滾機制恢復數(shù)據(jù),具體為:
[0021]I )PG層周期性進行Peering操作,拉取同組各OSD的PGLOG版本,對比各OSD的版本是否和權(quán)威版本一致,若一致,則不做處理,若不一致,則發(fā)送PGLOG權(quán)威版本到不一致節(jié)占.V ,
[0022]2)不一致節(jié)點收到Peering后的權(quán)威PGL0G,進行本地的PGLOG對比合并,發(fā)現(xiàn)本地版本超前后,遍歷超前的PGLOG,將其加入to_rol Iback列表;
[0023]3)處理完P(guān)GLOG版本后,PGLogEntryHand Ier遍歷 to_ro 11 back列表,讀取每一條Pglog的回滾信息,并調(diào)用對應的回滾函數(shù),讀取pglog中記錄的對象id,版本V,根據(jù)id和V索引更新時新分配的存儲塊,然后刪除存儲塊;
[0024]4)所有超前pglog回滾完成后,刪除這部分pglog,更新本地pglog為權(quán)威版本。
[0025]該方法不同編碼方案對應的更新后校驗塊讀取過程不同,具體為:
[0026]I)根據(jù)對象id查找主節(jié)點的元數(shù)據(jù)信息對應的更新記錄,遍歷更新記錄,檢查是否和讀請求偏移和長度有重疊,如果沒有重疊,則按原始方法直接構(gòu)造讀請求發(fā)送對應節(jié)點;如果有重疊,則跳轉(zhuǎn)步驟2;
[0027]2)計算讀請求和各重疊部分相關(guān)的偏移和長度,將這些構(gòu)造為讀請求的額外讀中,根據(jù)數(shù)據(jù)塊大小將讀請求和額外讀劃分到各個分片的讀請求中,并發(fā)送對應各節(jié)點;校驗塊節(jié)點根據(jù)讀請求和額外讀請求,讀取對應對象數(shù)據(jù),并將額外讀請求數(shù)據(jù)按版本從小到大順序合并入原始數(shù)據(jù),合并過程中,檢查額外讀數(shù)據(jù)元數(shù)據(jù)信息中的更新方法,如果是重構(gòu)寫,則直接合并,如果是增量寫,則計算對應位置原始數(shù)據(jù)和額外讀數(shù)據(jù)的和,再合并,然后返回主節(jié)點。
[0028]有益效果:本發(fā)明結(jié)合了CEPH系統(tǒng)的糾刪碼框架和恢復框架,以日志形式存儲覆蓋數(shù)據(jù),利用日志回滾機制解決更新失敗時數(shù)據(jù)一致性問題;結(jié)合動態(tài)選擇編碼方案,自適應大塊寫和小塊寫的復雜場景;利用主節(jié)點的緩存機制,減少頻繁局部寫時的預讀請求,以及通過隔離不同客戶端的緩存,防止大塊寫影響小塊寫的命中率。這些機制的配合從整體上可以減少糾刪碼覆蓋寫的磁盤開銷和網(wǎng)絡開銷。
【附圖說明】
[0029]圖1是CEPH中糾刪碼條帶存儲示意圖;
[0030]圖2是CEPH中糾刪碼覆蓋寫請求時序圖;
[0031 ]圖3是CEPH中糾刪碼覆蓋寫的重構(gòu)更新方式示意圖;
[0032]圖4是CEPH中糾刪碼覆蓋寫的增量更新方式示意圖。
【具體實施方式】
[0033]下面結(jié)合實施例對本發(fā)明做更進一步的說明。
[0034]分布式存儲CEPH的糾刪碼覆蓋寫方法,具體包括如下步驟:
[0035]1、客戶端節(jié)點根據(jù)CEPH的CRUSH算法和節(jié)點映射,將寫請求的對象id定位到數(shù)據(jù)存儲的主OSD,然后將寫請求包括對象id,偏移offset,長度length和數(shù)據(jù)buffer等發(fā)送到的主OSD。
[0036]2、主OSD從網(wǎng)絡消息中解析出寫請求,經(jīng)過PG層事務處理后,進入糾刪碼后端處理,判斷是覆蓋寫后進入新的寫路徑,然后以對象id為key為覆蓋寫請求構(gòu)造狀態(tài)機,并對該對象的加寫鎖。
[0037]3、狀態(tài)機進入讀狀態(tài),首先計算寫請求涉及的編碼條帶范圍,具體步驟:(I)對齊寫請求偏移到所在編碼條帶的首位置;(2)根據(jù)寫請求長度計算寫范圍的末尾偏移,并對齊到所在條帶的末位置;(3)根據(jù)對齊后的首偏移0fT_begin和尾偏移ofT_end,得到覆蓋寫請求的條帶覆蓋范圍偏移和長度(off_begin,off_end_off_begin)。
[0038]4、主OSD根據(jù)寫請求的偏移和長度結(jié)合條帶覆蓋范圍,計算不同編碼方案需要預先讀取的數(shù)據(jù)量:(I)重構(gòu)寫需要讀取數(shù)據(jù)量:對齊后計算得到的范圍減去實際更新數(shù)據(jù)量,得到重構(gòu)寫需要讀取的數(shù)據(jù)量;(2)增量寫需要讀取數(shù)據(jù)量:實際更新數(shù)據(jù)量即為增量需要讀取的數(shù)據(jù)量;
[0039]然后,根據(jù)需要讀取的數(shù)據(jù)量動態(tài)選擇編碼方案,具體方法為:(I)如果對齊后計算得到的范圍超過2個編碼條帶,至少有I個條帶已經(jīng)全覆蓋,則直接采用重構(gòu)寫;(2)如果前述計算得到的重構(gòu)讀取數(shù)據(jù)量小于增量寫讀取數(shù)據(jù)量時,則采用重構(gòu)寫;(3)以上情況以外的采用增量寫。
[0040]5、主OSD根據(jù)偏移、長度和不同更新方案計算預讀范圍,具體為:(I)重構(gòu)寫的讀取范圍:對齊后的首偏移off_begin到請求偏移off set之間為前段讀取范圍,偏移off_begin,長度(offset_off_begin);請求尾偏移offset+length到對齊后的尾偏移off_end之間為后端讀取范圍,偏移(offset+length),長度(off_end-offset_length) ; (2)增量寫的讀取范圍就是實際覆蓋寫的范圍,偏移off set,長度length;
[0041 ]然后檢查緩存中是否存在對應數(shù)據(jù)。根據(jù)請求客戶端cid檢索緩存組,如果存在,則直接提取,如果沒有則分配新的緩存組,如果空間足夠,則直接分配,如果已分配數(shù)超過預定客戶端緩存數(shù)時,從LRU鏈表中刪除末尾客戶端id,新建當前客戶端cid的緩存組索引,并加入LRU結(jié)構(gòu)。從緩存組中,根據(jù)對象oid和讀取范圍對應的數(shù)據(jù)塊序號num檢索Hashmap的索引結(jié)構(gòu),如果存在對應數(shù)據(jù)塊,則直接返回;如果不存在,則發(fā)起讀請求,在讀數(shù)據(jù)返回后將數(shù)據(jù)塊加入緩存組,在緩存滿時,根據(jù)LRU算法刪除最近最久未使用的數(shù)據(jù)塊;
[0042]檢索緩存未命中時主節(jié)點構(gòu)造讀請求,并將構(gòu)造好的讀請求發(fā)送到各個數(shù)據(jù)節(jié)點,步驟如下:(I)把讀取范圍根據(jù)每個節(jié)點的數(shù)據(jù)塊chunk長度切分,得到每個數(shù)據(jù)節(jié)點需要讀取的范圍,多個范圍在一個節(jié)點時進行合并;(2)根據(jù)偏移計算所在編碼條帶序號,將序號乘以數(shù)據(jù)塊大小,得到每個節(jié)點需要讀取的范圍的實際偏移。
[0043]6、主OSD接收完所有節(jié)點的讀取數(shù)據(jù)后,調(diào)用讀完成的回調(diào)函數(shù),準備各節(jié)點需要更新的數(shù)據(jù),其中數(shù)據(jù)塊節(jié)點的更新數(shù)據(jù)即為寫請求中數(shù)據(jù),校驗塊的更新數(shù)據(jù)根據(jù)不同更新方法來編碼構(gòu)造,重構(gòu)寫方法具體步驟:(I)合并讀取數(shù)據(jù)和更新數(shù)據(jù),得到完整的編碼條帶;(2)調(diào)用編碼函數(shù),編碼出新的校驗塊,得到更新數(shù)據(jù);增量寫方法的具體步驟:(I)以編碼數(shù)據(jù)塊大小為界,切分讀取數(shù)據(jù)和寫請求數(shù)據(jù);(2)計算切分后每組對應的請求數(shù)據(jù)和原始數(shù)據(jù)的差值;(3)根據(jù)編碼矩陣,計算差值乘以編碼矩陣中對應系數(shù),得到每一個校驗塊需要對應記錄的數(shù)據(jù);
[0044]準備好更新數(shù)據(jù)后狀態(tài)機進入寫狀態(tài),根據(jù)計算后得到的更新數(shù)據(jù)構(gòu)造寫請求,如果數(shù)據(jù)節(jié)點和主節(jié)點為同一個節(jié)點,則直接本地處理,如果數(shù)據(jù)節(jié)點和主節(jié)點為不同節(jié)點,則通過網(wǎng)絡發(fā)送到對應的數(shù)據(jù)節(jié)點和校驗塊節(jié)點,發(fā)送完后,主節(jié)點異步等待節(jié)點ACK回復;數(shù)據(jù)塊節(jié)點寫請求包括對象id,寫請求id,版本V,寫偏移,寫長度和其余附帶信息;校驗塊節(jié)點寫請求包括對象id,寫請求id,版本V,寫偏移,寫長度、更新方式和其余附帶信息。其中版本V指處理寫請求時獲取的PG中記錄日志PGLOG的最新版本號,隨著每次寫單調(diào)遞增加I;更新方式為I比特長度,O表示重構(gòu)寫,I表示增量寫。
[0045]7、數(shù)據(jù)塊節(jié)點接收寫請求后,根據(jù)對象id和版本V申請新存儲塊,同時將本次更新的對象id,版本V,偏移和長度記錄到本地更新日志PGLOG,數(shù)據(jù)塊和日志持久化后,節(jié)點發(fā)送ACK給主節(jié)點。存儲塊所在文件名為對象id,分片id,版本V的組合,每個數(shù)據(jù)塊節(jié)點的對象id和分片id固定,原始數(shù)據(jù)版本為O。這樣的分配方式,新分配的存儲塊磁盤位置會在原始對象位置附近。節(jié)點根據(jù)偏移和長度,寫入申請得新存儲塊。同時,節(jié)點將本次更新的對象id,版本V,偏移和長度記錄到本地更新日志PGL0G。數(shù)據(jù)塊和日志持久化后,節(jié)點發(fā)送ACK給主節(jié)點。
[0046]校驗塊節(jié)點接收寫請求后,同樣根據(jù)對象id和版本V申請新存儲塊,節(jié)點根據(jù)偏移和長度,寫入申請的新存儲塊,并將更新方式的I比特寫入對象元數(shù)據(jù)中,同時將本次更新的對象id,版本V,偏移和長度記錄到更新日志PGLOG,數(shù)據(jù)塊和日志持久化后,節(jié)點發(fā)送ACK給主節(jié)點。
[0047]8、主節(jié)點異步處理完所有節(jié)點的ACK后,狀態(tài)機進入完成狀態(tài),記錄本次更新到更新元數(shù)據(jù)信息,將版本V、偏移off set、長度length封裝為value保存到內(nèi)存數(shù)據(jù)結(jié)構(gòu)中以對象id為key的列表中,然后更新PG中記錄的上一次完成操作的版本變量last_complete為本次版本V,最后返回ACK給客戶端完成本次寫請求。
[0048]主OSD維護著所屬PG組的權(quán)威日志版本,變量last_complete記錄了PGLOG中上一次更新完成的版本號。前述主OSD在寫請求超時后,本次寫失敗,last_complete就不會更新,但是節(jié)點數(shù)據(jù)可能有不一致狀態(tài),部分節(jié)點完成了本次寫操作,部分節(jié)點還處于上一次一致狀態(tài)。通過PG層的周期性peering機制,檢查不一致節(jié)點發(fā)現(xiàn)更新超前,通過原子性的回滾操作保持所有節(jié)點數(shù)據(jù)一致性。具體步驟如下:
[0049]I )PG層周期性進行Peering操作,拉取同組各OSD的PGLOG版本,對比計算權(quán)威日志版本,然后各OSD的版本是否和權(quán)威版本一致,如果不一致則發(fā)送PGLOG權(quán)威版本到不一致節(jié)點;
[0050]2)不一致節(jié)點收到Peering后的權(quán)威PGL0G,進行本地的PGLOG對比合并。發(fā)現(xiàn)本地版本超前后,遍歷超前的PGLOG,將其加入to_rol Iback列表;
[0051 ] 3)處理完P(guān)GLOG版本后,PGLogEntryHand Ier遍歷 to_ro 11 back列表,讀取每一條Pglog的回滾信息,并調(diào)用對應的回滾函數(shù),讀取pglog中記錄的對象id,版本V,根據(jù)id和V索引更新時新分配的存儲塊,然后刪除存儲塊;
[0052]4)所有超前pglog回滾完成后,刪除這部分pglog,更新本地pglog為權(quán)威版本。
[0053]本發(fā)明方法根據(jù)覆蓋寫請求的塊大小自適應不同更新方法,減少磁盤和網(wǎng)絡開銷。更新后的校驗塊讀取時,需要根據(jù)對象id查找主節(jié)點的元數(shù)據(jù)信息對應的更新記錄,遍歷更新記錄,檢查是否和讀請求偏移和長度有重疊,如果沒有重疊,則按原始方法直接構(gòu)造讀請求發(fā)送對應節(jié)點;如果有重疊,則計算讀請求和各重疊部分相關(guān)的偏移和長度,將這些構(gòu)造為讀請求的額外讀中,根據(jù)數(shù)據(jù)塊大小將讀請求和額外讀劃分到各個分片的讀請求中,并發(fā)送對應各節(jié)點,校驗塊節(jié)點根據(jù)讀請求和額外讀請求,讀取對應對象數(shù)據(jù),并將額外讀請求數(shù)據(jù)按版本從小到大順序合并入原始數(shù)據(jù),合并過程中,檢查額外讀數(shù)據(jù)元數(shù)據(jù)信息中的更新方法,如果是重構(gòu)寫,則直接合并,如果是增量寫,則計算對應位置原始數(shù)據(jù)和額外讀數(shù)據(jù)的和,再合并,然后返回主節(jié)點。
[0054]讀取過程需要讀取額外的更新數(shù)據(jù),所以更新數(shù)據(jù)需要定期合并入原始數(shù)據(jù),以加快讀取過程。在每次寫完成后,主節(jié)點根據(jù)對象元數(shù)據(jù),檢查累計更新次數(shù),更新大小,默認達到10次更新大小達到一個編碼條帶大小后,由主節(jié)點生成更新請求,將對象id,所有合并版本,發(fā)送到各個節(jié)點。各節(jié)點接收請求,以版本從小到大開始處理,根據(jù)對象i d,版本V,檢索出該次更新偏移和長度,讀取對應數(shù)據(jù),類似于讀請求的處理,利用復制函數(shù),將新數(shù)據(jù)寫入原始數(shù)據(jù)對應偏移。校驗塊的更新合并需要檢查對應更新方法,重構(gòu)寫可以直接寫入,增量寫需要類似讀取原始數(shù)據(jù),計算后再寫入。各節(jié)點的數(shù)據(jù)寫入操作為原子操作。主節(jié)點接收所有節(jié)點回滾ACK后刪除對應對象的更新元數(shù)據(jù),完成合并操作。
[0055]下面以糾刪碼RS(4,2)為例說明本發(fā)明方法,即原始數(shù)據(jù)塊切成4塊,經(jīng)過RS編碼出2塊校驗塊,所有涉及的運算皆為RS編碼中的有限域運算。以4MB大小作為編碼條帶,其中每個節(jié)點都會存儲編碼條帶中IMB大小的數(shù)據(jù)塊,原始文件會以4MB為大小切分成多個編碼條帶。一個PG組包含6個存儲節(jié)點OSD,其中前4個節(jié)點存儲原始數(shù)據(jù)塊,稱為數(shù)據(jù)節(jié)點,第2個節(jié)點存儲編碼塊,稱為校驗塊節(jié)點,并且數(shù)據(jù)節(jié)點中第I塊數(shù)據(jù)塊所在節(jié)點為主0SD。寫請求由額外的I個客戶端節(jié)點發(fā)起。
[0056]圖1中表示CEPH系統(tǒng)中糾刪碼實現(xiàn)的條帶化存儲。原始對象數(shù)據(jù)按照預定的條帶大小4冊切分,最后不足時補零。條帶數(shù)據(jù)按等大切分為4塊(10、(11、(12、(13,然后編碼出校驗塊p0、pl,分別存儲到6個OSD節(jié)點。然后再取下一個條帶,編碼后追加到之前存儲的數(shù)據(jù)之后。一個PG組包含了以條帶形式存儲的6個0SD,其中第一個節(jié)點即O號節(jié)點為主0SD,負責接收客戶端寫請求,以及分發(fā)存儲數(shù)據(jù),維護著數(shù)據(jù)的一致性。
[0057]圖2中表示CEPH系統(tǒng)中實現(xiàn)的糾刪碼覆蓋寫時序圖。包括客戶端發(fā)起寫請求到主節(jié)點,主節(jié)點分析寫請求,選定編碼方法后構(gòu)造對應的讀請求,發(fā)送給對應數(shù)據(jù)塊OSD,然后異步等待數(shù)據(jù)返回。主OSD收到所有數(shù)據(jù)后,根據(jù)選定的編碼方法編碼校驗塊數(shù)據(jù),然后將需要更新的校驗塊和數(shù)據(jù)塊發(fā)送給對應OSD,各節(jié)點保存完數(shù)據(jù)后,回復ACK給主OSD,主OSD接收所有回復后將本地更新元數(shù)據(jù)寫入本地的緩存并返回客戶端完成寫請求。上述過程分別對應狀態(tài)機中讀狀態(tài)、寫狀態(tài)、完成狀態(tài)的請求的處理與發(fā)送過程。
[0058]圖3中表示CEPH系統(tǒng)中糾刪碼覆蓋寫更新的重構(gòu)寫樣例。其DO’、D1’、D2’表示更新數(shù)據(jù)。主OSD接收覆蓋寫數(shù)據(jù)后,計算重構(gòu)寫需要預讀D3,增量寫需要預讀D0、D1、D2,判斷重構(gòu)寫需要預讀的數(shù)據(jù)塊較少,所以選擇重構(gòu)寫方案。主OSD確定方案后向D3所在的OSD發(fā)起讀請求,對應OSD回復數(shù)據(jù)后,主OSD能夠組成完整的編碼條帶,重新編碼出校驗塊PO’和P1’,然后將更新數(shù)據(jù)發(fā)送給各個0SD,并把更新元數(shù)據(jù)記錄到pglog中。其中D3沒有更新數(shù)據(jù),所以只記錄本次的更新元數(shù)據(jù)。
[0059]為保證數(shù)據(jù)更新不丟失原始數(shù)據(jù),保持數(shù)據(jù)一致性,所以更新數(shù)據(jù)不寫入原始數(shù)據(jù)塊。根據(jù)對象id和版本V,索引并分配新的存儲塊,例如圖中新分配的灰色塊。在更新失敗觸發(fā)回滾時,需要刪除對應的更新塊。
[0060]圖4中CEPH中糾刪碼覆蓋寫的增量更新方式示意圖。D0’表示覆蓋寫更新數(shù)據(jù),其余概念同圖3說明。主OSD接收覆蓋寫數(shù)據(jù)后,計算重構(gòu)寫需要預讀D1、D2、D3,增量寫需要預讀D0,判斷增量寫需要預讀的數(shù)據(jù)塊較少,所以選擇重構(gòu)寫方案。主OSD確定方案后向DO所在的OSD發(fā)起讀請求,對應OSD回復數(shù)據(jù)后,主OSD計算更新校驗塊需要的△ P,然后將對應更新數(shù)據(jù)塊和校驗塊發(fā)送到對應0SD。同樣,Dl、D2、D3所在OSD沒有參與數(shù)據(jù)更新,只記錄Pglog,保持數(shù)據(jù)版本一致。
【主權(quán)項】
1.一種分布式存儲CEPH的糾刪碼覆蓋寫方法,其特征在于,包括以下步驟: 1)客戶端節(jié)點發(fā)送寫請求到Ceph的存儲節(jié)點中的主OSD,主OSD自動選擇最優(yōu)編碼方案后,計算需要讀取的數(shù)據(jù)塊,并根據(jù)客戶端id和對象id,從緩存中讀取數(shù)據(jù)塊返回主0SD; 2)主OSD在接收完所有需要的讀數(shù)據(jù)塊后,將數(shù)據(jù)塊存入緩存結(jié)構(gòu),并根據(jù)對應編碼方法計算校驗塊更新所需的數(shù)據(jù),然后更新數(shù)據(jù)塊和校驗塊,發(fā)送到需要更新的對應0SD; 3)數(shù)據(jù)塊節(jié)點和校驗塊節(jié)點接收寫請求,分配原始數(shù)據(jù)塊附近的新存儲位置存儲新更新,并記錄本次寫請求元數(shù)據(jù)到日志PGLOG,數(shù)據(jù)和日志落盤后發(fā)送ACK給主OSD; 4)主OSD接收所有更新節(jié)點的ACK后,記錄本次更新元數(shù)據(jù)到內(nèi)存,并回復ACK給客戶端,完成與請求。2.根據(jù)權(quán)利要求1所述的分布式存儲CEPH的糾刪碼覆蓋寫方法,其特征在于,步驟I確定最優(yōu)編碼方案的具體步驟為: 1)計算寫請求涉及的編碼條帶范圍:首先對齊寫請求偏移到所在編碼條帶的首位置;然后根據(jù)寫請求長度計算寫范圍的末尾偏移,并對齊到所在條帶的末位置;最后根據(jù)對齊后的首偏移和尾偏移,得到覆蓋寫請求的條帶覆蓋范圍偏移和長度; 2)根據(jù)寫請求的偏移和長度結(jié)合條帶覆蓋范圍,計算不同編碼方案需要預先讀取的數(shù)據(jù)量:重構(gòu)寫需要讀取數(shù)據(jù)量=對齊后計算得到的范圍減去實際更新數(shù)據(jù)量;增量寫需要讀取數(shù)據(jù)量=實際更新數(shù)據(jù)量; 3)根據(jù)需要讀取的數(shù)據(jù)量動態(tài)選擇編碼方案:若對齊后計算得到的范圍超過2個編碼條帶且至少有I個條帶已經(jīng)全覆蓋,或者重構(gòu)讀取數(shù)據(jù)量小于增量寫讀取數(shù)據(jù)量,則采用重構(gòu)寫;否則,采用增量寫。3.根據(jù)權(quán)利要求1所述的分布式存儲CEPH的糾刪碼覆蓋寫方法,其特征在于,步驟I主OSD從緩存中讀取數(shù)據(jù)塊的具體方法為: 1)根據(jù)請求客戶端cid檢索緩存組,如果存在,則直接提取,如果沒有則分配新的緩存組,如果空間足夠,則直接分配,如果已分配數(shù)超過預定客戶端緩存數(shù)時,從LRU鏈表中刪除末尾客戶端id,新建當前客戶端cid的緩存組索引,并加入LRU結(jié)構(gòu); 2)從緩存組中,根據(jù)對象oid和讀取范圍對應的數(shù)據(jù)塊序號num檢索Hashmap的索引結(jié)構(gòu),如果存在對應數(shù)據(jù)塊,則直接返回;如果不存在,則發(fā)起讀請求,在讀數(shù)據(jù)返回后將數(shù)據(jù)塊加入緩存組,在緩存滿時,根據(jù)LRU算法刪除最近最久未使用的數(shù)據(jù)塊。4.根據(jù)權(quán)利要求1所述的分布式存儲CEPH的糾刪碼覆蓋寫方法,其特征在于,步驟2選擇不同的編碼方案時,更新校驗塊所需的數(shù)據(jù)量和方法不同,具體為: 采用重構(gòu)寫時,讀取覆蓋寫范圍以外的條帶數(shù)據(jù),在讀取對應數(shù)據(jù)后,和覆蓋數(shù)據(jù)合并成新的完整塊,編碼出新的校驗塊; 采用增量寫時,讀取覆蓋寫范圍以內(nèi)的條帶數(shù)據(jù),直接讀取新數(shù)據(jù)并返回,在讀取對應數(shù)據(jù)后,計算覆蓋數(shù)據(jù)D’和原始數(shù)據(jù)D的有限域差值△ D,然后計算△ D乘以對應編碼系數(shù)的有限域乘后發(fā)送到對應的校驗塊存儲節(jié)點。5.根據(jù)權(quán)利要求1所述的分布式存儲CEPH的糾刪碼覆蓋寫方法,其特征在于,當主OSD接收所有更新節(jié)點的ACK回復超即更新失敗時,該方法還包括恢復數(shù)據(jù)的步驟。6.根據(jù)權(quán)利要求5所述的分布式存儲CEPH的糾刪碼覆蓋寫方法,其特征在于,采用基于PGLOG日志的回滾機制恢復數(shù)據(jù),具體為: I)PG層周期性進行Peering操作,拉取同組各OSD的PGLOG版本,對比各OSD的版本是否和權(quán)威版本一致,若一致,則不做處理,若不一致,則發(fā)送PGLOG權(quán)威版本到不一致節(jié)點; 2)不一致節(jié)點收到Peering后的權(quán)威PGL0G,進行本地的PGLOG對比合并,發(fā)現(xiàn)本地版本超前后,遍歷超前的PGLOG,將其加入to_rol Iback列表; 3)處理完P(guān)GLOG 版本后,PGLogEntryHandl er 遍歷 to_ro I Iback 列表,讀取每一條 pglog的回滾信息,并調(diào)用對應的回滾函數(shù),讀取Pglog中記錄的對象id,版本V,根據(jù)id和V索引更新時新分配的存儲塊,然后刪除存儲塊; 4)所有超前pglog回滾完成后,刪除這部分pglog,更新本地pglog為權(quán)威版本。7.根據(jù)根據(jù)權(quán)利要求1所述的分布式存儲CEPH的糾刪碼覆蓋寫方法,其特征在于,該方法不同編碼方案對應的更新后校驗塊讀取過程不同,具體為: 1)根據(jù)對象id查找主節(jié)點的元數(shù)據(jù)信息對應的更新記錄,遍歷更新記錄,檢查是否和讀請求偏移和長度有重疊,如果沒有重疊,則按原始方法直接構(gòu)造讀請求發(fā)送對應節(jié)點;如果有重疊,則跳轉(zhuǎn)步驟2; 2)計算讀請求和各重疊部分相關(guān)的偏移和長度,將這些構(gòu)造為讀請求的額外讀中,根據(jù)數(shù)據(jù)塊大小將讀請求和額外讀劃分到各個分片的讀請求中,并發(fā)送對應各節(jié)點;校驗塊節(jié)點根據(jù)讀請求和額外讀請求,讀取對應對象數(shù)據(jù),并將額外讀請求數(shù)據(jù)按版本從小到大順序合并入原始數(shù)據(jù),合并過程中,檢查額外讀數(shù)據(jù)元數(shù)據(jù)信息中的更新方法,如果是重構(gòu)寫,則直接合并,如果是增量寫,則計算對應位置原始數(shù)據(jù)和額外讀數(shù)據(jù)的和,再合并,然后返回主節(jié)點。
【文檔編號】G06F11/10GK105930103SQ201610305978
【公開日】2016年9月7日
【申請日】2016年5月10日
【發(fā)明人】瞿天善, 葉保留, 陸桑璐
【申請人】南京大學