本發(fā)明涉及數(shù)據(jù)存儲領域。具體地,本發(fā)明的實施例涉及用于描述圖形數(shù)據(jù)的三元組在分布式存儲環(huán)境內(nèi)的存儲。
背景技術:關系數(shù)據(jù)庫按照行與列來存儲數(shù)據(jù)。行與列組成了需要在存儲數(shù)據(jù)之前被限定的表。對這些表以及對包含在這些表上的數(shù)據(jù)之間的關系的限定被稱為模式。關系數(shù)據(jù)庫使用固定的模式。通過以節(jié)點和弧的形式存儲數(shù)據(jù),圖形數(shù)據(jù)庫表現(xiàn)出對關系數(shù)據(jù)庫的顯著擴展,其中節(jié)點表示實體或實例,弧表示任意兩個節(jié)點之間的某種類型的關系。在無向圖中,認為從節(jié)點A至節(jié)點B的弧與從節(jié)點B至節(jié)點A的弧相同。而在有向圖中,這兩個方向被處理為不同的弧。圖形數(shù)據(jù)庫用于各種不同的應用,這些應用一般可以分為兩種主要類型。第一種類型由具有較大的類描述集的復雜的基于知識的系統(tǒng)組成(稱為“基于知識的應用”),如智能決策支持及自學習。第二種類型包括涉及對交易數(shù)據(jù)進行圖形搜索的應用(稱為“交易數(shù)據(jù)應用”),如社交數(shù)據(jù)及商業(yè)智能。很多應用可以同時表現(xiàn)出這兩個類型。但是,大多數(shù)應用可以主要地表征為基于知識的應用或交易數(shù)據(jù)應用。圖形數(shù)據(jù)庫可以用于維護能夠將大量的結構化或非結構化數(shù)據(jù)存儲在各種字段中的大型“語義網(wǎng)絡”。語義網(wǎng)絡以知識表示的形式被使用,并且是由表示概念的節(jié)點和表示這些概念之間的語義關系的弧組成的有向圖。有多種類型的圖形表示。圖形數(shù)據(jù)可以作為多維數(shù)組或作為鏈接至其他符號的符號來存儲在存儲器中。另一種形式的圖形表示是“元組”的使用,“元組”是由每個都具有特定類型的對象組成的有限序列或有序列表。已知包含n個對象的元組為“n元組”,其中n可以是大于0的任意非負整數(shù)。通常將長度為2的元組(2-元組)稱為對(pair),將3-元組稱為三元組,將4-元組稱為四元組等等。資源描述框架(RDF)是作為語義網(wǎng)絡標準的用于概念描述或信息建模的一般方法。當今可用的RDF數(shù)據(jù)量在不斷地增長并且已經(jīng)不可能將其存儲在單個服務器中。為了能夠存儲和搜索大量的數(shù)據(jù),必須在多個服務器中對數(shù)據(jù)進行維護。必須使用針對分布式系統(tǒng)專門定制的算法和數(shù)據(jù)結構以協(xié)同的方式來完成數(shù)據(jù)的添加、刪除和查詢。期望以使得能夠進行計算效率高的數(shù)據(jù)查詢、維護和操作的方式來存儲圖形數(shù)據(jù)。如同所有的計算硬件一樣,也總是存在存儲數(shù)據(jù)的存儲節(jié)點(如服務器)會出現(xiàn)故障的某種風險。因此,已知在本領域中提供存儲數(shù)據(jù)拷貝的“冗余”存儲節(jié)點以防存儲節(jié)點出現(xiàn)故障。但是,從基礎設施的提供、維護及運行成本的方面來講,提供這樣的冗余存儲節(jié)點會很昂貴。隨著存儲節(jié)點的可靠性的增加,從單次使用成本方面來講,單純?yōu)榱嗽诹硪粋€節(jié)點出現(xiàn)故障時能夠進行數(shù)據(jù)恢復而提供冗余存儲節(jié)點的價值在不斷減小。
技術實現(xiàn)要素:本發(fā)明的實施例提供了用于存儲被編碼為三元組的圖形數(shù)據(jù)的數(shù)據(jù)庫的數(shù)據(jù)庫控制器,每個三元組包括主語、謂語和賓語,并且每個三元組存儲在數(shù)據(jù)項集合中的數(shù)據(jù)項內(nèi),所述數(shù)據(jù)項集合是根據(jù)存儲在數(shù)據(jù)項內(nèi)的三元組來排序的。每個數(shù)據(jù)項存儲在分布于網(wǎng)絡中的多個存儲節(jié)點中的存儲節(jié)點中。該數(shù)據(jù)庫控制器包括:存儲請求接收器,其被配置成接收在該數(shù)據(jù)庫中存儲三元組的請求;以及數(shù)據(jù)項生成模塊,其被配置成生成兩個或更多個數(shù)據(jù)項,每個數(shù)據(jù)項具有三元組的以下不同版本:第一版本,其中在數(shù)據(jù)項中主語在謂語和賓語之前;第二版本,其中在數(shù)據(jù)項中謂語在主語和賓語之前;以及第三版本,其中在數(shù)據(jù)項中賓語在主語和謂語之前。數(shù)據(jù)庫控制器還包括:指令分配器,其被配置成針對所述兩個或更多個數(shù)據(jù)項中的每一個數(shù)據(jù)項,從所述多個存儲節(jié)點中選擇存儲節(jié)點以指示存儲該數(shù)據(jù)項,該選擇是依靠該數(shù)據(jù)項在所述經(jīng)排序的集合中的位置做出的。所述指令分配器包括冗余模塊,所述冗余模塊被配置成確保指示所述多個存儲節(jié)點中的至少兩個不同存儲節(jié)點存儲包括三元組的版本的數(shù)據(jù)項。有利地,本發(fā)明的實施例提供了容錯分布式存儲系統(tǒng),其利用排序來存儲和查詢被存儲為三元組的圖形數(shù)據(jù)。實施例提供或實現(xiàn)了以下用于存儲數(shù)據(jù)的技術:所述技術使得在對所存儲的數(shù)據(jù)的范圍查詢的執(zhí)行上以及當存儲節(jié)點出現(xiàn)故障時對所存儲的數(shù)據(jù)的恢復上都具有很高的效率。為了執(zhí)行有效的范圍查詢(rangequery),按照至少兩種(例如,三種)不同的順序,例如,SPO、POS和OSP(其中貫穿本文獻,可以用P表示謂語,用S表示主語,以及用O表示賓語)中的兩種(或三種),來存儲三元組。同一三元組的兩個或更多個版本中的首項元素的變化是頭等重要的。雖然不是必需的,但也期望剩余兩個元素的位置的變化。所述冗余模塊或等同的功能確保出于有效的范圍查詢目的而提供的三元組的至少兩個不同版本還可以充當副本,以便當存儲節(jié)點出現(xiàn)故障時提供容錯性??傊?,本發(fā)明的實施例提供了以下數(shù)據(jù)庫,該數(shù)據(jù)庫將圖形數(shù)據(jù)存儲為按兩個或更多個版本復制的編碼三元組,其中每個版本(以其被存儲的形式)將該三元組的不同元素作為首項元素以提供有效的范圍查詢;并且該數(shù)據(jù)庫還使用那些復制的版本來提供數(shù)據(jù)冗余以進行丟失數(shù)據(jù)的再生。在本發(fā)明的實施例中,每個三元組(如RDF三元組)被存儲為數(shù)據(jù)項或數(shù)據(jù)項的一部分,例如存儲為簡單的字符串對象,并且在圖形G中是唯一的。所以關于G的所有信息都保存在數(shù)據(jù)項中。三元組作為數(shù)據(jù)項(按照數(shù)據(jù)項來編碼)被存儲在有序數(shù)據(jù)集合中,該有序數(shù)據(jù)集合分布在分布式網(wǎng)絡環(huán)境(如對等網(wǎng)絡環(huán)境)中的網(wǎng)絡存儲節(jié)點中的處理中。運行在每個存儲節(jié)點上的處理有利于存儲數(shù)據(jù)項的有序子集。該處理和運行該處理的網(wǎng)絡存儲節(jié)點在本文獻中或多或少可互換地被引用,從上下文中可以清楚地看出何時專門地意指前者或后者。本發(fā)明的實施例使得能夠對數(shù)據(jù)運行有效的查詢過程。例如,對dmin與dmax(當按次序放置時)之間的數(shù)據(jù)項范圍進行檢索的過程執(zhí)行以下步驟:客戶端應用程序向處理之一A發(fā)送請求;A執(zhí)行映射功能,獲取該處理的包含所請求的數(shù)據(jù)范圍的一個子集的各個存儲節(jié)點ID(或標記)(在示例性情況下,數(shù)據(jù)項均勻地分布并且每個處理負責存儲大量的數(shù)據(jù)項)。例如,考慮客戶端應用程序請求的數(shù)據(jù)項存儲在處理A和處理B中;A向自身和向B廣播對所請求的數(shù)據(jù)項的每個子集進行檢索的請求;每個處理以所請求的數(shù)據(jù)項來回復A;A收集結果(保持它們的順序)并且回復客戶端應用程序。從上面的示例可以看出,本發(fā)明的實施例能夠更有效地查詢數(shù)據(jù)。此外,如在使用常規(guī)技術的情況下一樣,不需要按請求中的每個數(shù)據(jù)項來重復步驟。本發(fā)明的實施例中的圖形數(shù)據(jù)可以是有向圖形數(shù)據(jù),所以從第一圖形節(jié)點至第二圖形節(jié)點的弧不被認為是與從第二圖形節(jié)點至第一圖形節(jié)點的弧相同。語義網(wǎng)絡形成為知識或信息的表示,其中圖形節(jié)點表示概念如實體或實例,而弧表示概念之間的語義關系。在本發(fā)明的實施例中,將圖形數(shù)據(jù)編碼為三元組,所述三元組是三個對象的有限序列或有序列表,每個對象都具有特定類型。可選地,三元組可以是資源描述框架(RDF)三元組。貫穿本文獻,應當理解,在引用“RDF三元組”的地方,它是三元組的示例性形式,遵守RDF標準。此外,對“三元組”的引用包括正在討論的三元組是RDF三元組的可能性。類似地,在本文獻其他地方所討論的RDF處理器是用于API包裝器與所存儲的數(shù)據(jù)項之間的交互的處理器的示例。資源描述框架(RDF)是作為語義網(wǎng)絡的標準的用于概念描述或信息建模的一般方法。對語義網(wǎng)絡中的信息建模進行的標準化允許運行在共用語義網(wǎng)絡上的應用程序之間的互操作性。RDF通過提供作為用于描述RDF中的詞匯表的語言的RDF模式(RDFS),來維護具有明確的正式語義的詞匯表??蛇x地,三元組的元素中的一個或更多個元素中的每一個元素(元素是謂語、賓語或主語)是統(tǒng)一資源標識符(URI)。RDF和其他三元組格式是以以下概念為前提的:使用如URI等網(wǎng)絡標識符來標識事物(即,對象、資源或實例),并且從簡單的屬性和屬性值方面來描述那些所標識的“事物”。從三元組方面來講,主語可以是用于標識用于描述實體的網(wǎng)絡資源的URI,謂語可以是用于標識屬性的類型(例如顏色)的URI,并且賓語可以是用于指示具有特定類型屬性的具體實例的URI,所述特定類型屬性在其網(wǎng)絡資源具體化方面歸屬于所述實體。URI的使用使得三元組能夠將關于資源的簡單語句表示為由表示資源以及它們各自的屬性和值的節(jié)點和弧組成的圖形??梢允褂肧PARQL協(xié)議和RDF查詢語言(SPARQL)來查詢RDF圖形。這由萬維網(wǎng)聯(lián)盟的RDF數(shù)據(jù)存取工作組(DAWG)標準化,并且被認為是一種關鍵的語義網(wǎng)絡技術。SPARQL允許由三元組模式、與運算、或運算和可選模式組成的查詢。三元組通過將圖形數(shù)據(jù)表征為多個主謂賓表達式來進行圖形數(shù)據(jù)的編碼。在該情況下,主語和賓語是圖形數(shù)據(jù)的圖形節(jié)點,如實體、對象、實例或概念,并且謂語是主語與賓語之間的關系的表示。謂語通過提供與賓語的特定類型的聯(lián)系來斷言與主語有關的事情。例如,主語可以指示網(wǎng)絡資源(例如,通過URI),謂語指示資源的特定特性、特征或方面,賓語指定該特性、特征或方面的實例。換言之,三元組語句的集合固有地表示有向圖形數(shù)據(jù)。RDF標準提供這樣的三元組的正式化結構。存儲節(jié)點的分布式網(wǎng)絡包括由彼此進行通信的不止一個不同存儲單元組成的系統(tǒng)。示例性通信范例是對等型(P2P),因此存儲節(jié)點的分布式網(wǎng)絡可以是存儲節(jié)點的對等網(wǎng)絡。P2P是在對等體(peer)之間劃分任務或工作量的分布式結構。對等體(各個存儲節(jié)點或處理)是應用中等同地被特許的同等參與者。每個對等體被配置成使得其資源(如處理能力、磁盤存儲器或網(wǎng)絡帶寬)的一部分直接可用于其他網(wǎng)絡參與者,而不需要服務器或穩(wěn)定主機的中心協(xié)調。相比服務器提供以及客戶端消耗的傳統(tǒng)的客戶端-服務器模型,對等體可以認為是資源的提供者和消耗者兩者。有利地,P2P系統(tǒng)能夠以對數(shù)通信成本來維護交換消息的大批存儲節(jié)點。在實施例中,例如在三元組的賓語很復雜的那些實施例中,存儲在有序數(shù)據(jù)項中的賓語可以是針對該賓語生成的通用唯一ID(UUID)。該選項在用于以下實現(xiàn)場景中的實施例中是很有用的,在所述實現(xiàn)場景中賓語很大,因此它們的大小降低了范圍查詢過程的效率。在本發(fā)明的實施例中,三元組存儲在有序數(shù)據(jù)項中,所以返回數(shù)據(jù)項的查詢使得三元組的表示能夠被檢索。如果同一三元組的不同版本存儲在不止一個不同存儲節(jié)點上,則出于有效的范圍查詢目的對上述不同版本進行的存儲還可以有益于數(shù)據(jù)恢復。因此,本發(fā)明的實施例中冗余模塊的提供消除了以下需要:復制每個數(shù)據(jù)項以提供數(shù)據(jù)冗余,使得能夠當存儲節(jié)點出現(xiàn)故障時進行恢復??蛇x地,數(shù)據(jù)項生成模塊被配置成生成三個數(shù)據(jù)項,每個數(shù)據(jù)項具有三元組的第一版本、第二版本和第三版本中的不同版本。有利地,使數(shù)據(jù)項具有三元組的三個不同版本使得能夠通過三元組的三個元素中的任一元素來進行有效的范圍查詢。也就是說,可以指定主語、賓語或謂語的范圍,并且以有效的方式返回存儲包括在該范圍內(nèi)的三元組的數(shù)據(jù)項。可以將冗余模塊配置成確保指示至少兩個不同存儲節(jié)點中的每一個節(jié)點存儲包括該三元組的不同版本的數(shù)據(jù)項。例如,在所述多個存儲節(jié)點中有三個或更多個存儲節(jié)點的實施例中,可以將冗余模塊配置成確保指示所述多個存儲節(jié)點中的三個不同存儲節(jié)點中的每一個存儲節(jié)點存儲包括該三元組的不同版本的數(shù)據(jù)項。在該特定的實現(xiàn)中,存儲三元組的三個不同版本的數(shù)據(jù)項自身分布在網(wǎng)絡中的三個不同的存儲節(jié)點上(每存儲節(jié)點分布一個數(shù)據(jù)項)。這是有利的,這是因為應用三元組的三個不同版本的優(yōu)點,另外,如果存儲那些版本中的任何一個的存儲節(jié)點出現(xiàn)故障,則有兩個其他存儲節(jié)點還存儲著該三元組的版本,所以存儲在故障存儲節(jié)點上的版本可以以有效的方式重新生成??商娲?,可以將冗余模塊配置成確保三個不同存儲節(jié)點中的每個存儲節(jié)點都存儲三元組的版本,但是它們不必是不同的版本。例如,如果指令分配器所執(zhí)行的映射過程導致同一三元組的兩個不同版本在一個存儲節(jié)點上而另一個不同版本在另一個節(jié)點上,則冗余模塊可以簡單地生成該三元組的特定版本(例如,SPO)的副本以存儲在第三個存儲節(jié)點上,而不管在所述一個存儲節(jié)點和所述另一個存儲節(jié)點中的每一個存儲節(jié)點上存儲的是該三元組的哪一個現(xiàn)有版本。在本發(fā)明的實施例中,可以按照表示三元組的元素的字符串對象的詞典順序來對數(shù)據(jù)項進行排序,字符串對象是數(shù)據(jù)項或包括在數(shù)據(jù)項中。例如,詞典順序可以是字母順序。在本發(fā)明的實施例的實現(xiàn)中,可以期望通過選定數(shù)據(jù)項的主語、謂語或賓語(或賓語的UUID)來查詢數(shù)據(jù)項的集合。為了有效地返回這樣的查詢的結果,在數(shù)據(jù)項中將三元組的兩個或更多個元素存儲為第一元素是有利的。排序的數(shù)據(jù)項使得能夠做出數(shù)據(jù)項之間的比較并且執(zhí)行范圍查詢。D1與D2(其中D1<D2)之間的范圍查詢是以下查詢:該查詢根據(jù)數(shù)據(jù)項的某種預定排序標準來返回包含在大于D1而小于D2的數(shù)據(jù)項的經(jīng)排序的集合中的數(shù)據(jù)項。當然,該數(shù)據(jù)項集合被劃分到節(jié)點的分布式網(wǎng)絡的節(jié)點(其中節(jié)點是如服務器或運行在那些服務器上的處理等資源)中。在示例性實施例中,由如代表應用程序的RDF處理器等處理器通過向節(jié)點之一發(fā)送查詢來發(fā)起范圍查詢。節(jié)點被配置成例如通過對D1和D2應用數(shù)據(jù)項的邏輯表示并且對這些節(jié)點執(zhí)行子范圍查詢來計算哪些其他節(jié)點具有查詢所尋找的數(shù)據(jù)項。節(jié)點則被配置成收集結果(保持數(shù)據(jù)項的順序)并且將結果返回給發(fā)起該查詢的處理器。從三元組在數(shù)據(jù)項內(nèi)的存儲形式來講,每個數(shù)據(jù)項可以包括字符串對象,所述字符串對象包括對應三元組的主語、謂語和賓語。有利地,字符串對象是普遍可讀的并且建立了用于其比較的例程,并且存在其他處理需求。數(shù)據(jù)庫自身和訪問數(shù)據(jù)庫的應用程序可以具有良好建立了的例程以用于處理字符串對象。此外,字符串對象易于快速搜索和比較(順序)。在這樣的實施例中,可以根據(jù)字符串對象的字母順序比較來對數(shù)據(jù)項進行排序。有利地,如搜索、測距和其他比較功能等數(shù)據(jù)庫功能是可用的,這些數(shù)據(jù)庫功能在比較字符串數(shù)據(jù)對象的字母順序內(nèi)容的計算效率方面被優(yōu)化。因此,以此方式對數(shù)據(jù)項進行排序的實施例在計算效率方面特別有效。在這樣的實施例中,可以根據(jù)數(shù)據(jù)項的字符串對象的字母順序來對數(shù)據(jù)項進行排序。數(shù)據(jù)項可以僅僅是字符串對象,或它們可以包括其他對象或數(shù)據(jù)。字符串是字母數(shù)字符號的序列??蛇x地,可以將指令分配器配置成通過使用有序哈希表來從所述多個存儲節(jié)點中選擇存儲節(jié)點以指示存儲數(shù)據(jù)項。有利地,哈希表提供了將數(shù)據(jù)項映射(其中映射從含義上等同于從所述多個存儲節(jié)點中選擇存儲節(jié)點以指示存儲數(shù)據(jù)項)至節(jié)點的計算效率高的方法。有序哈希表使用哈希函數(shù)來基于數(shù)據(jù)項的內(nèi)容將數(shù)據(jù)項分配至節(jié)點。在鍵值系統(tǒng)中,哈希表或哈希圖是使用哈希函數(shù)將標識已知為鍵的值映射至它們相關聯(lián)的值的數(shù)據(jù)結構。因此,可以說哈希表實現(xiàn)了關聯(lián)數(shù)組。哈希函數(shù)用于將鍵變換成其中對應的值要被尋找的數(shù)組元素(存儲位置,也稱為縫或槽)的索引(哈希)??蛇x地,有序哈希表可以使用一致性哈希函數(shù)。一致性哈希處理規(guī)定了需要響應于存儲數(shù)據(jù)項的存儲節(jié)點的數(shù)量變化來重新映射的有序數(shù)據(jù)項的數(shù)量。例如,考慮D個數(shù)據(jù)項分布在對等系統(tǒng)中的n-1個“對等體”中的系統(tǒng)。如果新的對等體加入到該系統(tǒng)中,則僅需要重新映射D/n個鍵。在一致性哈希處理中,如果有新的對等體添加至該系統(tǒng)中,則該對等體從其他對等體取得所存儲數(shù)據(jù)項的近似相等的份額,并且當移除對等體時,其數(shù)據(jù)項在剩余的對等體之間分配。由指令分配器用來選擇存儲節(jié)點以指示存儲具體數(shù)據(jù)項的技術,無論是哈希函數(shù)還是其他技術,該技術都應該是確定性的。也就是說,從多個存儲節(jié)點中選擇存儲節(jié)點以指示存儲數(shù)據(jù)項是確定性選擇。因此,該選擇的結果可以由網(wǎng)絡中的另一個數(shù)據(jù)庫控制器或在后后續(xù)操作中由同一數(shù)據(jù)庫控制器來確定。在具有不止一個數(shù)據(jù)庫控制器的實施例中,每個數(shù)據(jù)庫控制器使用相同的確定性選擇過程由,所以在給出相同的輸入變量的情況下,會產(chǎn)生相同的結果。關于KVS布置的值中的附加信息或是關于以三元組存儲在數(shù)據(jù)項中的數(shù)據(jù),在本發(fā)明的實施例中,存儲同一三元組的不同版本的兩個或更多個數(shù)據(jù)項中的每一個數(shù)據(jù)項還可以包括用于標識存有該三元組的不同版本的其他數(shù)據(jù)項中的每一個數(shù)據(jù)項所存儲于的存儲節(jié)點的數(shù)據(jù)。有利地,包括標識存有同一三元組的不同版本的其他數(shù)據(jù)項中的每一個數(shù)據(jù)項所存儲于的存儲節(jié)點的數(shù)據(jù)使得存儲在還沒有出現(xiàn)故障的節(jié)點上的數(shù)據(jù)項能夠用于識別存儲在故障節(jié)點上的數(shù)據(jù)項,因此需要被恢復或重新生成。存儲節(jié)點可由ID來標識,并且可以對ID進行重新排序,以使得當數(shù)據(jù)項分布在存儲節(jié)點的網(wǎng)絡中并且被存儲時,數(shù)據(jù)項的經(jīng)排序的集合的順序被保持。例如,可以通過對存儲節(jié)點在該網(wǎng)絡中的地址應用哈希函數(shù)來獲得ID。用于實施本發(fā)明的數(shù)據(jù)庫控制器還可以包括故障檢測器,該故障檢測器被配置成檢測存儲節(jié)點的分布式網(wǎng)絡中的存儲節(jié)點何時出現(xiàn)了故障并且識別存儲在故障存儲節(jié)點上的數(shù)據(jù)項項內(nèi)的三元組,其中數(shù)據(jù)庫控制器被配置成針對每個所識別的三元組在數(shù)據(jù)項生成模塊處執(zhí)行生成處理以及在指令分配器處執(zhí)行選擇處理,其中故障節(jié)點被從在其中選擇存儲節(jié)點的多個存儲節(jié)點中排除。所述指令分配器被配置成指示所選擇的存儲節(jié)點存儲具有所識別的三元組的版本的數(shù)據(jù)項,并且被配置成指示將現(xiàn)在沒有被選擇的存儲節(jié)點在故障之前存儲的具有所識別的三元組的版本的任何數(shù)據(jù)項移除。有利地,故障檢測器和數(shù)據(jù)庫控制器的關聯(lián)功能在存儲節(jié)點故障的情況下提供有效的數(shù)據(jù)恢復處理,同時最小化與單純出于數(shù)據(jù)恢復目的而存儲拷貝有關的系統(tǒng)成本??蛇x地,在實施本發(fā)明的數(shù)據(jù)庫控制器中,冗余模塊可以被配置成:在針對所述兩個或更多個數(shù)據(jù)項而進行存儲節(jié)點選擇之后,獲得所選的用于存儲所述兩個或更多個數(shù)據(jù)項的存儲節(jié)點中的不同存儲節(jié)點的數(shù)量的計數(shù),并且如果該計數(shù)小于冗余模塊被配置成確保其被指示存儲包括該三元組的版本的數(shù)據(jù)項的不同存儲節(jié)點的數(shù)量,則將冗余模塊配置成指示所述多個存儲節(jié)點中的特定數(shù)量的附加存儲節(jié)點存儲包括該三元組的版本的數(shù)據(jù)項,該特定數(shù)量等于所述計數(shù)與冗余模塊被配置成確保其被指示存儲包括該三元組的版本的數(shù)據(jù)項的不同存儲節(jié)點的數(shù)量之間的差。在指令分配器所使用的選擇過程是確定性的情況下,這樣的冗余模塊是特別有用的,因為它使得能夠在不擾亂數(shù)據(jù)項與存儲數(shù)據(jù)項的存儲節(jié)點之間的關系的確定性屬性的情況下存儲數(shù)據(jù)項的副本以進行數(shù)據(jù)恢復。冗余模塊被配置成確保其被指示存儲包括三元組的版本的數(shù)據(jù)項的不同存儲節(jié)點的數(shù)量為兩個或更多個并且是特定于實現(xiàn)的,但是在優(yōu)選的實施例中是3個。因此,被指示存儲包括三元組的版本的不同存儲節(jié)點的數(shù)量是3減去該計數(shù)。包括三元組的特定版本(例如,SPO)的數(shù)據(jù)項的副本可以被做出并且可以存儲在附加存儲節(jié)點上。此外,附加存儲節(jié)點所存儲的數(shù)據(jù)項可以存儲在數(shù)據(jù)項的經(jīng)排序的集合之外。有利地,這確保數(shù)據(jù)項的經(jīng)排序的集合的順序被保持,并且數(shù)據(jù)項與存儲數(shù)據(jù)項的存儲節(jié)點之間的關系的確定性屬性也被保持。在替代實施例中,冗余模塊被引入至指令分配器所使用的哈希算法中以從所述多個存儲節(jié)點中選擇待存儲數(shù)據(jù)項的存儲節(jié)點。本發(fā)明的實施例還包括計算設備如服務器,該計算設備用作實施本發(fā)明的數(shù)據(jù)庫控制器。例如,所述計算設備可以是分布式網(wǎng)絡中的存儲節(jié)點之一。此外,所述計算設備可以是多個這樣的計算設備之一,以使得在存儲節(jié)點的分布式網(wǎng)絡中,所述多個存儲節(jié)點中的不止一個(例如,全部)存儲節(jié)點具有實施本發(fā)明的數(shù)據(jù)庫控制器的功能。本發(fā)明的實施例包括計算機程序或存儲計算程序的非瞬態(tài)存儲介質,當由計算設備執(zhí)行該計算機程序時,該計算機程序使得該計算設備用作實施本發(fā)明的數(shù)據(jù)庫控制器。本發(fā)明還可以由用于將編碼為三元組的圖形數(shù)據(jù)存儲在數(shù)據(jù)庫中的方法來實施,每個三元組包括主語、謂語和賓語,并且每個三元組存儲在數(shù)據(jù)項集合中的數(shù)據(jù)項內(nèi),該數(shù)據(jù)項集合是根據(jù)存儲在數(shù)據(jù)項內(nèi)的三元組來排序的,其中每個數(shù)據(jù)項存儲在分布于網(wǎng)絡中的多個存儲節(jié)點中的存儲節(jié)點上。所述方法包括:接收在數(shù)據(jù)庫中存儲三元組的請求;生成具有三元組的以下版本中的不同版本的兩個或更多個數(shù)據(jù)項:第一版本,其中在數(shù)據(jù)項中主語在謂語和賓語之前;第二版本,其中在數(shù)據(jù)項中謂語在主語和賓語之前;以及第三版本,其中在數(shù)據(jù)項中賓語在主語和謂語之前。這樣的方法還包括:針對所述兩個或更多個數(shù)據(jù)項中的每一個數(shù)據(jù)項,從所述多個數(shù)據(jù)節(jié)點中選擇存儲節(jié)點以指示存儲數(shù)據(jù)項,所述選擇是依靠該數(shù)據(jù)項在所述經(jīng)排序的集合內(nèi)的位置來做出的;以及,確保指示所述多個存儲節(jié)點的至少兩個不同存儲節(jié)點來存儲包括該三元組的版本的數(shù)據(jù)項。在本文獻中所討論的數(shù)據(jù)項可以是在表中按行或表項存儲的獨立的信息。但是,發(fā)明實施例包括其中每個數(shù)據(jù)項都是鍵值系統(tǒng)(KVS)內(nèi)的鍵值對的鍵的實現(xiàn)。有利地,在鍵值系統(tǒng)的鍵內(nèi)存儲包括完整三元組的鍵使得能夠對返回該完整三元組的鍵集合執(zhí)行功能,而不是僅僅對可能發(fā)現(xiàn)三元組的地點的鏈接或標識執(zhí)行功能。存儲在鍵值對的鍵中包括將三元組的元素表示為自身是該鍵值對的鍵的字符串對象。鍵值系統(tǒng)(KVS)或鍵值存儲是多個所存儲的鍵和值,其中每個鍵具有關聯(lián)值,通過邏輯函數(shù)或邏輯樹例如哈希表或哈希圖來將該鍵映射至該關聯(lián)值。哈希表或哈希圖是使用哈希函數(shù)將各個鍵(標識值)映射至它們的關聯(lián)值的數(shù)據(jù)結構。在本發(fā)明的實施例中,可以使用哈希函數(shù)來將鍵變換為用于形成存儲節(jié)點的分布式網(wǎng)絡的所述多個存儲節(jié)點中的存儲節(jié)點(存儲資源)的標識。可以提供以下實施例:在所述實施例中,所述多個鍵值對中的每一個鍵的值包括與該鍵內(nèi)存儲的三元組有關的附加信息。例如,關于三元組的元數(shù)據(jù)存儲在該值中。在此上下文中,元數(shù)據(jù)是關于三元組中的信息項的描述性數(shù)據(jù)。該鍵存儲三元組并且該值存儲關于該三元組的信息??蛇x地,在這樣的實施例中,附加信息是依靠其身份來訪問數(shù)據(jù)庫的應用程序可獲得的數(shù)據(jù)。有利地,這樣的實施例通過使能在數(shù)據(jù)庫中讀取和/或寫入數(shù)據(jù)的依賴于應用程序的方面來擴展數(shù)據(jù)庫的功能。該數(shù)據(jù)是依賴于應用程序的數(shù)據(jù),并且可以作為模糊對象在KVS中被查看和處理。值容器還可以包括設置和檢索依賴于應用程序的數(shù)據(jù)的API??蛇x地,在上述KVS實現(xiàn)中,附加信息包括被注冊用于當對存儲在鍵值對內(nèi)的RDF三元組進行讀和/或寫訪問時接收通知的應用程序列表。此外,該附加信息可以包括用于由存儲該容器的節(jié)點執(zhí)行的軟件代碼。例如,可以響應于特定事件來存儲和調用該軟件代碼,該軟件代碼的變元也存儲在該容器中。例如,值可以將軟件代碼塊存儲為更新函數(shù)。當更新所關聯(lián)的三元組時,調用更新函數(shù),其中將其他三元組的列表以及它們的位置作為變元。該其他三元組的列表可以由客戶端應用程序通過將三元組添加至與特定事件相關聯(lián)的容器中的列表來產(chǎn)生。有利地,在對三元組數(shù)據(jù)進行讀或寫訪問時通知應用程序增強了數(shù)據(jù)庫與使用存儲在該數(shù)據(jù)庫中的數(shù)據(jù)的應用程序之間的交互水平。對注冊為接收通知的應用程序列表的維護提供了能夠管理通知的機制。附圖說明僅作為示例,現(xiàn)在將參考附圖來描述本發(fā)明的優(yōu)選特征,其中:圖1是實施本發(fā)明的數(shù)據(jù)庫控制器的示意圖;圖2是實施本發(fā)明的系統(tǒng)的示意圖;以及圖3示出了圖1的數(shù)據(jù)庫控制器的組件與圖2的軟件層對應的示例。具體實施方式圖1示意性地示出了實施本發(fā)明的數(shù)據(jù)庫控制器。數(shù)據(jù)庫控制器10包括多個組件:存儲請求接收器12、數(shù)據(jù)項生成模塊14和自身包括冗余模塊18的指令分配器16。這些組件本身可以由專用硬件例如處理器、內(nèi)存、存儲器以及網(wǎng)絡接口來實現(xiàn),在適當?shù)那闆r下,所有這些硬件被配置成以下述方式來工作??商娲?,數(shù)據(jù)庫控制器可以是由運行在計算設備上的計算程序(或由協(xié)作地運行在不止一個計算設備上的一組計算機程序)提供的功能,所述計算設備比如是自身可以是節(jié)點20的分布式網(wǎng)絡中的存儲節(jié)點的服務器。在這樣的實施例中,上述組件是功能單元或模塊,這些功能單元或模塊中的每一個利用作為計算設備自身的一部分的硬件來實現(xiàn)其所述功能。數(shù)據(jù)庫控制器10可以實現(xiàn)為單個存儲節(jié)點上的集中控制器,由協(xié)作的多個存儲節(jié)點實現(xiàn)的集中控制器,或者實現(xiàn)為其中每個都位于相應的存儲節(jié)點上的多個等同控制器中的控制器。例如,可以由運行在由節(jié)點組成的分布式網(wǎng)絡中的存儲節(jié)點上的程序來提供數(shù)據(jù)控制器10,并且一個或更多個其他存儲節(jié)點也可以運行等同的程序以使得能夠通過多個數(shù)據(jù)庫控制器10來訪問數(shù)據(jù)庫。數(shù)據(jù)庫控制器10被示出為連接至由存儲節(jié)點20組成的分布式網(wǎng)絡。始于指令分配器16并且止于存儲節(jié)點的箭頭被示出為具有方向性以表示存儲正在分發(fā)的數(shù)據(jù)項的指令。但是,數(shù)據(jù)庫控制器與分布式存儲節(jié)點的網(wǎng)絡之間的數(shù)據(jù)連接可以是雙向的。實際上,在本發(fā)明的實施例中,每個存儲節(jié)點和數(shù)據(jù)庫控制器可以通過網(wǎng)絡來彼此進行通信,而不管該網(wǎng)絡是有線的、無線的或兩者的組合。節(jié)點20的分布式網(wǎng)絡中的每個存儲節(jié)點可以具有如數(shù)據(jù)庫控制器10的數(shù)據(jù)庫控制器。存儲請求接收器12被配置成接收在數(shù)據(jù)庫中存儲三元組的請求。該請求可以來自例如運行希望向數(shù)據(jù)庫添加新的三元組的應用程序的客戶端設備。存儲請求接收器12可以例如是RDF層或RDF層的一部分,并且處理以下請求:向數(shù)據(jù)庫添加三元組的請求,還可能從數(shù)據(jù)庫移除三元組的請求,以及讀取或查詢數(shù)據(jù)庫的請求。希望訪問數(shù)據(jù)庫的應用程序與數(shù)據(jù)庫自身之間的交互是通過存儲請求接收器12來實現(xiàn)的,并且可以是以由應用程序編程接口(API)指定的形式,應用程序編程接口由數(shù)據(jù)庫控制器10和/或節(jié)點20的分布式網(wǎng)絡中的一個或更多個存儲節(jié)點輸出。存儲請求接收器12可以被配置成執(zhí)行以下處理:解釋來自應用程序的請求并且基于該請求來生成針對數(shù)據(jù)庫控制器10的其他組件的指令。例如,存儲請求接收器12可以提取表示形成三元組存儲請求的基礎的三元組的字符串,并且將所提取的字符串(或三元組的其他數(shù)據(jù)表示)傳遞至數(shù)據(jù)項生成模塊14。數(shù)據(jù)項生成模塊14被配置成生成兩個或更多個數(shù)據(jù)項,其中每個數(shù)據(jù)項具有三元組的以下不同版本:第一版本,其中在數(shù)據(jù)項中主語在謂語和賓語之前;第二版本,其中在數(shù)據(jù)項中謂語在主語和賓語之前;以及第三版本,其中在數(shù)據(jù)項中賓語在主語和謂語之前。還可以預先確定三元組的剩余元素在每個版本中出現(xiàn)的順序。數(shù)據(jù)項生成模塊14可以被配置成生成三個數(shù)據(jù)項,其中每個數(shù)據(jù)項具有上面列出的三個版本中的不同版本。數(shù)據(jù)項生成模塊14可以是RDF層、RDF層的一部分、或RDF層的一部分和存儲層的一部分的組合。數(shù)據(jù)項生成模塊14被配置成執(zhí)行從存儲請求接收器12接收三元組或表示三元組的數(shù)據(jù)所需要的處理,以及產(chǎn)生所需的三元組的不同版本,并且還可能將三元組的那些不同版本封裝到具有或不具有附加數(shù)據(jù)的特定格式的數(shù)據(jù)項中。數(shù)據(jù)項生成模塊14被配置成將所生成的數(shù)據(jù)項傳遞至指令分配器16。指令分配器16被配置成:針對上述兩個或更多個數(shù)據(jù)項中的每一個,從多個存儲節(jié)點20中選擇存儲節(jié)點以指示存儲數(shù)據(jù)項,該選擇是依靠該數(shù)據(jù)項在經(jīng)排序的集合內(nèi)的位置做出的。包括冗余模塊18的指令分配器16被配置成確保多個存儲節(jié)點20中的至少兩個不同存儲節(jié)點被指示為存儲包括該三元組的版本的數(shù)據(jù)項。指令分配器16可以是存儲層的一部分,并且被配置成執(zhí)行指示存儲節(jié)點存儲特定數(shù)據(jù)項所需要的處理,例如,將包括數(shù)據(jù)項的請求經(jīng)由網(wǎng)絡發(fā)送至存儲節(jié)點,或促使發(fā)送這樣的請求。例如,指令分配器16(通過冗余模塊18)可以配置成以確定性方式以及以確保沒有同一三元組的兩個版本存儲在同一存儲節(jié)點的方式來將數(shù)據(jù)項映射至存儲節(jié)點??商娲兀噶罘峙淦骺梢载撠煂?shù)據(jù)項映射至存儲節(jié)點(例如,使用確定性哈希函數(shù)),并且冗余模塊被配置成對具有特定三元組的兩個或更多個不同版本的數(shù)據(jù)項的映射進行檢查,其中該映射不導致:多于一個的存儲節(jié)點存儲該三元組的一個版本,生成具有該三元組的數(shù)據(jù)項的副本,以及指示除了被指示存儲所檢查的數(shù)據(jù)項的存儲節(jié)點以外的存儲節(jié)點存儲該附加的副本。節(jié)點20的分布式網(wǎng)絡可以是例如分布式對等網(wǎng)絡。這樣的網(wǎng)絡是可擴展的并且可以包括大量的服務器。實際上,數(shù)據(jù)項的有序集的分布水平越高,冗余模塊就越容易確保需要數(shù)量的存儲節(jié)點被指示為存儲包括三元組的版本的數(shù)據(jù)項。圖2示出了實施本發(fā)明的系統(tǒng)。在圖2中,各個服務器1-N和應用程序30都在計算機中執(zhí)行。所有的計算機通過網(wǎng)絡來可通信地連接。不同模塊之間的箭頭表示網(wǎng)絡通信,盡管這些箭頭意在強調下文所討論的通信,但是不對在這樣的系統(tǒng)架構中的模塊之間的可能的通信構成限制。應用程序30使用明確定義的API來與服務器之一進行交互,上述API由所有的服務器1-N輸出。每個服務器具有由3個軟件組件構成的數(shù)據(jù)庫控制器:RDF層11,RDF層11處理來自應用程序的以下請求:添加和移除數(shù)據(jù),或對現(xiàn)有數(shù)據(jù)進行高水平查詢。所述應用程序請求被轉換為低水平請求并且被轉發(fā)至存儲層。RDF層11負責將RDF數(shù)據(jù)轉換成三元組的簡單和統(tǒng)一表示。高水平查詢還必須被轉換成一組范圍查詢(rangequery)。RDF層11是存儲請求接收器12的示例;存儲層15,存儲層15負責數(shù)據(jù)項的生成與分配,并且負責范圍查詢的執(zhí)行。存儲層15是數(shù)據(jù)項生成模塊14、指令分配器16和冗余模塊18的示例;故障檢測器19,故障檢測器19負責看門狗的執(zhí)行,看門狗可以檢測服務器故障并且向存儲層15通知剩余(未出現(xiàn)故障)的服務器。存儲層15和故障檢測器19使用通信網(wǎng)絡與位于不同服務器上的類似組件進行通信。本實施例的數(shù)據(jù)庫是由存儲系統(tǒng)提供的,該存儲系統(tǒng)由通過網(wǎng)絡進行通信的服務器(存儲節(jié)點)20的分布式集合組成的。組成該系統(tǒng)的服務器20的該集合還實現(xiàn)分布式有序哈希映射。應用程序30(例如運行在可以通過網(wǎng)絡連接至一個或更多個服務器20的客戶端機器上的應用程序)通過連接至上述服務器之一來與該系統(tǒng)進行交互。客戶端應用程序30具有例如通過添加新的三元組、移除三元組以及執(zhí)行范圍查詢來實現(xiàn)的添加、移除和查詢RDF數(shù)據(jù)的接口。服務器20通過網(wǎng)絡彼此進行通信,并且通過每個服務器都運行作為它們各自數(shù)據(jù)庫控制器10的組件的故障檢測模塊19來運行分布式故障檢測器。當處理P出現(xiàn)故障時(其中處理P用于指代由服務器20的分布式集合中的服務器實現(xiàn)的存儲處理),最終,其他處理會從指示P出現(xiàn)故障的故障檢測器接收通知。該實施例的數(shù)據(jù)庫中的數(shù)據(jù)被存儲為三元組,例如RDF三元組。RDF三元組是[主語,謂語,賓語]或簡單地為SPO形式的RDF數(shù)據(jù)。該數(shù)據(jù)以以下方式來存儲:能夠使用以不同的順序如POS或OSP等存儲同一三元組的副本來有效地執(zhí)行范圍查詢。在本發(fā)明的實施例中,副本還用于數(shù)據(jù)恢復處理。根據(jù)每個數(shù)據(jù)項中的三元組數(shù)據(jù)來對存儲在數(shù)據(jù)庫中的數(shù)據(jù)集合進行排序。數(shù)據(jù)集合的范圍被分成N段,其中N是將用作存儲器的服務器的數(shù)量。每個服務器負責一個數(shù)據(jù)段。當將數(shù)據(jù)添加至系統(tǒng)時,生成每個三元組的至少兩個(優(yōu)選地為三個)版本并且將這些版本存儲在至少兩個(優(yōu)選地為三個)不同的服務器中。由存儲層15(指令分配器16)使用如一致性哈希算法等確定性技術來針對每個三元組版本計算段(及其對應的服務器地址或ID)。每個三元組版本自然可以存儲在不同的服務器上,但是一致性哈希算法不能總是保證該屬性。在各個三元組版本沒有存儲在不同服務器上(或上述版本沒有分布在至少兩個不同的服務器上)的情況下,將三元組的附加拷貝存儲在不同服務器上的數(shù)據(jù)項中??梢允褂么_定性過程來本地地(例如,在每個數(shù)據(jù)庫控制器10處)計算其中存儲了具有特定三元組的數(shù)據(jù)項的所有服務器。由于范圍查詢是對已經(jīng)存儲在有序集合中的數(shù)據(jù)來執(zhí)行的,所以發(fā)起范圍查詢的服務器還可以計算需要被本地查詢的服務器的列表。以不同的版本存儲的三元組的至少兩個(優(yōu)選地為三個)版本用于兩個目的:有效地執(zhí)行范圍查詢,而不管在范圍查詢中指定的前綴如何(即,可由主語、謂語或賓語來指定范圍并且仍然可以有效地處理該范圍);以及從故障中恢復數(shù)據(jù)。當包含SPO形式的三元組的服務器出現(xiàn)故障時,在系統(tǒng)中存在一個或更多個附加拷貝:POS和OSP。這些三元組包含完全相同的但是以不同的順序來表示的數(shù)據(jù)。使用該信息,實施本發(fā)明的系統(tǒng)提供了從三元組的不同表示中檢索丟失數(shù)據(jù)的機制?;謴蛠G失數(shù)據(jù)并且重新計算每個三元組的新位置。當有服務器(或處理)出現(xiàn)故障時,幸存服務器具有足夠的信息去了解哪些三元組需要被恢復和改組。不僅期望該恢復處理保持確保容錯性所需的副本的數(shù)量,而且還期望該恢復處理確保數(shù)據(jù)位于系統(tǒng)中的所有服務器可確定性地達到的服務器中。如前面所概述的,一致性哈希算法是將數(shù)據(jù)段映射至服務器的非常有效的方式,并且在本發(fā)明的實施例中可以由存儲層15(指令分配器16)使用以選擇指示哪個存儲節(jié)點(服務器)來存儲包括三元組的版本的數(shù)據(jù)項。這種哈希方法可以針對存儲同一三元組的每個數(shù)據(jù)項選擇不同的服務器,但是取決于數(shù)據(jù)項、服務器的相對數(shù)量和哈希算法(例如,其要求保持數(shù)據(jù)項之間的相對順序),也不是必需是該情況。因此,本發(fā)明的實施例提供有以下機制:確保存儲同一三元組的不同版本的數(shù)據(jù)項被存儲在至少兩個(優(yōu)選地為三個)不同服務器中。更具體地,存儲層15(指令分配器16)提供有以下功能(冗余模塊18):處理三種不同的場景以確保系統(tǒng)總是在例如三個不同的服務器中具有三元組的至少一份拷貝:在第一場景中:三元組的三個版本(SPO、POS和OSP)自然地存儲在不同的服務器中。例如,SPO存儲在服務器1中,POS存儲在服務器2中,以及OSP存儲在服務器3中。在該情況下,不需要采取另外的動作。在第二場景中:三元組的兩個版本存儲在同一服務器中,并且一個版本存儲在另一個服務器中。例如,SPO和POS存儲在服務器1中,并且OSP存儲在服務器2中。在該情況下,僅兩個服務器會具有該三元組的版本,系統(tǒng)對于該特定數(shù)據(jù)項會有更低的容錯性。為避免這種情況,數(shù)據(jù)庫控制器10(例如,通過冗余模塊18)執(zhí)行為將額外的拷貝存儲在第三服務器中所需要的處理。在第三場景中:三元組的所有三個版本SPO、POS和OSP存儲在同一服務器中(例如,服務器1)。在該情況下,如果服務器1出現(xiàn)故障,則系統(tǒng)會丟失該數(shù)據(jù)項。為了確保相同水平的容錯性,數(shù)據(jù)庫控制器10(例如,通過冗余模塊18)執(zhí)行將額外拷貝存儲在兩個不同服務器(不同于已經(jīng)存儲現(xiàn)有三個版本的服務器,并且彼此不同)中所需要的處理。通過以上面提出的方式來處理以上三個場景,系統(tǒng)確保針對數(shù)據(jù)庫中的每個三元組都有包括所存儲的該三元組的版本的至少三個數(shù)據(jù)項。在存儲該三元組的不同版本的數(shù)據(jù)項沒有映射至三個不同服務器(場景2和場景3)的情況下,添加上述數(shù)據(jù)項之一的更多副本或添加具有該三元組的版本的新數(shù)據(jù)項。在場景2中,系統(tǒng)將不得不存儲具有該三元組的版本的4個數(shù)據(jù)項。在場景3中,系統(tǒng)將不得不存儲具有該三元組的版本的5個數(shù)據(jù)項。這是必需的,這是因為在該特定的實現(xiàn)中,原始數(shù)據(jù)項(或三元組)不能從其在數(shù)據(jù)項的有序集合中的位置被移走。相比場景1,場景和場景3的出現(xiàn)頻率可能相對低,但是這取決于要存儲的數(shù)據(jù)的量和可用服務器的量。盡管用于存儲三元組的本方法可以用于任何網(wǎng)絡配置,但是使用具有許多服務器的可擴展對等網(wǎng)絡會增加場景1出現(xiàn)的概率,從而減小系統(tǒng)中三元組的版本的副本的數(shù)量。此外,該特定的系統(tǒng)包括故障檢測器19。故障檢測器的簡易版本是被配置成使用超時和“ping”消息的檢測器。每個服務器的故障檢測器19被配置成周期性地發(fā)送“ping”消息至每個其他服務器。例如,如果服務器1在指定量的時間后沒有從服務器2接收到“ping”消息(或其他類型的預定響應),服務器1會懷疑服務器2出現(xiàn)了故障,并且與剩余服務器一起執(zhí)行協(xié)定過程以將服務器2從可用服務器列表中排除,并執(zhí)行數(shù)據(jù)恢復處理。用于實現(xiàn)故障檢測器的該特定方法已知為“最終完美故障檢測器(eventuallyperfectfailuredetector)”,并且在網(wǎng)絡消息未丟失并且消息延遲有(未知)上界的系統(tǒng)中尤其有用??蛇x地,可以將“ping”消息捎帶在常規(guī)的服務器消息中以節(jié)省網(wǎng)絡帶寬。實現(xiàn)故障檢測器的更多細節(jié)以及方法可以在論文“TusharDeepakChandraandSamToueg.1996.Unreliablefailuredetectorsforreliabledistributedsystems.J.ACM43,2(March1996),225-267.DOI=10.1145/226643.226647”中找到。在圖2所示的系統(tǒng)中,每個服務器具有執(zhí)行等同任務的其自己的數(shù)據(jù)庫控制器。每個服務器運行具有以下數(shù)據(jù)結構的處理:存儲表。每個處理存儲由以下字段組成的表:triple_data:三元組triple_order:Enum{SOP,POS,OSP}spo_node_ID:整數(shù)pos_node_ID:整數(shù)osp_node_ID:整數(shù)在存儲表中,表項按照第一個字段(triple_data)排序以使得能夠對每個處理進行本地范圍查詢(例如,基于表示三元組的字符串的字母順序排序)。triple_order是表示三元組的編碼順序的數(shù)字,因此,例如基于存儲在“triple_order”中的數(shù)字,可導出該三元組的哪個元素是由例如第二元素表示的。在該特定的實現(xiàn)中,存儲同一三元組的三個版本中的每一個版本的節(jié)點的ID也與該三元組一起存儲在存儲表中。在替選實現(xiàn)中,存儲表和下面討論的副本表可以利用有序搜索樹(Trie)結合在一起,以使得能夠具有兩個有序三元組并且可搜索的索引可用于數(shù)據(jù)控制器。處理/服務器可以存儲的附加數(shù)據(jù)結構包括以下數(shù)據(jù)結構:索引,該索引將node_ID映射至指向存儲表上的行的指示符,例如,在特定服務器出現(xiàn)故障的情況下,可以確定該服務器的node_ID,并且該索引使得能夠有效地識別故障服務器上的數(shù)據(jù)恢復所需的行;副本表,用于存儲所生成的三元組版本的副本以滿足以下要求:例如,三個不同的服務器中每一個服務器都存儲同一三元組的版本。為了保持三元組的現(xiàn)有版本的排序,可以將這樣的副本存儲在主存儲表之外,因而該副本表可以僅存儲SPO形式的三元組并且可以由以下字段組成(其中replica1_ID是表示在其上可以找到該三元組的SPO版本的第一副本的節(jié)點的ID的整數(shù),并且如果存在第二副本,則replica2_ID是表示在其上可以找到該三元組的SPO版本的第二副本的節(jié)點的ID的整數(shù)):triple_data:三元組spo_node_ID:整數(shù)pos_node_ID:整數(shù)osp_node_ID:整數(shù)replica1_ID:整數(shù)replica2_ID:整數(shù)索引,該索引將node_ID映射至指向副本表上的行的指示符,同樣,這樣的索引方便數(shù)據(jù)恢復目的。在本實施例中,每個三元組在分布式存儲系統(tǒng)中被存儲3次:按照SPO順序,按照OSP順序以及按照POS順序。這確保了每個三元組的三個版本存儲在數(shù)據(jù)項中并且確保了可以有效地執(zhí)行范圍查詢,而不管搜索類型(按主語,按謂語或按賓語)如何。以下段落描述如何存儲三元組以及當處理失敗時如何恢復信息。數(shù)據(jù)是由通過線性數(shù)據(jù)空間排序的三元組集合來組成的。該數(shù)據(jù)空間按段劃分。為了有效地檢索特定數(shù)據(jù)項應該位于的段,可以使用如Trie(一種分類樹)等機制,其中該Trie的每個葉子對應于一個段。在系統(tǒng)的每個存儲節(jié)點中復制這樣的數(shù)據(jù)結構并且將數(shù)據(jù)項映射至段ID。因為數(shù)據(jù)項總是被排序的,所以可以檢索執(zhí)行范圍查詢所需的段ID。范圍查詢檢索t1與t2之間的所有數(shù)據(jù),其中t1和t2是數(shù)據(jù)項(或三元組)。因此,需要查詢的段(其中將段理解為存儲在特定存儲節(jié)點/服務器/機器上的數(shù)據(jù)的總集合中的一部分)是:t1所位于的段、t2所位于的段以及這兩個段之間的所有段(當存儲節(jié)點是根據(jù)每個存儲節(jié)點存儲的數(shù)據(jù)項的有序集合組成的段的順序排序時,就存儲節(jié)點的順序而言的之間)。在檢索段ID之后,使用如一致性哈希等機制作為工具將段映射至機器。利用該功能提供了本地地將數(shù)據(jù)項(三元組)映射至特定機器ID的函數(shù)/方法:機器IDgetMachineID(對象三元組)該方法使用Trie結構(或有序數(shù)據(jù)項至段ID的其他映射)將數(shù)據(jù)項映射至段ID,然后使用一致性哈希算法將段ID映射至機器ID(但是在該第二步驟中,將段ID映射至機器ID的任何機制都符合目的)。通過具有作為變元提供的三元組的表示的指令“getMachineID”來調用該方法。返回例如可以是整數(shù)的機器ID(MachineID)。存儲層15(指令分配器16)可以使用該方法來選擇存儲三元組的每個版本的存儲節(jié)點。機器ID標識特定的存儲節(jié)點。例如可以通過對其地址進行哈希處理并根據(jù)其在數(shù)據(jù)的線性空間中的相對位置來確定存儲節(jié)點(其中存儲節(jié)點是機器或服務器)的ID。這些ID還可以以循環(huán)的方式來限定彼此之間的順序。這意味著:例如如果在系統(tǒng)中具有3個機器,則將順序關系“A<B”(A小于B)限定如下:機器1<機器2<機器3<機器1。在數(shù)據(jù)插入方法的描述中,運算“機器ID+1”對應于線性空間的下一個機器。例如:機器1+1與機器2相同機器3+1與機器1相同最終,由兩個附加的方法:store(對象三元組,機器IDspoID,機器IDposID,機器IDospID)storeReplica(對象三元組,機器IDspoID,機器IDposID,機器IDospID,機器IDreplica1,機器IDreplica2)所有的存儲服務器通過它們的數(shù)據(jù)庫控制器來提供這些方法。例如,可以由指令分配器在向存儲節(jié)點分發(fā)指令時調用這些方法。該“store()”方法指示三元組在特定服務器的存儲表中的存儲。從上可以看出,在該實施例中,當調用該方法時所包括的變元是該三元組自身、存儲該三元組的存儲節(jié)點的ID和存儲該三元組的每個版本的存儲節(jié)點的ID。該storeReplica()方法在三元組的版本例如由冗余模塊18復制時在特定服務器的副本表中存儲該三元組,以確保所需數(shù)量的存儲節(jié)點具有特定三元組的版本。作為對發(fā)明實施例的核心功能的可選擴展,這些方法還存儲三元組的其他版本的ID并且更新先前描述的索引。存儲三元組的三個版本(以及如果需要還有副本)的機制(方法addTriple)按如下方式工作,以三元組的表示作為變元,并且是由接收到在數(shù)據(jù)庫中存儲三元組的請求的數(shù)據(jù)庫控制器10執(zhí)行的方法的示例:方法addTriple(三元組三元組):機器IDm1,m2,m3m1=getMachineID(triple.asSPO())m2=getMachineID(triple.asPOS())m3=getMachineID(triple.asPOS())在m1中store(triple.asSPO(),m1,m2,m3)在m2中store(triple.asPOS(),m1,m2,m3)在m3中store(triple.asOSP(),m1,m2,m3)這些過程確保三元組的每個版本SPO、POS和OSP被存儲在系統(tǒng)中以使得能夠使用三元組數(shù)據(jù)的子集的任意組合作為前綴來進行范圍查詢。針對作為SPO、POS和OSP的三元組在“getmachineID”中使用的哈希函數(shù)針對三元組的所有三個版本返回不同的機器ID,因此,所述三個版本將存儲在不同的服務器中。在已經(jīng)檢查了這是否發(fā)生之后,確定所需的副本的數(shù)量并且生成副本并指示所述副本的存儲。僅當這沒有發(fā)生時,才存儲一個或兩個額外的副本。這些副本僅在恢復處理中使用而不用于執(zhí)行范圍查詢。額外的拷貝僅是一個回退過程以確保系統(tǒng)總是具有每個過程的至少三份拷貝。在某些情況下,系統(tǒng)可以存儲某些數(shù)據(jù)的4個或甚至5個版本,但是一致性哈希算法確保這僅發(fā)生在極少數(shù)的情況下,并且僅當出于數(shù)據(jù)冗余目的而請求時。在本發(fā)明的操作實現(xiàn)中,很有可能僅在非常小百分比的情況下才會需要副本。最后,以完全相同的方式進行刪除操作,但是是通過在服務器中執(zhí)行“delete()”和“deleteReplica()”方法,而不是分別執(zhí)行“store()”和“storeReplica()”。這些方法刪除每個表中與要刪除的三元組對應的行。如果需要,“delete()”和“deleteReplica()”還更新各個索引。當服務器出現(xiàn)故障時,故障檢測器最終會檢測到該事件。例如,特定服務器的故障檢測器可以通過與網(wǎng)絡中的其他數(shù)據(jù)庫控制器的故障檢測器或故障檢測模塊進行協(xié)作來檢測該事件。因此,可以考慮將故障檢測器分布在網(wǎng)絡中的每個服務器(數(shù)據(jù)庫控制器)中。一旦檢測到服務器故障,則會觸發(fā)響應。例如,故障服務器的檢測可以在幸存服務器上(例如,在它們的數(shù)據(jù)庫控制器上)觸發(fā)“故障(onFailed)”事件。一旦服務器例如通過接收“故障”事件通知而被通知另一個服務器出現(xiàn)故障,則服務器通過其數(shù)據(jù)庫控制器執(zhí)行恢復操作。假設FID是故障處理的ID,則數(shù)據(jù)恢復操作可以由每個非故障存儲節(jié)點的數(shù)據(jù)庫控制器的以下步驟組成:1.如果(在非故障存儲節(jié)點上)存在從FID至表行的任何映射,則登記存儲索引。2.對于該索引所標識的每個三元組:a.使用新成員配置來計算用于該三元組(即,用于存儲該三元組的版本的每個數(shù)據(jù)項)的新機器ID,例如可以通過使用以具有三種配置SPO、POS、OSP中的每一種配置的三元組作為變元的getmachineID方法在存儲層15(在指令分配器16中)執(zhí)行這樣的操作;b.如果有存儲了三元組的版本并且不會以新的配置來存儲的服務器,則從該機器移除該三元組,例如,該移除可以由存儲層15(指令分配器16)使用“delete()”方法來指示;c.如果有將存儲三元組但沒有以先前的配置來存儲的服務器,則向該服務器添加該三元組,例如,該添加可以由存儲層15(指令分配器16)使用具有特定實現(xiàn)所需的變元的“store()”方法來指示,但是所述變元至少包括要存儲的三元組的版本;d.如果有以先前配置存儲了三元組并且繼續(xù)以新配置來存儲的服務器,則簡單地更新該服務器的表上的三元組的ID,這樣的更新可以通過向適當?shù)姆掌靼l(fā)布更新指令來執(zhí)行。3.如果存在從FID至表行的任何映射,則登記副本索引,并且針對這些三元組重復步驟2。最終,為了避免該過程針對同一三元組被執(zhí)行多次,本發(fā)明的實施例可以包括以下機制:確保包含三元組的副本(或版本)服務器中的僅僅一個服務器會執(zhí)行數(shù)據(jù)恢復操作。例如,這可以通過計算存儲三元組的版本(不管其是副本或是其他)的(非故障)服務器的最低機器ID來實現(xiàn)。如果使用存儲同一三元組的版本或副本的其他節(jié)點的機器ID來存儲三元組,則僅通過參考存儲表和副本表來獲得該值。否則,可以根據(jù)在通過指令分配器選擇指示哪個節(jié)點存儲三元組的版本時所使用的映射函數(shù)來確定存儲同一三元組的版本或副本的其他存儲節(jié)點的ID。如果正在執(zhí)行恢復程序的服務器對于該三元組具有最低的ID,則該服務器會針對該三元組執(zhí)行恢復程序。否則,這被簡單地忽略,因為另一服務器會處理該三元組。圖3示出了圖2的“層”如何與圖1的組件相聯(lián)系的示例。即,RDF層11包括存儲請求接收器12,存儲層15包括數(shù)據(jù)項生成模塊14、指令分配器16和冗余模塊18。故障檢測器19不屬于任一層,而是可以根據(jù)需要與任一或兩個層/組件交換數(shù)據(jù)并向所述任一或兩個層/組件發(fā)布指令的部件。在上述方面中的任一方面中,各種特征可以用硬件實現(xiàn)或實現(xiàn)為運行在一個或更多個處理器上的軟件模塊。一個方面的特征可以應用至其他方面中的任何一個。本發(fā)明還提供了用于執(zhí)行本文所述方法中的任意一種方法的計算機程序或計算機程序產(chǎn)品,以及在其上存儲有用于執(zhí)行本文所述方法中的任意一種方法的程序的計算機可讀介質。實施本發(fā)明的計算機程序可以存儲在計算機可讀介質上,或者,所述計算機程序例如可以是以信號的形式如由互聯(lián)網(wǎng)網(wǎng)站提供的可下載的數(shù)據(jù)信號,或者可以是以任何其他形式。