溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

批量隨機(jī)鍵值查詢測試

發(fā)布時間:2020-06-04 03:57:59 來源:網(wǎng)絡(luò) 閱讀:185 作者:raqsoft 欄目:大數(shù)據(jù)

當(dāng)數(shù)據(jù)量巨大時,使用大批量隨機(jī)鍵值集獲取對應(yīng)記錄集合,不僅僅考驗數(shù)據(jù)庫軟件本身,更在于程序員對數(shù)據(jù)的理解!如何在硬件資源有限的情況下將性能發(fā)揮到極致?

本次測試主要針對集算器組表索引實(shí)現(xiàn)的批量鍵值取數(shù)性能,并與 Oracle 進(jìn)行同規(guī)模運(yùn)算對比。


一、測試環(huán)境


批量隨機(jī)鍵值查詢測試  


二、數(shù)據(jù)描述


2.1數(shù)據(jù)結(jié)構(gòu)



批量隨機(jī)鍵值查詢測試  


2.2數(shù)據(jù)規(guī)模


按以上數(shù)據(jù)結(jié)構(gòu),造出 6 億條記錄的行存組表文件和對應(yīng)的索引文件:



批量隨機(jī)鍵值查詢測試  


三、測試過程


3.1生成測試文件


3.1.1  建組表



批量隨機(jī)鍵值查詢測試  


A1:包含 26 個英文字母和 10 個阿拉伯?dāng)?shù)字的字符串。


A2、A3:建立結(jié)構(gòu)為 (id,data) 的組表文件,@r 選項表示使用行式存儲方式。


A4:循環(huán) 6000 次,循環(huán)體B4、B5,每次生成 10 萬條對應(yīng)結(jié)構(gòu)的記錄,并追加到組表文件。


執(zhí)行后,生成組表文件:id_600m.ctx


3.1.2  建索引


批量隨機(jī)鍵值查詢測試  


A2:根據(jù)組表文件的 id 列,建立組表索引。


執(zhí)行后,生成組表的索引文件:id_600m.ctx__id_idx


3.2查詢測試


批量隨機(jī)鍵值查詢測試  


A2:循環(huán)一萬次,每次獲取對應(yīng)組表文件 id 列中的隨機(jī)一個,并排序。(可能會有少量重復(fù)值,但對測試影響不大)


A4:在組表的 icursor()這個函數(shù)中,使用索引 id_idx,以條件 A2.contain(id) 來過濾組表。集算器會自動識別出 A2.contain(id) 這個條件可以使用索引,并會自動將 A2 的內(nèi)容排序后從前向后查找。


3.3奇怪的現(xiàn)象


原本希望多次執(zhí)行后,求得一個平均值作為測試結(jié)果。但是發(fā)現(xiàn)每執(zhí)行完畢一次該測試代碼,都會比上一次執(zhí)行快一些,這里列出從第一次執(zhí)行該代碼后的 5 次測試查詢耗時:


批量隨機(jī)鍵值查詢測試  


手動一次次點(diǎn)擊設(shè)計器中的執(zhí)行按鈕,并記錄下查詢耗時,太費(fèi)勁了。為了找出規(guī)律,將代碼改為以下形式:


批量隨機(jī)鍵值查詢測試  


B7:將循環(huán)體中 icursor() 函數(shù)每一次查詢的耗時,在 A1 中追加記錄下來。


執(zhí)行過程中,觀察 A1 中新追加的查詢耗時與上一次的比較,發(fā)現(xiàn)經(jīng)過大約 350 次循環(huán)后接近極限值 25 秒。再后續(xù)近千次循環(huán)中,查詢耗時也都是如此,基本穩(wěn)定。


難道是集算器對數(shù)據(jù)進(jìn)行了緩存?抱著懷疑的態(tài)度,重啟了集算器設(shè)計器,再次執(zhí)行了查詢代碼。發(fā)現(xiàn)重啟后第一次的查詢耗時也是 25 秒。這樣看來提速的原因和集算器本身并沒有什么直接的關(guān)系了。


另一方面,可以想到基于目前測試的數(shù)據(jù)量,能夠在短時間內(nèi)完成查詢,部分?jǐn)?shù)據(jù)可能已經(jīng)裝載至內(nèi)存,那么很可能是 linux 操作系統(tǒng)的文件緩存造成了這個現(xiàn)象。重啟服務(wù)器后,再通過集算器設(shè)計器來執(zhí)行查詢,發(fā)現(xiàn)耗時又開始從 80 秒左右慢慢減少了。


進(jìn)一步的測試中,使用了 linux 的 free 命令查看系統(tǒng)內(nèi)存使用情況。發(fā)現(xiàn)每完成一次組表的查詢,其中的 cached 一項就會變大。而隨著 cached 慢慢的變大,查詢的耗時又逐步減少。


3.4index@3的使用


在網(wǎng)絡(luò)上查詢了一些資料,了解到 Linux 會存在緩存內(nèi)存,通常叫做 Cache Memory。就是之前使用 free 命令看到其中的 cached 一項,執(zhí)行 free -h:


批量隨機(jī)鍵值查詢測試  


