俞席忠
摘要: 該文分析兩個(gè)網(wǎng)絡(luò)癱瘓事件,說明數(shù)據(jù)庫并發(fā)控制對系統(tǒng)的運(yùn)行效率起著至關(guān)重要的作用,對樂觀鎖和悲觀鎖進(jìn)行分析,說明高并發(fā)網(wǎng)絡(luò)環(huán)境下,數(shù)據(jù)庫并發(fā)控制的選擇。
關(guān)鍵詞: 數(shù)據(jù)庫; 并發(fā)控制; 樂觀鎖 ; 悲觀鎖
中圖分類號:TP391文獻(xiàn)標(biāo)識碼:A文章編號:1009-3044(2012)30-7172-03
第一個(gè)網(wǎng)絡(luò)事件:小米手機(jī)網(wǎng)站第二輪開放購買時(shí),網(wǎng)站癱瘓。
2012年1月4日消息 1月4日中午1點(diǎn),小米手機(jī)第二輪開放購買。在開放購買后一個(gè)小時(shí)內(nèi),小米官方網(wǎng)站由于同時(shí)段訪問人數(shù)過多出現(xiàn)宕機(jī)。對此,小米科技CEO雷軍對于服務(wù)器無法負(fù)擔(dān)訪問人數(shù)過多,出現(xiàn)官網(wǎng)宕機(jī)事件表示歉意。雷軍表示,“這次開放購買,服務(wù)器沒有抗住,實(shí)在對不起各位!懇請各位諒解!”。
另一個(gè)網(wǎng)絡(luò)事件:由于訪問量過大,鐵路售票網(wǎng)癱瘓.
2012年1月1日起,鐵路部門開始調(diào)整售票時(shí)間,網(wǎng)絡(luò)售票、電話訂票、代售點(diǎn)、車站窗口等進(jìn)行錯(cuò)時(shí)放售車票。但由于訪問量過大,不少旅客在12306網(wǎng)購車票時(shí),頻頻遭遇“系統(tǒng)忙”而無法訪問。相比之下,電話訂票比網(wǎng)購車票要更順利些。記者親歷:折騰一個(gè)多小時(shí)訂單沒提交上。目前,網(wǎng)上購買火車票唯一官方網(wǎng)站就是鐵道部下屬的中國鐵路客戶服務(wù)中心網(wǎng)(www.12306.cn)。
什么原因?qū)е戮W(wǎng)站癱瘓,是前端接口、是帶寬、是網(wǎng)絡(luò)架構(gòu),還是數(shù)據(jù)庫并發(fā)出了問題。2012年初的這兩個(gè)網(wǎng)絡(luò)事件,引發(fā)了廣大技術(shù)人員和專家的大討論。本文將從數(shù)據(jù)庫并發(fā)控制這個(gè)層面來研究網(wǎng)絡(luò)效率與并發(fā)控制間的關(guān)系及它們間的優(yōu)化處理。
1 網(wǎng)站癱瘓?jiān)蚍治?/p>
小米網(wǎng)站平時(shí)的訪問量不大,由于手機(jī)采用網(wǎng)上直銷模式,使瞬時(shí)每分鐘的并發(fā)量沖高導(dǎo)致服務(wù)DOWN機(jī),小米手機(jī)運(yùn)營經(jīng)理鐘雨菲貼出小米網(wǎng)站的數(shù)據(jù)解釋:“給大家貼一個(gè)cnzz后臺數(shù)據(jù):15分鐘內(nèi),小米官網(wǎng),不含論壇,同時(shí)在線24萬多人。做過網(wǎng)站運(yùn)營的朋友都知道,這么多人同時(shí)在線對服務(wù)器的壓力還是很大的”。
整體來說負(fù)載均衡的問題不大,問題根本不在前端服務(wù)器,前端都有良好的綬沖機(jī)制,加上只有讀數(shù)據(jù),沒有寫的操作。真正的原因集中在后端數(shù)據(jù)庫并發(fā)跟不上來,因?yàn)橐粋€(gè)用戶要定購一臺手機(jī),首先要讀(作一次selecet操作)庫存表中剩余多少臺這個(gè)字段,判斷自已能否下單,若還有剩余,則向定購表中作一次插入操作(instert),最后向庫存表更新剩余數(shù)(作一次update操作),可見數(shù)據(jù)庫并發(fā)量過大,加上沒作好并發(fā)控制的優(yōu)化,是導(dǎo)致網(wǎng)站癱瘓的主要原因。主要是準(zhǔn)備不足,前期沒有作數(shù)據(jù)庫并發(fā)壓力測試一下,沒有根據(jù)估計(jì)在線數(shù)設(shè)置一下限流,在相同的硬件條件下,通過數(shù)據(jù)庫的并發(fā)控制優(yōu)化和流量控制等軟件的手段可以綬解并發(fā)數(shù)過多造成的網(wǎng)站響應(yīng)慢的難題。小米公司在這個(gè)事件之后,對后臺數(shù)據(jù)庫的進(jìn)行了徹底的優(yōu)化并作了一些限流的措施,在2012年4月6日,在6分鐘時(shí)間成功完成了10萬臺定購量。
2012年前7天,鐵道部客戶服務(wù)官方網(wǎng)站12306網(wǎng)日均點(diǎn)擊次數(shù)已經(jīng)超過了10億次。眾多專業(yè)人士認(rèn)為,12306網(wǎng)站在線售票功能,其實(shí)就是個(gè)海量事務(wù)高速處理系統(tǒng),這樣一個(gè)系統(tǒng),并不能簡單地使用通用方案進(jìn)行設(shè)計(jì),但12306網(wǎng)站很可能是采用了Oracle通用數(shù)據(jù)庫進(jìn)行搭建,使用通用系統(tǒng)進(jìn)行設(shè)計(jì),在面對春運(yùn)前夕的瞬間海量網(wǎng)絡(luò)購票需求時(shí),這個(gè)系統(tǒng)就變得極為脆弱。業(yè)內(nèi)人士認(rèn)為,問題不出在硬件上,而出在軟件設(shè)計(jì)上。鐵道部方面試圖通過服務(wù)器的堆積,來解決軟件設(shè)計(jì)的不足,但顯然再強(qiáng)大的硬件也很難滿足一個(gè)不完善的軟件系統(tǒng)的極端處理請求。據(jù)悉,12306網(wǎng)目前正在進(jìn)行后臺調(diào)試,新一代客票系統(tǒng)將在既有客票系統(tǒng)的基礎(chǔ)之上,提供全方位的信息咨詢、豐富的售票渠道、多元化的支付方式、快捷的進(jìn)出站,為鐵路企業(yè)提供精細(xì)化的售票管理、智能化的售票組織、科學(xué)化的運(yùn)力調(diào)配,并引入云計(jì)算技術(shù),構(gòu)建支撐超大規(guī)模并發(fā)交易。是否能真正解決,這要到2013年春運(yùn)才看得出來,讓我們試目以待吧。
從以上分析可以看出,數(shù)據(jù)庫并發(fā)控制對系統(tǒng)的運(yùn)行效率起著至關(guān)重要的地位。
2 數(shù)據(jù)庫并發(fā)控制基本原理
數(shù)據(jù)庫的并發(fā)控制能力是指在處理多個(gè)用戶在同一時(shí)間內(nèi)對相同數(shù)據(jù)同時(shí)進(jìn)行訪問的能力。一般的關(guān)系型數(shù)據(jù)庫都具備這種能力,日常應(yīng)用系統(tǒng)中也隨處可見,例如火車的售票系統(tǒng)、銀行數(shù)據(jù)庫系統(tǒng)。
數(shù)據(jù)庫并發(fā)處理時(shí),常出現(xiàn)的問題有:
1)更新丟失:當(dāng)多個(gè)事務(wù)同一條記錄進(jìn)新更新時(shí),由于每個(gè)事務(wù)間沒有通訊,事務(wù)間相對獨(dú)立,就會(huì)產(chǎn)生更新丟失現(xiàn)象,例如A事務(wù)更新了一條記錄的某個(gè)字段的值,接著B事務(wù)更新了此字段的值,此時(shí)A事務(wù)更新的值丟失。
2)臟讀:一個(gè)事務(wù)正在修改記錄數(shù)據(jù),此時(shí)尚未提交,另一個(gè)事務(wù)讀取了這些未提交的修改的記錄數(shù)據(jù),形成臟讀。這里所指的修改記錄,除了更新(Update)操作,還包括插入(Insert)和刪除(Delete)記錄操作。臟讀的結(jié)果是:如果后面一個(gè)事務(wù)做回滾操作時(shí),那么后一事務(wù)所做的修改內(nèi)容,全部都會(huì)被撤銷。這樣前面一個(gè)事務(wù)讀到的數(shù)據(jù),就是臟數(shù)據(jù)。
下面舉一個(gè)實(shí)例:在賓館房間預(yù)訂系統(tǒng)中。設(shè)計(jì)有一個(gè)預(yù)訂表,向表中插入一條記錄時(shí),表示預(yù)訂出了一個(gè)房間。
事務(wù)A:向預(yù)訂表中插入一條記錄,預(yù)訂第20號房間。
事務(wù)B:執(zhí)行查詢未預(yù)定的房間命令,事務(wù)A已預(yù)訂20號房間。所以20號房不會(huì)在空房列表中。
事務(wù)A:使用信用卡支付預(yù)訂金,由于網(wǎng)絡(luò)或其它原因,支付失敗,導(dǎo)致事務(wù)回滾。插入到預(yù)訂表中的預(yù)訂記錄被刪除。事實(shí)上20號房間是空房。此時(shí),事務(wù)B所得到空房列表,是不準(zhǔn)確的。
3)不可重復(fù)讀:在同一個(gè)事務(wù)中,重復(fù)讀取數(shù)據(jù)時(shí)多次查詢(select)操作時(shí),所讀取的數(shù)據(jù),和前次讀取的數(shù)據(jù)不一致,是不可重復(fù)讀。例如新生報(bào)名系統(tǒng),在編班時(shí),新班人數(shù)是變化的數(shù)據(jù),執(zhí)行同一查詢事務(wù)沒有變化,得到的新班人數(shù)是不一樣的。由于操作對象發(fā)生變化,而導(dǎo)致同一事務(wù)執(zhí)行結(jié)果不一致,稱為不可重復(fù)讀。
4)幻讀:事務(wù)A查詢指定的條件的記錄,之后別一事務(wù)B插入一條新記錄,這條新記錄滿足事務(wù)A使用的查詢條件。事務(wù)A再次使用相同的查詢讀取記錄,此時(shí)可以查詢到事務(wù)A剛插入的記錄。這條記錄被稱為幻象,事務(wù)A查詢操作,稱之為幻讀,因?qū)κ聞?wù)A來說,這條的新出現(xiàn)的記錄是件奇怪的事,象是幻覺一樣。
舉個(gè)例子來說明,在火車的售票系統(tǒng)中,有這樣一個(gè)過程。
售票點(diǎn)通過網(wǎng)絡(luò)從源數(shù)據(jù)庫讀出某車次的車票剩余張數(shù)為n(=100)。
B售票點(diǎn)通過網(wǎng)絡(luò)從源數(shù)據(jù)庫讀出該車次的車票剩余張數(shù)也為n(=100)。
A售票點(diǎn)賣出一張?jiān)撥嚧蔚能嚻?,?(99)寫回源數(shù)據(jù)庫。
B售票點(diǎn)也賣出一張?jiān)撥嚧蔚能嚻保瑢?(99)寫回源數(shù)據(jù)庫。
這樣就存在并發(fā)控制的問題,賣出了兩張票,而數(shù)據(jù)庫里面只有1條數(shù)據(jù)減少。這樣,下次讀取數(shù)據(jù)的時(shí)候,源數(shù)據(jù)就不準(zhǔn)確了,從而會(huì)帶來數(shù)據(jù)的錯(cuò)誤。如果按照上面的操作順序執(zhí)行,A對源數(shù)據(jù)庫的修改就被丟失。并發(fā)控制帶來數(shù)據(jù)的不一致問題,被稱為“數(shù)據(jù)庫并發(fā)控制過程沖突”,在實(shí)際的測試過程中,我們必須對這樣的沖突進(jìn)行測試設(shè)計(jì)。我們主要是通過邏輯判定來設(shè)計(jì)測試用例。
剛才的例子就是一個(gè)典型。當(dāng)事務(wù)A和B對同一個(gè)數(shù)據(jù)源進(jìn)行修改,B提交的結(jié)果破壞了A提交的結(jié)果,導(dǎo)致A對數(shù)據(jù)庫的修改失效。
不可重復(fù)讀數(shù)據(jù)是指事務(wù)A在讀取數(shù)據(jù)后,事務(wù)B對其進(jìn)行了修改并執(zhí)行了更新操作,當(dāng)事務(wù)A無法再現(xiàn)前一次讀取的結(jié)果。舉個(gè)例子來說明:
事務(wù)A從數(shù)據(jù)庫表中讀出整數(shù)x=10,Y=20值進(jìn)行求和運(yùn)算z=x+Y=30。
事務(wù)B從相同的數(shù)據(jù)庫中讀出x值x=10,對x乘以5后寫入原x值(x=X*5=50),提交事務(wù)B。
此時(shí),事務(wù)A處理的結(jié)果是:z=x+Y=10-50<0,事務(wù)B對數(shù)據(jù)的操作已經(jīng)影響了原來的結(jié)果。當(dāng)多個(gè)事務(wù)在數(shù)據(jù)庫中并發(fā)執(zhí)行時(shí),數(shù)據(jù)的一致性可能受到破壞。系統(tǒng)有必要控制各事務(wù)之間的相互作用,這是通過并發(fā)控制機(jī)制的多種機(jī)制中的一種來實(shí)現(xiàn)的。
避免事務(wù)“餓死”,授權(quán)加鎖的條件:不存在在數(shù)據(jù)項(xiàng)Q上持有與M型鎖沖突的鎖的其他事務(wù);不存在等待對數(shù)據(jù)項(xiàng)Q加鎖且先于Ti申請加鎖的事務(wù)。
常用的機(jī)制是各種封鎖協(xié)議,時(shí)間戳排序,有效性檢查,多版本機(jī)制。
數(shù)據(jù)封鎖是需要時(shí)間開銷的,對于訪問量巨大的鐵路客票系統(tǒng)和在線搶購等并發(fā)性要求極高的場合下,即可保證數(shù)據(jù)正確,又要得到最佳的并發(fā)效率,是值得研究的問題。
3 網(wǎng)絡(luò)數(shù)據(jù)庫在并發(fā)控制中的選擇
對于互連網(wǎng),數(shù)據(jù)庫屬于共享資源的一個(gè)重要組成部分,眾多使用者可以同時(shí)使用數(shù)據(jù)庫提供的各種數(shù)據(jù)服務(wù)。為了保證數(shù)據(jù)的一致性,早期的數(shù)據(jù)庫系統(tǒng),要求用戶程序進(jìn)行排隊(duì),即每一時(shí)刻只允許一個(gè)用戶程序?qū)?shù)據(jù)庫做存取操作,其他用戶程序等待上一用戶程序完成操作后,才能對數(shù)據(jù)庫進(jìn)行存取。數(shù)據(jù)庫服務(wù)器的輸出能力實(shí)際上是較強(qiáng)大的,面對一個(gè)用戶的數(shù)據(jù)處理,數(shù)據(jù)庫絕大多數(shù)的時(shí)間是處于閑置狀態(tài),別一方面,眾多用戶的數(shù)據(jù)請求已得到不到響應(yīng),要解決這一矛盾,現(xiàn)代數(shù)據(jù)庫管理系統(tǒng)必須提供并發(fā)控制機(jī)制。并發(fā)控制機(jī)制的好壞是將關(guān)系到大型網(wǎng)絡(luò)平臺的數(shù)據(jù)吞吐能力,直接影響到網(wǎng)站的用戶體驗(yàn)。
目前大型數(shù)據(jù)庫系統(tǒng)的并發(fā)控制,主要是通過鎖定的方式。不同的加鎖方式用于不同的應(yīng)用場合。根據(jù)業(yè)務(wù)邏輯關(guān)系,我們需要保證數(shù)據(jù)訪問的排他性。通過一些并發(fā)機(jī)制保證數(shù)據(jù)在某個(gè)特定操作過程中不會(huì)被其它用戶程序所修改,這就是所謂的“加鎖”,目標(biāo)數(shù)據(jù)鎖定時(shí),使其無法被其他用戶程序修改。 目前常用兩種加鎖機(jī)制為:悲觀鎖(Pessimistic Locking)和樂觀鎖(Optimistic Locking)。
悲觀鎖認(rèn)為你正在更新的記錄,會(huì)被其它用戶讀取或更改的概率很高,因此當(dāng)你的進(jìn)程需要更改記錄數(shù)據(jù)時(shí),先進(jìn)行鎖定,禁止其它用戶程序讀取或更改,當(dāng)你的進(jìn)程完成更新后,解除鎖定,其它用戶程序才能正常讀寫。在一些實(shí)際應(yīng)用程序中,例如生產(chǎn)管理系統(tǒng),如果并發(fā)量不大,完全可以使用悲觀鎖定的方法,這種方法使用起來非常方便和簡單。悲觀鎖很好的解決了數(shù)據(jù)讀寫的正確性,并由于加鎖時(shí)間較長,使得并發(fā)性變差,在訪問量很大時(shí),用戶體驗(yàn)將會(huì)是災(zāi)難性的。在系統(tǒng)的并發(fā)非常大的情況下,悲觀鎖定會(huì)帶來非常大的性能問題,所以就要選擇樂觀鎖定的方法。
樂觀鎖與悲觀鎖相反,樂觀的認(rèn)為對同一數(shù)據(jù)同時(shí)存取的概率極小,因而在數(shù)據(jù)庫層次上的不加鎖定機(jī)制,為了保證數(shù)據(jù)的正確性,樂觀鎖定采用在應(yīng)用程序設(shè)計(jì)時(shí),考慮在邏輯進(jìn)行數(shù)據(jù)進(jìn)行保護(hù)。在樂觀鎖機(jī)制中,增加了并發(fā)用戶次數(shù),大大提高了數(shù)據(jù)庫的效率。
在高并發(fā)的環(huán)境下,使用多臺電腦做均衡負(fù)載,但是數(shù)據(jù)庫放在一臺電腦上,那如何是這些并發(fā)保持?jǐn)?shù)據(jù)都是統(tǒng)一的, 比如在用一時(shí)間,A用戶調(diào)用1號設(shè)備修改記錄,而A用戶也在2號設(shè)備同樣需要修改記錄 ,現(xiàn)在的思路是在數(shù)據(jù)庫電腦上做異步鎖,所用的數(shù)據(jù)操作都會(huì)調(diào)用到這個(gè)鎖,這個(gè)鎖就是以用戶的用戶名來定義。
4 結(jié)束語
本文從數(shù)據(jù)庫并發(fā)控制角度分析了大型網(wǎng)絡(luò)平臺在高負(fù)荷環(huán)境時(shí)鎖定機(jī)制對網(wǎng)絡(luò)效率的影響,提出解決數(shù)據(jù)一致性和高并發(fā)讀寫效率的思路。并發(fā)控制的方法非常豐富,遠(yuǎn)不止本文所提及的這些方法。在網(wǎng)絡(luò)數(shù)據(jù)庫應(yīng)用中,并發(fā)控制的方法和實(shí)現(xiàn)途徑多種多樣。在選擇時(shí)所依據(jù)的基本原則就是:數(shù)據(jù)一致性一定要合乎應(yīng)用的需要,在此基礎(chǔ)上,盡量提高并發(fā)度。
參考文獻(xiàn):
[1] 劉云生,郭芬,廖國瓊.安全的樂觀實(shí)時(shí)并發(fā)控制策略[J]. 微計(jì)算機(jī)應(yīng)用,2006(4).
[2] 陳月峰.淺析數(shù)據(jù)庫并發(fā)控制技術(shù)[J].科技信息,2009,(30).
[3] 戴志龍.淺談高級數(shù)據(jù)庫并發(fā)控制方法[J].科技經(jīng)濟(jì)市場,2010,(4) .
[4] 雷霖,熊偉,吳燁,景寧.基于語義的數(shù)據(jù)庫并發(fā)控制研究進(jìn)展[J].小型微型計(jì)算機(jī)系統(tǒng),2011(12).