專利名稱:Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法
技術(shù)領(lǐng)域:
本發(fā)明涉及Key-Value數(shù)據(jù)庫領(lǐng)域,具體涉及一種Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法。
背景技術(shù):
與SQL數(shù)據(jù)庫不同,Key-Value數(shù)據(jù)庫用于存儲無結(jié)構(gòu)的鍵值數(shù)據(jù),即以鍵碼(即Key)作為索引,讀、寫、刪除Key對應(yīng)的數(shù)據(jù)記錄(即Value)。由于Key-Value數(shù)據(jù)庫只關(guān)心通過Key索引Value的過程,不關(guān)心Value中存儲的具體數(shù)據(jù)的結(jié)構(gòu)和內(nèi)容,因此相較于SQL數(shù)據(jù)庫,功能更加專一、存取速度快、水平擴(kuò)展性好。通常,Key-Value數(shù)據(jù)庫的請求處理過程分為前端和后端兩部分:通過網(wǎng)絡(luò)等I/0輸入接口接收請求的前端請求處理過程,通過后端數(shù)據(jù)處理引擎執(zhí)行數(shù)據(jù)查詢、存儲的后端處理過程。其中,Key-Value數(shù)據(jù)庫的前端負(fù)責(zé)對請求報(bào)文進(jìn)行接收、校驗(yàn)請求報(bào)文后發(fā)往后端;Key_Value數(shù)據(jù)庫的數(shù)據(jù)庫后端負(fù)責(zé)按順序逐個(gè)處理前端發(fā)來的請求,并查詢、讀寫數(shù)據(jù)。目前,已有Key-Value數(shù)據(jù)庫后端均支持多線程并發(fā)地進(jìn)行數(shù)據(jù)庫存取,但其并發(fā)性卻直接受限于前端是否能夠最大程度并發(fā)地向后端提供用戶的存取請求。目前,已有Key-Value數(shù)據(jù)庫對用戶請求的并行處理粒度較粗。一般以用戶連接為粒度,每個(gè)連接對應(yīng)一個(gè)處理線程,進(jìn)行并行處理。盡管這種方式對不同連接發(fā)送的請求是并行處理的,但對于同一個(gè)連接送入的請求仍舊以串行方式逐個(gè)處理,并行粒度較粗,且存在以下不足:
I)在多核處理平臺上,各個(gè)計(jì)算核之間工作負(fù)載可能出現(xiàn)不均衡情況。因?yàn)椴煌脩暨B接產(chǎn)生Key-Value數(shù)據(jù)請求的速率不同,因此各個(gè)連接對應(yīng)的處理線程的閑忙程度不同,最終導(dǎo)致數(shù)據(jù)庫在多核處理 平臺上運(yùn)行時(shí),各個(gè)計(jì)算核的工作負(fù)載不同。2)同一連接發(fā)送的Key-Value數(shù)據(jù)請求的潛在并發(fā)性沒得到充分發(fā)掘。這是因?yàn)榧词故峭挥脩暨B接發(fā)送的請求,對Keyl的讀寫請求和對Key2的讀寫請求間由于不存在依賴關(guān)系,完全可以并發(fā)執(zhí)行,但現(xiàn)有系統(tǒng)卻無法有效發(fā)掘此類并發(fā)特性。
發(fā)明內(nèi)容
本發(fā)明要解決的技術(shù)問題是提供一種并行處理細(xì)粒度高、并發(fā)處理能力強(qiáng)、硬件資源利用率高、多核處理器下各個(gè)處理器核負(fù)載均衡、能夠保證讀寫依賴請求間順序的Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法。為了解決上述技術(shù)問題,本發(fā)明采用的技術(shù)方案為:
一種Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法,其實(shí)施步驟如下:
1)接收用戶請求并按接收順序加入請求緩沖隊(duì)列;
2)首先初始化用于存儲鍵碼與待處理隊(duì)列之間一一映射關(guān)系的鍵碼分類排隊(duì)表,然后持續(xù)按照先進(jìn)先出的順序從所述請求緩沖隊(duì)列中彈出用戶請求,根據(jù)用戶請求中鍵碼的不同分揀到不同待處理隊(duì)列中,并將鍵碼與待處理隊(duì)列的映射關(guān)系添加至所述鍵碼分類排隊(duì)表中;
3)首先初始化用于可并發(fā)處理的請求集合,然后持續(xù)彈出各個(gè)待處理隊(duì)列頭部的用戶請求并加入至所述請求集合中,使用預(yù)設(shè)數(shù)量的工作者線程并行處理所述請求集合中的用戶請求,并向用戶返回處理結(jié)果。作為本發(fā)明上述技術(shù)方案的進(jìn)一步改進(jìn):
所述步驟I)的詳細(xì)實(shí)施步驟如下:
1.1)監(jiān)控用戶指定的網(wǎng)絡(luò)端口,當(dāng)有一個(gè)新的套接字用戶連接建立后為對應(yīng)的用戶啟動一個(gè)接收線程,通過各個(gè)用戶對應(yīng)的接收線程分別接收用戶發(fā)出的用戶請求;
1.2)將接收的用戶請求附帶上用戶消息,然后按接收順序添加到請求緩沖隊(duì)列的頭部。所述步驟2)的詳細(xì)實(shí)施步驟如下:
2.1)初始化用于存儲鍵碼與待處理隊(duì)列之間一一映射關(guān)系的鍵碼分類排隊(duì)表為空,跳轉(zhuǎn)執(zhí)行下一步;
2.2)判斷所述請求緩沖隊(duì)列是否為空,如果所述請求緩沖隊(duì)列為空則繼續(xù)等待直至請求緩沖隊(duì)列非空,在請求緩沖隊(duì)列非空時(shí)跳轉(zhuǎn)執(zhí)行下一步;
2.3)按照先進(jìn)先出的原則,從所述請求緩沖隊(duì)列的尾部彈出最先進(jìn)入所述請求緩沖隊(duì)列的用戶請求,跳轉(zhuǎn)執(zhí)行下一步; 2.4)在所述鍵碼分類排隊(duì)表中查找是否有與被彈出用戶請求的鍵碼相對應(yīng)的待處理隊(duì)列,如果有則將被彈出用戶請求添加到所述對應(yīng)的待處理隊(duì)列尾部,將被彈出用戶請求的鍵碼和所述待處理隊(duì)列的映射關(guān)系添加至所述鍵碼分類排隊(duì)表中;否則,新建一個(gè)以被彈出用戶請求為頭的待處理隊(duì)列,將被彈出用戶請求的鍵碼和新建待處理隊(duì)列的映射關(guān)系添加至所述鍵碼分類排隊(duì)表中;跳轉(zhuǎn)執(zhí)行下一步;
2.5)跳轉(zhuǎn)執(zhí)行步驟2.2)。所述步驟3)的詳細(xì)實(shí)施步驟如下:
3.1)初始化用于存儲可并發(fā)處理用戶請求的請求集合為空,跳轉(zhuǎn)執(zhí)行下一步;
3.2)檢查所述鍵碼分類排隊(duì)表中是否有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,如果沒有則繼續(xù)等待直到所述鍵碼分類排隊(duì)表中有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,在所述鍵碼分類排隊(duì)表有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系時(shí)則跳轉(zhuǎn)執(zhí)行下一步;
3.3)找出所述新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,將所述新增的映射關(guān)系中鍵碼所對應(yīng)各個(gè)待處理隊(duì)列頭部的用戶請求彈出并添加到所述請求集合中,跳轉(zhuǎn)執(zhí)行下一步;
3.4)判斷預(yù)設(shè)數(shù)量的工作者線程是否啟動,如果沒有則啟動預(yù)設(shè)數(shù)量的工作者線程;通過所述工作者線程并發(fā)執(zhí)行所述請求集合中用戶請求并返回執(zhí)行結(jié)果,在所述請求集合中的所有用戶請求被處理完畢后返回執(zhí)行步驟3.2)。所述步驟3.4)中通過工作者線程并發(fā)執(zhí)行所述請求集合中用戶請求并返回執(zhí)行結(jié)果的詳細(xì)實(shí)施步驟如下:
3.4.1)判斷所述請求集合是否為空,如果請求集合為空則等待;在所述請求集合非空時(shí),跳轉(zhuǎn)執(zhí)行下一步;
3.4.2)從所述請求集合中隨機(jī)取出一個(gè)用戶請求作為當(dāng)前用戶請求發(fā)送給Key-Value數(shù)據(jù)庫的后端數(shù)據(jù)處理引擎進(jìn)行讀寫數(shù)據(jù);3.4.3)將Key-Value數(shù)據(jù)庫的后端數(shù)據(jù)處理引擎輸出當(dāng)前用戶請求的執(zhí)行結(jié)果返回給用戶,在所述鍵碼分類排隊(duì)表中檢查當(dāng)前用戶請求的鍵碼對應(yīng)的待處理隊(duì)列中是否仍有用戶請求,如果仍有用戶請求則從所述對應(yīng)的待處理隊(duì)列的頭部彈出一個(gè)用戶請求并添加到所述請求集合中,如果沒有用戶請求則將當(dāng)前用戶請求的鍵碼與對應(yīng)的待處理隊(duì)列的映射關(guān)系從所述鍵碼分類排隊(duì)表中刪除;
3.4.4)跳轉(zhuǎn)執(zhí)行步驟3.4.1)。本發(fā)明Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法具有下述優(yōu)點(diǎn):
I)并行處理細(xì)粒度高、并發(fā)處理能力強(qiáng)、硬件資源利用率高、多核處理器下各個(gè)處理器核負(fù)載均衡。本發(fā)明根據(jù)用戶請求中鍵碼的不同,把取出的用戶請求分揀到鍵碼分類排隊(duì)表的不同待處理隊(duì)列中,實(shí)現(xiàn)將用戶請求“先分揀”的步驟,通過“先分揀”使得不同待處理隊(duì)列的用戶請求由于鍵碼不同,在并發(fā)執(zhí)行不同待處理隊(duì)列頭部的用戶請求時(shí)不會存在讀寫順序依賴,因此能夠從不同待處理隊(duì)列的頭部彈出并分發(fā)給多個(gè)工作者線程獨(dú)立并發(fā)處理,能夠?qū)崿F(xiàn)以無讀寫順序依賴關(guān)系的Key-Value數(shù)據(jù)請求為并發(fā)粒度進(jìn)行處理的,而且經(jīng)過“先分揀”步驟后的大量可并發(fā)請求在多核計(jì)算環(huán)境中時(shí),能夠最大限度的發(fā)揮多核CPU并發(fā)性能,且細(xì)粒度的并行處理使各個(gè)處理器核的工作負(fù)載也更為平均,具有并行處理細(xì)粒度高、并發(fā)處理能力強(qiáng)、硬件資源利用率高、多核處理器下各個(gè)處理器核負(fù)載均衡的優(yōu)點(diǎn)。2)能夠保證讀寫 依賴請求間順序。本發(fā)明將接收的用戶請求按照接收順序添加到請求緩沖隊(duì)列,且按照先進(jìn)先出的順序不斷從請求緩沖隊(duì)列中取出用戶請求,鍵碼分類排隊(duì)表中的各個(gè)待請求隊(duì)列是服從先進(jìn)先出原則的,因此對于相同的鍵碼,用戶發(fā)送的用戶請求的讀寫請求順序可以得到保障,因此本發(fā)明在最大限度挖掘Key-Value數(shù)據(jù)請求處理并發(fā)特性的同時(shí),也能夠使有讀寫相關(guān)性的請求的依賴關(guān)系得到保證,從而使得有讀寫依賴的請求之間的順序正確性能夠得到保證。
圖1為本發(fā)明實(shí)施例的方法流程示意圖。圖2為本發(fā)明實(shí)施例接收處理階段的接收原理示意圖,每I根波浪線表示I個(gè)接收線程。圖3為用戶請求的數(shù)據(jù)格式示意圖。圖4為本發(fā)明實(shí)施例分揀階段的分揀原理示意圖,上側(cè)的每I根波浪線表示I個(gè)接收線程;下側(cè)的I根波浪線為表示分揀階段的I個(gè)分揀線程。圖5為本發(fā)明實(shí)施例分揀階段的得到的鍵碼分類排隊(duì)表的結(jié)構(gòu)示意圖。圖6為本發(fā)明實(shí)施例并發(fā)請求處理階段進(jìn)行并發(fā)處理的原理示意圖,每I根波浪線表示I個(gè)運(yùn)行中的工作者線程。圖7為本發(fā)明實(shí)施例并發(fā)請求處理階段在T1時(shí)刻的用戶請求處理示意圖,每I根波浪線表示I個(gè)運(yùn)行中的工作者線程。圖8為本發(fā)明實(shí)施例并發(fā)請求處理階段在T2時(shí)刻的用戶請求處理示意圖,每I根波浪線表示I個(gè)運(yùn)行中的工作者線程。
具體實(shí)施例方式如圖1所示,本實(shí)施例Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法的實(shí)施步驟如下:
1)接收用戶請求并按接收順序加入請求緩沖隊(duì)列;
2)首先初始化用于存儲鍵碼與待處理隊(duì)列之間一一映射關(guān)系的鍵碼分類排隊(duì)表,然后持續(xù)按照先進(jìn)先出的順序從請求緩沖隊(duì)列中彈出用戶請求,根據(jù)用戶請求中鍵碼Key的不同分揀到不同待處理隊(duì)列中,并將鍵碼Key與待處理隊(duì)列的映射關(guān)系添加至鍵碼分類排隊(duì)表中;
3)首先初始化用于可并發(fā)處理的請求集合,然后持續(xù)彈出各個(gè)待處理隊(duì)列頭部的用戶請求并加入至請求集合中,使用預(yù)設(shè)數(shù)量的工作者線程并行處理請求集合中的用戶請求,并向用戶返回處理結(jié)果。本實(shí)施例由三個(gè)處理階段構(gòu)成,第一階段為用戶請求的接收處理階段,即前述步驟I);第二階段為分揀階段,即前述步驟2);第三階段為用戶請求的并發(fā)請求處理階段,即前述步驟3)。上述三階段是并行執(zhí)行的關(guān)系,但從功能上構(gòu)成用戶請求處理的流水線,從而實(shí)現(xiàn)細(xì)粒度并發(fā)的Key-Value數(shù)據(jù)庫用戶請求處理。與已有的Key-Value數(shù)據(jù)庫并發(fā)請求處理方法不同,本實(shí)施例對用戶請求實(shí)現(xiàn)細(xì)粒度并發(fā)處理的核心是“先分揀,再并發(fā)”。其中,“分揀”是指步驟2)中按照先進(jìn)先出的順序從請求緩沖隊(duì)列中彈出用戶請求,根據(jù)用戶請求中鍵碼Key的不同分揀到不同待處理隊(duì)列中,并將鍵碼Key與待處理隊(duì)列的映射關(guān)系添加至鍵碼分類排隊(duì)表中,因此使得其中每個(gè)待處理隊(duì)列與鍵碼Key—一對應(yīng),分揀后的不同待處理隊(duì)列中的用戶請求之間不存在任何寫后讀順序相關(guān)和讀后寫順序相關(guān),可以完全被并發(fā)地處理?!安l(fā)”是指步驟3)中持續(xù)彈出各個(gè)待處理隊(duì)列頭部的用戶請求并加入至請求集合中,使用預(yù)設(shè)數(shù)量的工作者線程并行處理請求集合中的用戶請求,并向用戶返回處理結(jié)果,通過設(shè)置工作者線程數(shù)量,能夠根據(jù)CPU數(shù)量最大化并發(fā)地將不同待處理隊(duì)列頭部的用戶請求發(fā)送到Key-Value數(shù)據(jù)庫的后端進(jìn)行并行數(shù)據(jù)存取,能夠始終最大程度地并發(fā)處理無讀寫順序依賴的用戶請求,大大提升Key-Value數(shù)據(jù)庫的系統(tǒng)性能。而且由于并發(fā)處理的請求間具有無讀寫順序相關(guān)的特性,使得待處理的請求可以均勻地分派到不同的處理器核上處理,從而大大提升多核處理器的負(fù)載均衡性和處理效能。參見圖2,本實(shí)施例中步驟I)接收處理階段的詳細(xì)實(shí)施步驟如下:
1.1)監(jiān)控用戶指定的網(wǎng)絡(luò)端口,當(dāng)有一個(gè)新的套接字用戶連接(socket用戶連接)建立后為對應(yīng)的用戶啟動一個(gè)接收線程,通過各個(gè)用戶對應(yīng)的接收線程分別接收用戶發(fā)出的用戶請求;
1.2)將接收的用戶請求附帶上用戶消息,然后按接收順序添加到請求緩沖隊(duì)列的頭部。參見圖3所示,用戶發(fā)出的用戶請求(Key-Value請求)格式中:K是具體的鍵碼值(Key值);0是該用戶請求的操作類型,即Key-Value請求的操作,可以是讀、寫、刪除等;V是Value的值,即寫入Key-Value數(shù)據(jù)庫中對應(yīng)鍵碼Key對應(yīng)節(jié)點(diǎn)的數(shù)據(jù),V根據(jù)操作的不同,可以為空,比如讀或刪除操作的用戶請求中Value為空。參見圖2,本實(shí)施例中步驟I)接收處理階段接收到3個(gè)用戶請 求=ReqpReq2Jeq3,按照接收順序加入到了請求緩沖隊(duì)列中,Req1位于最前側(cè)將最先被分揀處理;Req3位于最后側(cè)將最后被分揀處理。當(dāng)接收線程接到用戶消息后,則需要將〈K,0,V〉的請求數(shù)據(jù)轉(zhuǎn)換成Req:〈K,0,V,C〉請求結(jié)構(gòu)(其中C是代表當(dāng)前的用戶連接,用于返回結(jié)果時(shí)使用)加入到請求緩沖隊(duì)列(ReqQueue)中,請求緩沖隊(duì)列滿足先進(jìn)先出的進(jìn)出規(guī)則。為了描述方便,本實(shí)施例中將附帶上用戶消息的用戶請求Reqk定義為一個(gè)四元組:Reqk: <Kk, Ok, Vk,Ck>。其中,Reqk表示接收到的用戶請求,而下標(biāo)k表示按照接收時(shí)間序的第k個(gè)用戶請求。本實(shí)施例的四元組<Kk, Ok, Vk, Ck>中:Kk字段表示第k個(gè)用戶請求Reqk的鍵碼值(Key值);0k字段表示第k個(gè)用戶請求Reqk的數(shù)據(jù)庫增、刪、改、查等操作;Vk字段表示第k個(gè)用戶請求Reqk的Value值,如果Ok操作不需要Value (如讀操作和刪除操作等)則Vk的值為空;Ck為當(dāng)前請求對應(yīng)的用戶連接。四元組僅是本實(shí)施例對用戶請求的描述方式之一,在具體實(shí)現(xiàn)時(shí)根據(jù)具體需要的不同采用其它不同的描述方法。本實(shí)施例中,步驟2)分揀階段的詳細(xì)實(shí)施步驟如下: 2.1)初始化用于存儲鍵碼與待處理隊(duì)列之間一一映射關(guān)系的鍵碼分類排隊(duì)表(Key分類排隊(duì)表)為空,跳轉(zhuǎn)執(zhí)行下一步;
2.2)判斷請求緩沖隊(duì)列是否為空,如果請求緩沖隊(duì)列為空則繼續(xù)等待直至請求緩沖隊(duì)列非空,在請求緩沖隊(duì)列非空時(shí)跳轉(zhuǎn)執(zhí)行下一步;
2.3)按照先進(jìn)先出的原則,從請求緩沖隊(duì)列的尾部彈出最先進(jìn)入請求緩沖隊(duì)列的用戶請求Reqk:〈Kk, Ok, Vk, Ck>,跳轉(zhuǎn)執(zhí)行下一步;
2.4)在鍵碼分類排隊(duì)表中查找是否有與被彈出用戶請求Reqk的鍵碼Kk相對應(yīng)的待處理隊(duì)列,如果有則將被彈出用戶請求Reqk添加到對應(yīng)的待處理隊(duì)列尾部,將被彈出用戶請求Reqk的鍵碼Kk和待處理隊(duì)列的映射關(guān)系添加至鍵碼分類排隊(duì)表中;否則,新建一個(gè)以被彈出用戶請求Reqk為頭的待處理隊(duì)列,將被彈出用戶請求Reqk的鍵碼Kk和新建待處理隊(duì)列的映射關(guān)系添加至鍵碼分類排隊(duì)表中;跳轉(zhuǎn)執(zhí)行下一步;
2.5)跳轉(zhuǎn)執(zhí)行步驟2.2)。如圖4所示,本實(shí)施例中分揀階段啟動唯一的一個(gè)分揀線程。分揀線程不斷從請求緩沖隊(duì)列中按先進(jìn)先出順序取出收到的用戶請求,并建立鍵碼分類排隊(duì)表(Key分類排隊(duì)表),本實(shí)施例的鍵碼分類排隊(duì)表為一個(gè)Hash表,根據(jù)鍵碼Key的不同,把用戶請求分類加入不同的待處理隊(duì)列,此外也可以根據(jù)需要采用其它形式存儲鍵碼和待處理隊(duì)列。鍵碼分類排隊(duì)表中,待處理隊(duì)列與用戶請求的鍵碼Key是一一對應(yīng)的映射關(guān)系,每一個(gè)處理請求隊(duì)列只對應(yīng)唯一的一個(gè)鍵碼Key,且用于存儲該鍵碼Key對應(yīng)的用戶請求,當(dāng)處理請求隊(duì)列的所有用戶請求被彈出后,則將空的處理請求隊(duì)列刪除。假設(shè)當(dāng)前系統(tǒng)接收到3個(gè)用戶請求,且接收順序?yàn)?
Reqil: ^Ki, Oil, Vil, Cn〉,Reqjl: ^Kj-, Ojl, Vj1, Cj1^,Reqi2:〈K” 0i2, Vi2, Ci2〉。為了描述方便,本實(shí)施例中假設(shè)第一個(gè)Reqil和第三個(gè)Reqi2中的鍵碼Key是相同的(都為I)。參見圖4,本實(shí)施例針對上述3個(gè)用戶請求進(jìn)行分揀的詳細(xì)執(zhí)行步驟如下:
第①步,從緩沖隊(duì)列中取出第一個(gè)用戶請求Reqil:〈K” 0n,Vn,Cn>,根據(jù)Reqil中的鍵碼Ki在鍵碼分類排隊(duì)表中進(jìn)行查找,由于是第一個(gè)用戶請求,因此鍵碼分類排隊(duì)表中尚無任何鍵碼Key與待處理隊(duì)列的映射關(guān)系。因此,分揀線程在鍵碼分類排隊(duì)表中創(chuàng)建Ki — (Reqil)的映射,其中(Reqil)表不一個(gè)待處理隊(duì)列,該待處理隊(duì)列包含一個(gè)兀素Reqn。
第②步,從緩沖隊(duì)列中取出第二個(gè)用戶請求Reqjl:〈K」,Ojl, Vjl, Cjl),根據(jù)Reqjl中的鍵碼Kj在鍵碼分類排隊(duì)表中進(jìn)行查找。由于此時(shí)仍舊沒有鍵碼Kj所對應(yīng)的待處理隊(duì)列,因此分揀線程在鍵碼分類排隊(duì)表中創(chuàng)建K」一 (Reqjl)的映射,其中(Reqjl)表示一個(gè)待處理隊(duì)列,該待處理隊(duì)列包含一個(gè)元素Reqjlt5第③步,從緩沖隊(duì)列中取出第三個(gè)用戶請求Reqi2KKi, 0i2, Vi2, Ci2>,根據(jù)Reqi2中的鍵碼Ki在鍵碼分類排隊(duì)表中進(jìn)行查找。分揀線程找到了 I— (Reqil)的映射,于是,將第三個(gè)用戶請求Reqi2添加到待處理隊(duì)列Reqil的尾部,成為=Ki — (Reqil, Reqi2)。通過上述3個(gè)步驟,接收的3個(gè)請求就分別被分揀完畢,此時(shí)鍵碼分類排隊(duì)表的結(jié)構(gòu)如圖4的下部所示,鍵碼分類排隊(duì)表包含2個(gè)待處理隊(duì)列〈(Reqjl)、(Reqil, Reqi2) >,并通過Kj — (Reqjl)和Ki — (Reqil, Reqi2)的映射關(guān)系分別與鍵碼Kj和Ki相對應(yīng)。經(jīng)過分揀階段后,鍵碼分類排隊(duì)表根據(jù)用戶請求中鍵碼Key的不同,把取出的用戶請求分類存儲在不同待處理隊(duì)列中,因此不同待處理隊(duì)列頭部的用戶請求由于鍵碼Key不同,不會存在讀寫順序依賴,從而能夠從不同待處理隊(duì)列的頭部彈出并分發(fā)給多個(gè)工作者線程獨(dú)立并發(fā)處理。如圖5所示,鍵碼分類排隊(duì)表在正常運(yùn)行時(shí)會包含大量的待處理隊(duì)列,其中1、Kj>…、Kn為所有用戶請求中的不重復(fù)的鍵碼Key,每一個(gè)鍵碼Key都映射有一個(gè)待處理隊(duì)列,例如鍵碼Ki映射的待處理隊(duì)列為(Reqn,Reqi2,…)、鍵碼Kj映射的待處理隊(duì)列為(Reqjl,…)、…、鍵碼Kn映射的待處理隊(duì)列為(Reqnl,Reqn2,…)。本實(shí)施例通過對用戶請求的分揀,在鍵碼分類排隊(duì)表中將用戶請求按照鍵碼的不同分揀到不同的待處理隊(duì)列中,因此不同待處理隊(duì)列頭部的用戶請求由于鍵碼Key不同,不會存在讀寫順序依賴,從而能夠從不同待處理隊(duì)列的頭部彈出并分發(fā)給多個(gè)工作者線程獨(dú)立并發(fā)處理。本實(shí)施例中,步驟3)并發(fā)請求處理階段的詳細(xì)實(shí)施步驟如下:
3.1)初始化用于存儲可并發(fā)處理用戶請求的請求集合pset為空,跳轉(zhuǎn)執(zhí)行下一步;
3.2)檢查鍵碼分類排隊(duì)表中是否有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,如果沒有則繼續(xù)等待直到鍵碼分類排隊(duì)表中有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,在鍵碼分類排隊(duì)表有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系時(shí)則跳轉(zhuǎn)執(zhí)行下一步;
3.3)找出新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,將新增的映射關(guān)系中鍵碼所對應(yīng)各個(gè)待處理隊(duì)列頭部的用戶請求彈出并添加到請求集合pset中,跳轉(zhuǎn)執(zhí)行下一步;
3.4)判斷預(yù)設(shè)數(shù)量的工作者線程是否啟動,如果沒有則啟動預(yù)設(shè)數(shù)量的工作者線程;通過工作者線程并發(fā)執(zhí)行請求集合中用戶請求并返回執(zhí)行結(jié)果,在請求集合pset中的所有用戶請求被處理完畢后返回執(zhí)行步驟3.2)。本實(shí)施例中,步驟3.4)中通過工作者線程并發(fā)執(zhí)行請求集合中用戶請求并返回執(zhí)行結(jié)果的詳細(xì)實(shí)施步驟如下:
3.4.1)判斷請求集合是否為空,如果請求集合為空則等待;在請求集合非空時(shí),跳轉(zhuǎn)執(zhí)行下一步;
3.4.2)從請求集合pset中隨機(jī)取出一個(gè)用戶請求作為當(dāng)前用戶請求發(fā)送給Key-Value數(shù)據(jù)庫的后端數(shù)據(jù)處理引擎進(jìn)行讀寫數(shù)據(jù);
3.4.3)將Key-Value數(shù)據(jù)庫的后端數(shù)據(jù)處理引擎輸出當(dāng)前用戶請求的執(zhí)行結(jié)果返回給用戶,在鍵碼分類排隊(duì)表中檢查當(dāng)前用戶請求的鍵碼對應(yīng)的待處理隊(duì)列中是否仍有用戶請求,如果仍有用戶請求則從對應(yīng)的待處理隊(duì)列的頭部彈出一個(gè)用戶請求并添加到請求集合中,如果沒有用戶請求則將當(dāng)前用戶請求的鍵碼與對應(yīng)的待處理隊(duì)列的映射關(guān)系從鍵碼分類排隊(duì)表中刪除;
3.4.4)跳轉(zhuǎn)執(zhí)行步驟3.4.1)。如圖6所示,本實(shí)施例并發(fā)請求處理階段將各個(gè)待處理隊(duì)列頭部的用戶請求Reqil> Reqjl,…、Reqnl添加到請求集合pset中,通過多個(gè)工作者線程進(jìn)行并發(fā)處理。由于Reqn、ReqjP…、Reqnl的鍵碼Key均不同,因此能夠并行處理而不會相互影響。并發(fā)請求處理階段初始時(shí)啟動n個(gè)工作者線程,n的具體數(shù)值由用戶根據(jù)CPU核心數(shù)量自行指定(n>=l)。本實(shí)施例中工作者線程數(shù)量n為2。初始情況下,鍵碼分類排隊(duì)表為空,因此,2個(gè)工作者線程都在等待鍵碼分類排隊(duì)表中有待處理的用戶請求加入。如圖7所示,假定T1時(shí)刻鍵碼分類排隊(duì)表(key分類排隊(duì)表)中累積有待處理的用戶請求ReqmReqyReqi2,在并發(fā)請求處理階段時(shí),將首先提取鍵碼分類排隊(duì)表中所有待處理隊(duì)列中的頭部請求(即鍵碼Ki映射待處理隊(duì)列(Reqn,Reqi2)頭部的Reqil、鍵碼Kj映射待處理隊(duì)列(Reqjl)頭部的Reqjl),將Reqil和Reqjl分別移出待處理隊(duì)列并添加到請求集合pset中,通過請求集合pset均衡地交給2個(gè)工作者線程并發(fā)處理。其中,由于Reqjl被移出,&所對應(yīng)的待處理隊(duì)列為空,因此需要從鍵碼分類排隊(duì)表中移除I —()的映射關(guān)系將空的待處理隊(duì)列刪除。如圖8所示,假設(shè)用戶請求Reqil先于用戶請求Reqjl處理完成,記此時(shí)刻為T2, T2時(shí)刻鍵碼分類排隊(duì)表(key分類排隊(duì)表)中待處理的用戶請求只剩下Reqi2。在并發(fā)請求處理階段時(shí),檢查已完成的用戶請求Reqil中鍵碼Ki是否還對應(yīng)有待處理隊(duì)列,此刻由于鍵碼Ki所對應(yīng)的待處理隊(duì)列為(Reqi2),即其中仍有一個(gè)待處理的用戶請求Reqi2,因此此時(shí)將取出用戶請求Reqi2并添加到請求集合pset并送入空閑的工作者線程中,與尚未完成的用戶請求Reqj2并發(fā)處理。以 此類推,2個(gè)工作者線程循環(huán)往復(fù)地對用戶發(fā)出的用戶請求進(jìn)行細(xì)粒度并發(fā)處理。以上所述僅是本發(fā)明的優(yōu)選實(shí)施方式,本發(fā)明的保護(hù)范圍并不僅局限于上述實(shí)施例,凡屬于本發(fā)明思路下的技術(shù)方案均屬于本發(fā)明的保護(hù)范圍。應(yīng)當(dāng)指出,對于本技術(shù)領(lǐng)域的普通技術(shù)人員來說,在不脫離本發(fā)明原理前提下的若干改進(jìn)和潤飾,這些改進(jìn)和潤飾也應(yīng)視為本發(fā)明的保護(hù)范圍。
權(quán)利要求
1.一種Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法,其特征在于實(shí)施步驟如下: 1)接收用戶請求并按接收順序加入請求緩沖隊(duì)列; 2)首先初始化用于存儲鍵碼與待處理隊(duì)列之間一一映射關(guān)系的鍵碼分類排隊(duì)表,然后持續(xù)按照先進(jìn)先出的順序從所述請求緩沖隊(duì)列中彈出用戶請求,根據(jù)用戶請求中鍵碼的不同分揀到不同待處理隊(duì)列中,并將鍵碼與待處理隊(duì)列的映射關(guān)系添加至所述鍵碼分類排隊(duì)表中; 3)首先初始化用于可并發(fā)處理的請求集合,然后持續(xù)彈出各個(gè)待處理隊(duì)列頭部的用戶請求并加入至所述請求集合中,使用預(yù)設(shè)數(shù)量的工作者線程并行處理所述請求集合中的用戶請求,并向用戶返回處理結(jié)果。
2.根據(jù)權(quán)利要求1所述的Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法,其特征在于,所述步驟I)的詳細(xì)實(shí)施步驟如下: .1.1)監(jiān)控用戶指定的網(wǎng)絡(luò)端口,當(dāng)有一個(gè)新的套接字用戶連接建立后為對應(yīng)的用戶啟動一個(gè)接收線程,通過各個(gè)用戶對應(yīng)的接收線程分別接收用戶發(fā)出的用戶請求; . 1.2)將接收的用戶請求附帶上用戶消息,然后按接收順序添加到請求緩沖隊(duì)列的頭部。
3.根據(jù)權(quán)利要求2所述的Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法,其特征在于,所述步驟2)的詳細(xì)實(shí)施步驟如下: 2.1)初始化用于存儲鍵碼與待處理隊(duì)列之間一一映射關(guān)系的鍵碼分類排隊(duì)表為空,跳轉(zhuǎn)執(zhí)行下一步; 2.2)判斷所述請求緩沖隊(duì)列是否為空,如果所述請求緩沖隊(duì)列為空則繼續(xù)等待直至請求緩沖隊(duì)列非空,在請求緩沖隊(duì)列非空時(shí)跳轉(zhuǎn)執(zhí)行下一步; 2.3)按照先進(jìn)先出的原則,從所述請求緩沖隊(duì)列的尾部彈出最先進(jìn)入所述請求緩沖隊(duì)列的用戶請求,跳轉(zhuǎn)執(zhí)行下一步; 2.4)在所述鍵碼分類排隊(duì)表中查找是否有與被彈出用戶請求的鍵碼相對應(yīng)的待處理隊(duì)列,如果有則將被彈出用戶請求添加到所述對應(yīng)的待處理隊(duì)列尾部,將被彈出用戶請求的鍵碼和所述待處理隊(duì)列的映射關(guān)系添加至所述鍵碼分類排隊(duì)表中;否則,新建一個(gè)以被彈出用戶請求為頭的待處理隊(duì)列,將被彈出用戶請求的鍵碼和新建待處理隊(duì)列的映射關(guān)系添加至所述鍵碼分類排隊(duì)表中;跳轉(zhuǎn)執(zhí)行下一步; 2.5)跳轉(zhuǎn)執(zhí)行步驟2.2)。
4.根據(jù)權(quán)利要求3所述的Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法,其特征在于,所述步驟3)的詳細(xì)實(shí)施步驟如下: .3.1)初始化用于存儲可并發(fā)處理用戶請求的請求集合為空,跳轉(zhuǎn)執(zhí)行下一步; .3.2)檢查所述鍵碼分類排隊(duì)表中是否有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,如果沒有則繼續(xù)等待直到所述鍵碼分類排隊(duì)表中有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,在所述鍵碼分類排隊(duì)表有新增鍵碼與待處理隊(duì)列之間的映射關(guān)系時(shí)則跳轉(zhuǎn)執(zhí)行下一步; .3.3)找出所述新增鍵碼與待處理隊(duì)列之間的映射關(guān)系,將所述新增的映射關(guān)系中鍵碼所對應(yīng)各個(gè)待處理隊(duì)列頭部的用戶請求彈出并添加到所述請求集合中,跳轉(zhuǎn)執(zhí)行下一步; .3.4)判斷預(yù)設(shè)數(shù)量的工作者線程是否啟動,如果沒有則啟動預(yù)設(shè)數(shù)量的工作者線程;通過所述工作者線程并發(fā)執(zhí)行所述請求集合中用戶請求并返回執(zhí)行結(jié)果,在所述請求集合中的所有用戶請求被處理完畢后返回執(zhí)行步驟3.2)。
5.根據(jù)權(quán)利要求4所述的Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法,其特征在于,所述步驟3.4)中通過工作者線程并發(fā)執(zhí)行所述請求集合中用戶請求并返回執(zhí)行結(jié)果的詳細(xì)實(shí)施步驟如下: .3.4.1)判斷所述請求集合是否為空,如果請求集合為空則等待;在所述請求集合非空時(shí),跳轉(zhuǎn)執(zhí)行下一步; . 3.4.2)從所述請求集合中隨機(jī)取出一個(gè)用戶請求作為當(dāng)前用戶請求發(fā)送給Key-Value數(shù)據(jù)庫的后端數(shù)據(jù)處理引擎進(jìn)行讀寫數(shù)據(jù); .3.4.3)將Key-Value數(shù)據(jù)庫的后端數(shù)據(jù)處理引擎輸出當(dāng)前用戶請求的執(zhí)行結(jié)果返回給用戶,在所述鍵碼分類排隊(duì)表中檢查當(dāng)前用戶請求的鍵碼對應(yīng)的待處理隊(duì)列中是否仍有用戶請求,如果仍有用戶請求則從所述對應(yīng)的待處理隊(duì)列的頭部彈出一個(gè)用戶請求并添加到所述請求集合中,如果沒有用戶請求則將當(dāng)前用戶請求的鍵碼與對應(yīng)的待處理隊(duì)列的映射關(guān)系從所述鍵碼分類排隊(duì)表中刪除; . 3.4.4)跳轉(zhuǎn)執(zhí)行步驟3.4.1)。
全文摘要
本發(fā)明公開了一種Key-Value數(shù)據(jù)庫用戶請求的高速并發(fā)處理方法,其實(shí)施步驟如下1)接收用戶請求并順序加入請求緩沖隊(duì)列;2)初始化鍵碼分類排隊(duì)表,持續(xù)按照先進(jìn)先出的順序從請求緩沖隊(duì)列中彈出用戶請求,根據(jù)用戶請求中鍵碼的不同分揀到不同待處理隊(duì)列中,并將鍵碼與待處理隊(duì)列的映射關(guān)系添加至鍵碼分類排隊(duì)表中;3)初始化請求集合,持續(xù)彈出各待處理隊(duì)列頭部的用戶請求至請求集合中,使用預(yù)設(shè)數(shù)量的工作者線程并行處理請求集合中的用戶請求,并向用戶返回處理結(jié)果。本發(fā)明具有并行處理細(xì)粒度高、并發(fā)處理能力強(qiáng)、硬件資源利用率高、多核處理器下各個(gè)處理器核負(fù)載均衡、能夠保證讀寫依賴請求間順序的優(yōu)點(diǎn)。
文檔編號G06F17/30GK103218455SQ20131016402
公開日2013年7月24日 申請日期2013年5月7日 優(yōu)先權(quán)日2013年5月7日
發(fā)明者李 根, 王睿伯, 盧凱, 遲萬慶, 馮華, 蔣杰, 劉勇鵬, 高穎慧, 唐宏偉, 樊葆華, 王小平 申請人:中國人民解放軍國防科學(xué)技術(shù)大學(xué)