當(dāng)我們讀寫文件的時候,Linux 內(nèi)核為了提高讀寫效率與速度,會將文件在內(nèi)存中進(jìn)行緩存,這部分內(nèi)存就是 Cache Memory(緩存內(nèi)存)。即使我們的程序運(yùn)行結(jié)束后,Cache Memory 也不會自動釋放。這就會導(dǎo)致我們在 Linux 系統(tǒng)中程序頻繁讀寫文件后,我們會發(fā)現(xiàn)可用物理內(nèi)存會很少。其實(shí)這個緩存內(nèi)存在我們需要使用內(nèi)存的時候會自動釋放,所以我們不必?fù)?dān)心沒有內(nèi)存可用。并且手動去釋放 Cache Memory 也是有辦法的,但此處不再詳細(xì)探討。


這個函數(shù)涉及數(shù)據(jù)量有 111G,比機(jī)器的物理內(nèi)存 64G 更大,顯然不可能把所有數(shù)據(jù)都緩存到內(nèi)存中,那么到底緩存了哪些數(shù)據(jù)后就能穩(wěn)定地提高查詢性能呢?是不是可以事先就把需要這些數(shù)據(jù)先緩存起來以獲得高性能?請教了高手后,發(fā)現(xiàn)果然還有選項可以來預(yù)先緩存索引的索引。在使用 icursor()函數(shù)查詢之前,對組表索引使用了 T.index@2(idx) 使用了 T.index@3(idx)。代碼如下: 


批量隨機(jī)鍵值查詢測試  


集算器的索引有個分級緩存,@3 的意思是將索引的第三級緩存先加載進(jìn)內(nèi)存。經(jīng)過 index@3 預(yù)處理,第一遍查詢時間也能達(dá)到上面查詢數(shù)百次后才能達(dá)到的極限值。


四、與 Oracle 對比


測試環(huán)境、數(shù)據(jù)結(jié)構(gòu)和規(guī)模與上文一致,測試對象如下:


批量隨機(jī)鍵值查詢測試  


Oracle建表語句為:


create table ctx_600m (id number(13),data varchar2(200));


數(shù)據(jù)由集算器生成同結(jié)構(gòu)的文本文件后,使用 Oracle 的 SqlLoader 導(dǎo)入表中。


Oracle建索引語句為:


create unique index idx_id_600m on ctx_600m(id);


使用 Oracle 進(jìn)行批量隨機(jī)取數(shù)測試時,我們使用這樣的 SQL:


select * from ctx_600m where id in (…)


 


使用單線程連接 Oracle 進(jìn)行查詢的集算器腳本為:



批量隨機(jī)鍵值查詢測試  


由于 oracle 的 in 個數(shù)有限制,腳本中進(jìn)行分批執(zhí)行后合并。


 


使用 10 線程連接 Oracle 進(jìn)行查詢的集算器腳本為:


批量隨機(jī)鍵值查詢測試      


 


使用單線程對行存組表進(jìn)行查詢的集算器腳本為:


批量隨機(jī)鍵值查詢測試  


 


使用 10 線程對行存組表進(jìn)行查詢的集算器腳本為:


批量隨機(jī)鍵值查詢測試      


 


從 6 億條數(shù)據(jù)總量中取 1 萬條批量隨機(jī)鍵值,在都建立索引的測試結(jié)果:


批量隨機(jī)鍵值查詢測試  


五、列存索引測試


集算器列存采用了數(shù)據(jù)分塊并壓縮的算法,這樣對于遍歷運(yùn)算來講,訪問數(shù)據(jù)量會變小,也就會具有更好的性能。但對于基于索引隨機(jī)取數(shù)的場景,由于要有額外的解壓過程,而且每次取數(shù)都會針對整個分塊,運(yùn)算復(fù)雜度會高很多。因此,從原理上分析,這時候的性能應(yīng)當(dāng)會比行存要差。


上述代碼中把生成組表的 create() 函數(shù)不用 @r 選項,即可生成列存文件。重復(fù)上面的運(yùn)算,單線程情況下 6 億行中取 1 萬行耗時為 129120 毫秒,比行存方式慢了 6 倍多。不過平均到一行也只有 13 毫秒,對于大多數(shù)單條取數(shù)的場景仍然有足夠的實(shí)用性。


同一份數(shù)據(jù)不能在遍歷運(yùn)算和隨機(jī)取數(shù)這兩方面都達(dá)到最優(yōu)性能,在實(shí)際應(yīng)用中就要根據(jù)需求做一下取舍了,一定要追求各種運(yùn)算的極限性能時,可能就要把數(shù)據(jù)冗余多份了。


六、索引冗余機(jī)制


集算器確實(shí)也提供了冗余索引機(jī)制,可以用于提高列存數(shù)據(jù)的隨機(jī)訪問性能,代碼如下:


批量隨機(jī)鍵值查詢測試  


在對組表建立索引時,當(dāng) index 函數(shù)有數(shù)據(jù)列名參數(shù),如本例 A2 中的 data,就會在建索引時把數(shù)據(jù)列 data 復(fù)制進(jìn)索引。當(dāng)有多個數(shù)據(jù)列時,可以寫為:index(id_idx;id;data1,data2,…)


因為在索引中做了冗余,索引文件也自然會較大,本文中測試的列存組表和索引冗余后的文件大小為:


批量隨機(jī)鍵值查詢測試  


當(dāng)數(shù)據(jù)復(fù)制進(jìn)索引后,實(shí)際上讀取時不再訪問原數(shù)據(jù)文件了。


從 6 億條數(shù)據(jù)總量中取 1 萬條批量隨機(jī)鍵值,完整的測試結(jié)果對比: 

批量隨機(jī)鍵值查詢測試


向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報,并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI