王宇杰,楊文賓
在數(shù)據(jù)庫的訪問中,采用連接池技術(shù)在并發(fā)性能的處理上以及用戶時延的等待上都有很大優(yōu)勢。但通用的連接池具有效率低、缺乏監(jiān)控的缺點。本文在連接池的設(shè)計中,應(yīng)用排隊論的理論,建立了一個訪問服務(wù)模型,用以優(yōu)化連接池的服務(wù)質(zhì)量。
文中設(shè)計連接池模型具有一定的通用性,可以用在對各種數(shù)據(jù)庫的連接應(yīng)用中。
連接池在總體上包括四個部分:連接池、管理器、監(jiān)視器和配置文件。如圖1所示。
圖1 連接池模塊總體結(jié)構(gòu)
連接池是存放具體連接實例的地方,需要注意的是,每個連接池對應(yīng)著一種連接方式,比如對同一個數(shù)據(jù)庫,不同的數(shù)據(jù)庫用戶所建立的連接就要放在不同的連接池中(因為連接參數(shù)不一樣)。一個連接池中可以存放若干個連接實例。每個實例對應(yīng)一個編號和一些使用屬性,如已經(jīng)被使用的次數(shù),被創(chuàng)建的時間,上一次被使用的時間等。通過這些信息,就可以對這個實例進行管理(分配、回收和銷毀等)以及由此獲得系統(tǒng)的某些性能參數(shù)。每個連接池也設(shè)置一些參數(shù),或者用于記錄整個連接池的被使用情況,或者用來控制連接池的某些行為。連接池可以被設(shè)計成一個類,主要存放有一些有關(guān)連接池狀態(tài)的信息,也可以自主地對存儲在其內(nèi)的連接實例進行管理(生成、銷毀和維護等)。
管理器是對連接池進行管理的部分。一個管理器可以管理若干個連接池,負責每個連接池的生成和銷毀。管理器從配置文件中獲得靜態(tài)的配置信息,如:可以管理的連接池的列表,每個連接池的連接信息,每個連接池的最大連接數(shù)或總體的最大連接數(shù),建立連接時最大的等待時間等。用這些信息生成各個連接池,在系統(tǒng)停止時管理器還負責銷毀各個連接池(回收資源)。
由于各個連接池都由管理器統(tǒng)一管理,所以管理器也為應(yīng)用程序提供連接池的使用接口,所有應(yīng)用程序都通過管理器的接口來獲得合適的連接實例以及釋放(連接池回收)一個連接實例。
監(jiān)視器是一個后臺運行的守候進程(或線程),本質(zhì)上是一種對連接池進行優(yōu)化的計算程序。它以一定頻率掃描連接池的被訪問頻率和連接操作反應(yīng)速度的統(tǒng)計信息,并以此為依據(jù),計算最優(yōu)的連接池參數(shù),供連接池使用。訪問的統(tǒng)計信息反應(yīng)了用戶的訪問情況,連接操作的統(tǒng)計信息訪問了服務(wù)器的當前狀態(tài)(負荷、性能等),再通過一定的排隊論模型計算,就可以大致確定連接池適應(yīng)當前狀況的最優(yōu)狀態(tài),從而動態(tài)的對連接池進行調(diào)整,提高服務(wù)質(zhì)量(QoS)。
監(jiān)視器是與連接池相對應(yīng)的,每個連接池實例對應(yīng)一個監(jiān)視器實例,這個監(jiān)視器實例在與之對應(yīng)的連接池實例被創(chuàng)建的時候啟動,之后就不停地監(jiān)視和調(diào)整連接池實例的狀態(tài)。因為應(yīng)用程序?qū)B接池的訪問就是個排隊論的問題,所以監(jiān)視器的算法以排隊論為理論基礎(chǔ),通過建立一個合適的排隊模型進行優(yōu)化計算。
配置文件是存放連接池的靜態(tài)參數(shù)的地方,比如可管理的連接池名稱列表,每個連接池建立連接所用的用戶名,密碼,服務(wù)器地址,數(shù)據(jù)庫名稱,連接驅(qū)動程序名稱等。這些數(shù)據(jù)都是關(guān)于連接池全局的數(shù)據(jù),都是在管理器每次啟動時,一次性裝入,此后便不再對連接池產(chǎn)生任何作用。
連接池管理器有兩個主要作用:一是按照配置文件中的配置信息建立和銷毀連接池。一是按照應(yīng)用程序的要求,向相應(yīng)的連接池實例請求可用的連接實例或回收一個連接實例,即要實現(xiàn)取得和回收連接實例的接口。
連接池的設(shè)計主要有3點考慮:
1.管理器在設(shè)計上需要注意的就是它只能生成一個實例,換句話說,第一個管理器實例生成后,要能禁止第二個管理器實例的生成,保證所有的連接池統(tǒng)一管理。
2.應(yīng)用程序在請求獲釋放連接時,僅僅指出連接池的名稱,即可通過管理器提供的接口獲得或釋放一個連接實例。管理器內(nèi)部依據(jù)這個名字,向其所管理的某個連接池申請連接實例并返回給應(yīng)用程序,或者回收這個連接實例。這個過程對應(yīng)用程序透明。
3.管理器在實現(xiàn)這個接口時,還要注意多個進程(線程)使用接口時所造成的同步問題;一方面,我們希望提高程序的并行程度,即在同一時間內(nèi)允許有多個應(yīng)用訪問管理器,以此來提高系統(tǒng)的運行效率;另一方面,還要嚴格注意到并行過程中不適當?shù)拇a可能造成的混亂。所以,對管理器的設(shè)計我們力求避免實現(xiàn)繁瑣而又不甚必要的功能。
2.2.1 連接池的主要功能
(1)要能生成、維護和銷毀所管理的連接實例;
(2)要能迅速地對管理的連接實例進行檢索,返回給應(yīng)用程序(通過管理器),或從管理器回收一個連接實例;
(3)要維護各個連接實例的相關(guān)信息,以便于實現(xiàn)對連接實例和連接池的維護;
(4)要能及時地為監(jiān)視器提供有用的統(tǒng)計信息以供監(jiān)視器進行優(yōu)化計算。
2.2.2 連接池中的數(shù)據(jù)組織
在實際設(shè)計中,一個連接池主要包括如下一些重要數(shù)據(jù)組織:
(1)鏈表cons,我們把空閑的連接實例放入這個鏈表中,因為對連接實例的操作主要是取得(不需檢索)、加入和刪除等修改性操作,采用鏈表結(jié)構(gòu)最為適合。
(2)哈希表infos,我們把連接實例的相關(guān)信息放入一個哈希表中,每個連接實例的相關(guān)信息包括實例創(chuàng)建時間,實例被使用的次數(shù),實例上次被調(diào)用的時間。因為對連接實例相關(guān)信息的查詢操作比較頻繁,不同于連接實例本身,所以,把相關(guān)信息和連接實例本身分開存儲;哈希表比較適合于查詢,所以就把連接實例信息放在哈希表中。
(3)還設(shè)有兩個變量專門用于統(tǒng)計系統(tǒng)的被訪頻率和系統(tǒng)當前的反應(yīng)速度uCount和yCount,連接池會根據(jù)實際情況不斷地把一些信息計入這兩個變量,監(jiān)視器也會不斷地訪問這兩個變量,以進行優(yōu)化計算。
(4)其他比較重要的參數(shù)就是連接池內(nèi)最大的連接實例數(shù)n,連接池內(nèi)等待連接的請求隊列的最大長度(m-n),這兩個參數(shù)對連接池的性能有較大的影響,監(jiān)視器會根據(jù)計算結(jié)果不斷調(diào)整n和m的值,以期連接池的性能最優(yōu)。
此外還有一些不太重要的參數(shù),如連接實例的最大生存時間,最大使用次數(shù),最長等待時間,已經(jīng)生成的所有連接數(shù)(包括正在被使用和空閑狀態(tài)中的連接實例)等等。
2.2.3 連接池向外提供的接口
連接池主要向外提供兩個接口:獲取連接getConnection(),即是從連接池取得一個可用的連接實例;釋放連接freeConnection(),即是將一個用完的連接實例放回連接池。這兩個接口都需要調(diào)用者提供一個連接池名稱作為參數(shù)。
2.2.4 連接池的運行流程
考慮到一個連接實例在多次使用之后,或在經(jīng)過較長一段時間之后會逐漸的變得不穩(wěn)定(由于底層的原因),所以,在回收連接實例時,連接池要檢查連接實例的生成時間和使用次數(shù),當超過相應(yīng)的標準時,就把這個連接實例銷毀,同時刪除對應(yīng)的使用記錄。
一個連接池的運行流程分析如下。
(1)管理器應(yīng)應(yīng)用程序的請求,調(diào)用連接池的獲取連接接口getConnection()。連接池首先把這個請求的有關(guān)信息記錄到y(tǒng)Count中去,然后,看空閑連接鏈表cons中有沒有可用的連接實例,如果有,到哈希表infos中修改這個連接實例的相關(guān)信息,并返回這個連接實例給管理器;如果空閑鏈表已經(jīng)空了,則查看所有連接數(shù)是否達到最大值n,如果沒有達到,則生成一個新的連接實例,把相關(guān)信息計入哈希表infos,并返回這個新的連接實例給管理器;如果已經(jīng)達到最大值,則看等待隊列有沒有排滿,若沒滿,則把這個請求放入等待隊列,若已滿,返回出錯信息給管理器,報告沒有取道連接。放入等待隊列的請求也有一個最大的等待時間,如果在這個時間內(nèi),沒有獲得可用連接,則也要返回出錯信息給管理器。如果我們還要對請求失敗率進行統(tǒng)計的話,在合適的地方,還要對相關(guān)信息進行記錄。
(2)管理器應(yīng)應(yīng)用程序的請求,調(diào)用連接池的釋放連接接口freeConnection()。連接池首先從哈希表infos中取出這個連接實例的相關(guān)信息,并把相關(guān)信息記錄到uCount中去,然后檢查這個連接實例的生存時間和使用次數(shù)是否超過要求,如果已經(jīng)超過,關(guān)閉這個連接,刪除相關(guān)信息,所有連接數(shù)減1。如果沒有超過,則把這個連接實例放入空閑鏈表cons,相關(guān)信息中使用次數(shù)加1,然后通知等待隊列,已經(jīng)有空閑連接實例回收。
(3)連接池實例一旦生成,即啟動一個監(jiān)視器實例monitor,這個監(jiān)視器以后臺守護進程或線程的方式運行,經(jīng)過一段間隔,就查詢連接池中的統(tǒng)計信息yCount和uCount,并進行一次優(yōu)化計算,并根據(jù)計算結(jié)果,調(diào)整連接池中的m和n值。在銷毀連接池之前,要停止監(jiān)視器最后銷毀掉。
連接池的運行流程如圖2所示,實際上包括兩個獨立的過程:
(a)應(yīng)用程序向連接池申請一個連接的過程;
(b)應(yīng)用程序向連接池釋放一個連接的過程;
圖2 連接池處理流程
2.3.1 監(jiān)視器算法
監(jiān)視器的作用就在于,按照一定的指標,通過模型計算,得到合適的連接池參數(shù)。優(yōu)化的目標主要有兩個:一個是盡量提高系統(tǒng)的通過能力,即是要使絕對通過量保持不低于某一個值(與系統(tǒng)能力有關(guān));一個是盡量減小對每個用戶的服務(wù)時間,不能讓用戶等待的太久。
這兩個指標在有些時候是矛盾的,假設(shè)系統(tǒng)資源已經(jīng)達到極限,為了提高系統(tǒng)通過率,可以增加每個連接池內(nèi)的連接數(shù),使更多到達的請求不被馬上拒絕,但這樣肯定會增大整個系統(tǒng)的開銷,使得等待隊列中的請求等待的時間延長。反之,如果想讓每個以獲得連接的用戶花費時間短,就不能在連接池內(nèi)創(chuàng)建太多的連接,以節(jié)省系統(tǒng)資源,從而降低了系統(tǒng)的通過率。
所以,必須分情況采用不同的優(yōu)化策略,權(quán)衡兩個因素,以期達到最佳效果。在平均的請求速度低于平均的響應(yīng)速度時,說明系統(tǒng)是可以勝任當前任務(wù)的,所以應(yīng)該盡量保證系統(tǒng)通過率,適當?shù)卦黾舆B接實例以及加長等待隊列的長度,使一些局部密集到達的請求不至于被馬上拒絕掉。在平均的請求速度高于平均的響應(yīng)速度時,說明系統(tǒng)是已經(jīng)不可以勝任當前任務(wù)了,一些請求被拒絕是必然的,這時,就應(yīng)該保證每個用戶的響應(yīng)時間,在此基礎(chǔ)上,盡量提高系統(tǒng)通過量,所以就要限制連接池內(nèi)連接實例數(shù)目和等待隊列的長度,適當拒絕對某些申請的響應(yīng)。
從而得到如下的優(yōu)化算法:
Λ:為單位時間內(nèi)平均到達的請求數(shù)量;
μ:為單位時間內(nèi)每個連接實例所能處理的請求數(shù);
n:為連接池內(nèi)所有的連接實例數(shù)目;
m:等待隊列長度;
timeout:用戶最大等待時間;
(1)使用當前的λ、μ、m和n值,比較nμ和λ,如果nμ>λ說明系統(tǒng)目前設(shè)置基本上能夠勝任當前任務(wù),僅僅需要微調(diào),進入第二步計算。
(2)計算用戶等待時間,如果計算結(jié)果已經(jīng)大于timeout,則適當增加m值重復(fù)計算,但m值不要大于2n,如果在某一個時刻,計算結(jié)果小于timeout了,計算完成,本輪計算結(jié)束。當增加到m=2n時,若還沒有使計算結(jié)果小于timeout,此時m值的增加對計算結(jié)果的影響已經(jīng)很小,說明不能靠調(diào)整m值來縮短響應(yīng)時間了,轉(zhuǎn)入第四步。如果計算結(jié)果小于timeout,轉(zhuǎn)入第三步。
(3)減小m值,值到計算的等待時間剛好小于timeout,本輪計算完成。如果一直到m=n尚不能使等待時間剛好小于timeout,轉(zhuǎn)入第四步。
(4)n值減1,本輪計算完成,等待下一輪計算。
(5)使用當前的λ、μ、m和n值,比較nμ和λ,如果nμ<λ說明系統(tǒng)目前設(shè)置不能夠勝任當前任務(wù),需要大的調(diào)整,轉(zhuǎn)入第六步。
(6)檢查以前記錄的μ和n值,其乘積與當前值乘積進行比較,如果當前值較大且n+1值有效,說明系統(tǒng)尚有空余利用空間,記錄下當前μ和n值存儲起來,n值加1,本輪計算完成,等待下一輪計算。如果當前值較小,轉(zhuǎn)入第七步計算。如果n+1值無效,同樣轉(zhuǎn)入第七步計算進行微調(diào)。
(7)此時系統(tǒng)資源的利用到達極限,且還不能滿足當前任務(wù),使一部分的用戶請求被拒絕已經(jīng)無法避免,所能做的就是保證連接用戶的等待時間在規(guī)定的等待時間內(nèi),同時,盡可能提高系統(tǒng)通過率。計算方法是計算等待時間是否小于規(guī)定時間,如果是,逐步增加m值,直到一個臨界值(并且m<2n),如果不是,逐步減小m值,直到一個臨界值;如果一直到m=n尚不能滿足要求,說明通過調(diào)整等待隊列長度不能完成用戶等待時間的調(diào)整,從而轉(zhuǎn)入第八步計算。
(8)做一個標記,表示當前n值無效,n值減1,進入下一輪計算。
優(yōu)化算法的流程可參考圖3,其中的具體算法參考排隊論理論。
圖3 監(jiān)視器算法流程圖
可以看出,因為n值的調(diào)整會對系統(tǒng)有較大的影響,所以一般n值變化后要等到下一輪實測結(jié)果出來再做進一步?jīng)Q定(此時的實測結(jié)果可能會較現(xiàn)狀有較大的變化),調(diào)整周期要長;而m值的調(diào)整對系統(tǒng)影響較小,可以用過迭代計算在一輪內(nèi)算得出,調(diào)整周期要短的多。調(diào)整n值時伴隨著連接實例的建立和銷毀,是個很費資源的工作,但m值的調(diào)整則沒有這么大的影響,而且m值的調(diào)整也能在小范圍內(nèi)對系統(tǒng)指標產(chǎn)生影響,所以在一定程度上避免了由于任務(wù)變化劇烈所帶來n值的頻繁變化,為n值的調(diào)整起到了一定的緩沖作用,實際上,也就是在一定程度上避免了系統(tǒng)頻繁生成和銷毀連接實例所出現(xiàn)的“顛簸”現(xiàn)象。
由于排隊論計算中,算法比較繁瑣,不好由要求的指標變量反求得到輸入變量,所以,在計算中采用了所謂“愿望模型”的試算方法,即逐次給出不同的輸入變量得到不同的指標變量,再依據(jù)得到的指標變量,從中選擇一個合適的輸入作為計算結(jié)果。對m和n值的計算本質(zhì)上都是這樣的。
2.3.2 優(yōu)化計算時用到的主要公式及其推導(dǎo)過程(已知n,m,μ,λ的值)
(1)計算系統(tǒng)損失率:
(2)系統(tǒng)絕對通過能力:A=λ*Pm
(3)平均服務(wù)時間:
由:
本文設(shè)計了一種通用的連接池技術(shù),包括連接池、管理器、監(jiān)視器和配置文件等幾部份,并在監(jiān)視器的設(shè)計上,結(jié)合排隊論理論,建立了一個訪問服務(wù)模型,用以優(yōu)化連接池的服務(wù)質(zhì)量,以期達到更好的訪問性能。該設(shè)計已經(jīng)在多個系統(tǒng)中應(yīng)用,其中包括北京交通大學(xué)管理信息系統(tǒng)。運行穩(wěn)定,訪問效率高。
[1]黃汛,程治剛,數(shù)據(jù)庫連接池技術(shù)的應(yīng)用研究,武漢大學(xué)學(xué)報(工學(xué)版),第35期第一期,2002年2月.
[2]陸傳賚,排隊論[M].北京郵電學(xué)院出版社,1994.
[3]陸鳳山,排隊論及其應(yīng)用[M].湖南科學(xué)技術(shù)出版社,1984.
[4]孟玉珂,排隊論基礎(chǔ)及應(yīng)用[M].同濟大學(xué)出版社,1989.
[5]華興,排隊論與隨機服務(wù)系統(tǒng)[M].上海翻譯出版公司,1987.
[6]劉瓊波,施軍,尤晉元,分布式環(huán)境下的訪問控制[M].《計算機研究與發(fā)展》,第38卷第6期,2001年6月.
[7]Sun Microsystems,Inc.JavaTM2 SDK,Standard Edition Documentation,Version 1.4.1 September 26,2002.
[8]Bruce Eckel.Java編程思想[M].京京工作室譯,機械工業(yè)出版社,1999.4.