一種鍵值數(shù)據(jù)庫(kù)的內(nèi)存分配方法
【技術(shù)領(lǐng)域】
[0001]本發(fā)明涉及數(shù)據(jù)庫(kù)設(shè)計(jì)領(lǐng)域,更具體地涉及一種鍵值數(shù)據(jù)庫(kù)的內(nèi)存分配方法。
【背景技術(shù)】
[0002]內(nèi)存分配器(Memory Allocator)介于內(nèi)核與用戶程序之間,負(fù)責(zé)處理用戶的分配請(qǐng)求,其根據(jù)一定的規(guī)則向操作系統(tǒng)申請(qǐng)內(nèi)存,然后將適合的內(nèi)存空間返回給請(qǐng)求進(jìn)程。
[0003]內(nèi)存分配器的職責(zé)概括為:向操作系統(tǒng)申請(qǐng)大塊內(nèi)存,并通過(guò)一定的策略管理這些內(nèi)存,將這些內(nèi)存分為兩部分:已分配內(nèi)存和空閑內(nèi)存,對(duì)每種內(nèi)存進(jìn)行特定管理。當(dāng)用戶進(jìn)程提出內(nèi)存分配需求時(shí),內(nèi)存分配器首先在空閑空間中尋找是否存在合適的內(nèi)存,如果找不到合適的內(nèi)存,則分配一塊新的內(nèi)存。更具體地,當(dāng)某一線程需要調(diào)用mallocO分配內(nèi)存空間時(shí),該線程先查看線程私有變量中是否已經(jīng)存在一個(gè)分配區(qū),如果存在,嘗試對(duì)該分配區(qū)加鎖,如果加鎖成功,使用該分配區(qū)分配內(nèi)存;如果失敗,該線程搜索循環(huán)鏈表試圖獲得一個(gè)沒(méi)有加鎖的分配區(qū)。如果所有的分配區(qū)都已經(jīng)加鎖,那么mallocO會(huì)開(kāi)辟一個(gè)新的分配區(qū),把該分配區(qū)加入到全局分配區(qū)循環(huán)鏈表并加鎖,然后使用該分配區(qū)進(jìn)行分配內(nèi)存操作。在釋放操作中,線程同樣試圖獲得待釋放內(nèi)存塊所在分配區(qū)的鎖,如果該分配區(qū)正在被別的線程使用,則需要等待直到其他線程釋放該分配區(qū)的互斥鎖之后才可以進(jìn)行釋放操作。
[0004]對(duì)于高并發(fā)的需求,數(shù)據(jù)庫(kù)申請(qǐng)內(nèi)存的需求非常頻繁,而若使用傳統(tǒng)的malloc-free函數(shù)來(lái)分配和釋放內(nèi)存,則會(huì)帶來(lái)大量的鎖操作,而且會(huì)受到數(shù)據(jù)庫(kù)運(yùn)行環(huán)境上其他進(jìn)程的影響。通過(guò)測(cè)試發(fā)現(xiàn),使用傳統(tǒng)的malloc-free函數(shù)進(jìn)行內(nèi)存申請(qǐng)和釋放,消耗的時(shí)間為數(shù)據(jù)寫(xiě)入MemTable總時(shí)間的15_40%。這一情形尤其是應(yīng)用于處理物聯(lián)網(wǎng)數(shù)據(jù)時(shí)更甚,物聯(lián)網(wǎng)數(shù)據(jù)大多來(lái)自無(wú)線傳感器,其主要特點(diǎn)是數(shù)據(jù)條數(shù)多,但每條數(shù)據(jù)較短,并且具有時(shí)序性。由此,如何優(yōu)化內(nèi)存分配是迫切需要解決的一個(gè)技術(shù)問(wèn)題。
【發(fā)明內(nèi)容】
[0005]有鑒于此,本發(fā)明的主要目的在于提供一種鍵值數(shù)據(jù)庫(kù)的快速內(nèi)存分配方法,以適應(yīng)高并發(fā)數(shù)據(jù)頻繁內(nèi)存分配的需求,實(shí)現(xiàn)快速有效的內(nèi)存分配。
[0006]為了實(shí)現(xiàn)上述目的,作為本發(fā)明的一個(gè)方面,本發(fā)明提供一種鍵值數(shù)據(jù)庫(kù)的內(nèi)存分配方法,包括以下步驟:
[0007]接收用戶內(nèi)存分配請(qǐng)求;
[0008]判斷所需分配的塊的大小是否不大于快速分配容器中塊大小的最大值MAX_FAST ;如果不大于,則在快速分配容器中找一個(gè)所需大小的塊分配給用戶,如果找到則整個(gè)分配流程結(jié)束,如果找不到則繼續(xù)下一步;如果大于,也繼續(xù)下一步;
[0009]判斷未分類(lèi)容器中是否存在滿足要求的塊,如果滿足,則給用戶分配內(nèi)存,整個(gè)分配流程結(jié)束;否則繼續(xù)下一步;
[0010]判斷所需分配的塊是否存在于小容器中,如果存在于小容器中,則給用戶分配內(nèi)存,整個(gè)分配流程結(jié)束;否則繼續(xù)下一步;
[0011]判斷所需分配的塊是否存在于大容器中,如果存在于大容器中,則給用戶分配內(nèi)存,整個(gè)分配流程結(jié)束;否則繼續(xù)下一步;
[0012]直接從中央資源池中分配相適應(yīng)的存儲(chǔ)空間,整個(gè)分配流程結(jié)束。
[0013]其中,所述直接從中央資源池中分配相適應(yīng)的存儲(chǔ)空間的步驟按照“最小優(yōu)先、最佳適應(yīng)”的原則。
[0014]其中,所述直接從中央資源池中分配相適應(yīng)的存儲(chǔ)空間的步驟還包括從中央資源池中切割所需分配的塊,并將切割剩余的部分存儲(chǔ)到相適應(yīng)的進(jìn)程緩沖區(qū)的相應(yīng)容器中。
[0015]其中,在所述判斷未分類(lèi)容器中是否存在滿足要求的塊的步驟之前還包括整理所述快速分配容器,將用戶釋放的大于MAX_FAST的塊,或快速分配容器中的空閑塊合并后,放到未分類(lèi)容器隊(duì)列中的步驟。
[0016]其中,所述大容器中存放的為塊大小大于512字節(jié)的塊,所述小容器中存放的為塊大小小于等于512字節(jié)的塊。
[0017]作為本發(fā)明的另一個(gè)方面,本發(fā)明還提供了一種鍵值數(shù)據(jù)庫(kù)的內(nèi)存釋放方法,包括以下步驟:
[0018]判斷需要釋放的內(nèi)存是否直接由局部緩存區(qū)內(nèi)存分配函數(shù)_ap O得來(lái),如果是,則調(diào)用對(duì)應(yīng)的釋放函數(shù)munmap O,釋放相應(yīng)空間;
[0019]將塊放入到快速分配容器中,塊放入到快速分配容器中時(shí),并不修改塊使用狀態(tài)位P,也不與相鄰的塊進(jìn)行合并,僅僅是簡(jiǎn)單的放入。
[0020]其中,還包括內(nèi)存分配器定期回收和合并快速分配容器中的塊的步驟。
[0021]其中,當(dāng)用戶釋放的塊大于快速分配容器中塊大小的最大值MAX_FAST,或者快速分配容器中的空閑塊合并后,將所述塊放到未分類(lèi)容器隊(duì)列中。
[0022]基于上述技術(shù)方案可知,本發(fā)明的內(nèi)存分配方法采用進(jìn)程局部緩存技術(shù)來(lái)解決加鎖問(wèn)題,用戶請(qǐng)求的分配空間用塊來(lái)表示,小內(nèi)存空間的分配可以直接由進(jìn)程局部緩存來(lái)返回,從而可以減少大量的內(nèi)存鎖操作,提高內(nèi)存分配進(jìn)度和有效性,更加適合于高并發(fā)數(shù)據(jù)的處理;本發(fā)明的內(nèi)存釋放時(shí),優(yōu)先放到快速分配容器中,可在出現(xiàn)新的請(qǐng)求時(shí)直接應(yīng)用,減少了合并空閑資源再重新分配的冗余操作;定期進(jìn)行容器整理,合并快速分配容器中的塊,并將合并后的塊歸入適當(dāng)?shù)娜萜髦?,可以保證內(nèi)存分配方法有序執(zhí)行。
【附圖說(shuō)明】
[0023]圖1是本發(fā)明的內(nèi)存分配器存儲(chǔ)管理結(jié)構(gòu)的框架示意圖;
[0024]圖2是本發(fā)明的內(nèi)存中塊結(jié)構(gòu)的示意圖;
[0025]圖3是本發(fā)明的內(nèi)存分配管理器響應(yīng)用戶內(nèi)存分配要求的具體步驟的流程圖。
【具體實(shí)施方式】
[0026]為使本發(fā)明的目的、技術(shù)方案和優(yōu)點(diǎn)更加清楚明白,以下結(jié)合具體實(shí)施例,并參照附圖,對(duì)本發(fā)明作進(jìn)一步的詳細(xì)說(shuō)明。
[0027]本發(fā)明采用進(jìn)程局部緩存技術(shù)來(lái)解決內(nèi)存中加鎖的問(wèn)題,其主要思想是:小內(nèi)存空間的分配可以直接由進(jìn)程局部緩存來(lái)返回;當(dāng)進(jìn)程局部緩存中不存在進(jìn)程請(qǐng)求的空間時(shí),將相應(yīng)的內(nèi)存對(duì)象從中央資源池移動(dòng)到進(jìn)程局部緩存中,同時(shí)定期的垃圾回收機(jī)制負(fù)責(zé)把內(nèi)存從局部緩存迀移回中央資源池。下面對(duì)此進(jìn)行詳細(xì)的闡述。
[0028]用戶請(qǐng)求分配的空間在內(nèi)存分配器中都使用一個(gè)塊(chunk)來(lái)表示。用戶調(diào)用free O函數(shù)釋放掉的內(nèi)存也并不是立即就歸還給操作系統(tǒng),而是將它們也用塊來(lái)表示,內(nèi)存分配器使用特定的數(shù)據(jù)結(jié)構(gòu)來(lái)管理這些空閑的塊,并給用戶分配空間的前后加上一些控制信息,用這樣的方法來(lái)記錄分配的信息,以便完成分配和釋放工作。
[0029]塊的結(jié)構(gòu)如圖2所示,為了使得塊所占用的空間最小,內(nèi)存分配器使用了空間復(fù)用,一個(gè)塊或者正在被使用,或者已經(jīng)被釋放(free),所以塊中的一些域可以在使用狀態(tài)和空閑狀態(tài)表示不同的意義,來(lái)達(dá)到空間復(fù)用的效果。
[0030]進(jìn)程局部緩存將相似大小的塊用雙向鏈表鏈接起來(lái),這樣的一個(gè)鏈表被稱為一個(gè)容器(bin)。容器類(lèi)型按容量大小分為3種:快速分配容器(fast bin)、未分類(lèi)容器(unsorted bin)和普通容器(bin),其中普通容器又可以分為小容器(small bin)和大容器(large bin)。
[0031 ] 塊的操作包括釋放和分配兩種操作。在分配過(guò)程中不大于MAX_FAST (默認(rèn)值為64字節(jié),如果為方便物聯(lián)網(wǎng)傳感器數(shù)據(jù)存儲(chǔ),則可以將其設(shè)置為200字節(jié))的塊被釋放后,首先會(huì)被放入到快速分配容器中。當(dāng)需要給用戶分配的塊小于或等于MAX_FAST時(shí),內(nèi)存分配器首先會(huì)在快速分配容器中查找相應(yīng)的空閑塊。在某個(gè)特定的時(shí)候,內(nèi)存分配器會(huì)遍歷快速分配容器中的塊,將相鄰的空閑塊進(jìn)行合并,并將合并后的塊加入到未分類(lèi)容器中。
[0032]如果被用戶釋放的塊大于MAX_FAST,或者快速分配容器中的空閑塊合并后,這些塊會(huì)被放到未分類(lèi)容器隊(duì)列中。在進(jìn)行內(nèi)存分配操作的時(shí)候,如果在快速分配容器中沒(méi)有找到合適的塊,則內(nèi)存分配器會(huì)先在未分類(lèi)容器中查找合適的空閑塊,然后才查找普通容器。
[0033]如果未分類(lèi)容器不能滿足分配要求,內(nèi)存分配器便會(huì)將未分類(lèi)容器中的塊加入到普通容器中。然后再?gòu)钠胀ㄈ萜髦欣^續(xù)進(jìn)行查找和分配過(guò)程。從這個(gè)過(guò)程可以看出來(lái)