鐵道部新客票系統(tǒng)設(shè)計(jì)(三)
在第二篇文章里面,重點(diǎn)分析了余票庫(kù)的整體設(shè)計(jì),我看到有的評(píng)論說(shuō)了幾點(diǎn),現(xiàn)在整理一下
1 為什么要用悲觀鎖
為什么要用鎖,由于之前是做金融系統(tǒng),對(duì)數(shù)據(jù)的一致性要求很高。鐵道部的出票操作要保證數(shù)據(jù)一致性,所以必須在獲取余票的情況下鎖定余票記錄,否則會(huì)導(dǎo)致并發(fā)問(wèn)題,多出票。如果是站票還無(wú)所謂,如果是臥鋪咋辦,一個(gè)席位,兩張票。這個(gè)操作和帳戶扣款一樣,考慮下面的例子:

這里沒(méi)有鎖,導(dǎo)致多出票,這個(gè)只是兩個(gè)線程,假設(shè)有10個(gè)線程,則多出10張票
考慮有鎖的情況:

2 系統(tǒng)能否承受悲觀鎖
首先,我們需要看到什么情況下鎖,以及鎖持續(xù)時(shí)間,以及請(qǐng)求的并發(fā)數(shù)來(lái)進(jìn)行分析。大多數(shù)情況下,鐵道部購(gòu)票系統(tǒng)承受的并發(fā)量都不會(huì)太大,除了節(jié)假日,主要是國(guó)慶節(jié)和春節(jié)。及時(shí)在國(guó)慶節(jié)和春節(jié)的情況下,我們假設(shè)每秒鐘1000個(gè)請(qǐng)求去買(mǎi)座Z27的20121001的座票,那么鎖記錄持續(xù)的時(shí)間是多長(zhǎng)了
分兩種情況
a 有票:業(yè)務(wù)邏輯完成,釋放鎖
假設(shè)一般坐票有1000張,那么會(huì)有1000次鎖業(yè)務(wù)操作,假設(shè)業(yè)務(wù)持續(xù)鎖時(shí)間0.1秒(這個(gè)需要實(shí)際去進(jìn)行壓力測(cè)試),一秒鐘處理10條記錄,需要2分鐘才能消化。而且這兩分鐘內(nèi)oracle連接也被占用,后續(xù)的請(qǐng)求排隊(duì),系統(tǒng)緩慢,然后假死。這里面我們可以設(shè)置一個(gè)值,假設(shè)超過(guò)5秒,還沒(méi)有辦法獲取到鎖,自動(dòng)釋放連接,數(shù)據(jù)庫(kù)返回錯(cuò)誤,客戶端可以選擇重試查詢票數(shù)或者報(bào)錯(cuò)給客戶,當(dāng)然,這個(gè)涉及到客戶體驗(yàn),如果獲取不到鎖,基本上可以告知客戶票已經(jīng)售完。
考慮到如果余票庫(kù)有10個(gè),那么就可以分?jǐn)傄幻腌娋涂梢?00請(qǐng)求。這個(gè)具體還是,不過(guò)以上只是假設(shè),需要有實(shí)際的數(shù)據(jù)以及壓力測(cè)試要測(cè)試一下性能。
b 無(wú)票:直接釋放鎖
基本上非常快,不會(huì)占用資源。在下一個(gè)查詢周期就不會(huì)在鎖定記錄,因?yàn)橹苯釉诰彺娉鼍团懦恕?/p>
所以個(gè)人認(rèn)為使用悲觀鎖不會(huì)存在太大的問(wèn)題,只要庫(kù)設(shè)計(jì)的合理,鎖超時(shí)時(shí)間設(shè)計(jì)的合理,對(duì)請(qǐng)求進(jìn)行有限的控制,是可以支持的,當(dāng)然,這個(gè)要求實(shí)際去檢測(cè)。
3 不需要鎖,只需要一臺(tái)應(yīng)用服務(wù)器啟動(dòng)線程處理購(gòu)票,也不需要應(yīng)用集群?
那可以想象一下,所有的購(gòu)票請(qǐng)求都會(huì)同時(shí)請(qǐng)求到那一臺(tái)處理購(gòu)票的服務(wù)器上,假設(shè)這個(gè)每秒鐘處理1000請(qǐng)求(這個(gè)據(jù)我所知已經(jīng)算高了)基本上高峰期幾秒種的數(shù)據(jù)就把服務(wù)壓掛了。并且這個(gè)是單點(diǎn),一旦這一臺(tái)服務(wù)器掛了,整個(gè)系統(tǒng)癱瘓。
4 余票數(shù)據(jù)可以放在內(nèi)存中嗎?
放在內(nèi)存,也就是放在內(nèi)存緩存里面,這個(gè)問(wèn)題有以下幾個(gè)?
1 緩存故障
當(dāng)緩存出現(xiàn)故障的時(shí)候,怎么辦?當(dāng)然可以緩存集群,切換到另外一臺(tái)緩存服務(wù)器,但是余票的數(shù)據(jù)如何同步??jī)烧卟灰恢略趺崔k
2 系統(tǒng)發(fā)布
當(dāng)系統(tǒng)發(fā)布的時(shí)候怎么解決緩存中的數(shù)據(jù)庫(kù)問(wèn)題,當(dāng)然可以先把請(qǐng)求處理完成,然后在發(fā)布?;蛘甙l(fā)布之前,把緩存的數(shù)據(jù)同步到數(shù)據(jù)庫(kù)中,這樣也是可以的。但是設(shè)計(jì)上太復(fù)雜。
3 極端情況
硬件故障
操作系統(tǒng)故障
機(jī)房斷電
這些故障都會(huì)導(dǎo)致內(nèi)存數(shù)據(jù)丟失,余票數(shù)據(jù)都丟失了
我就知道我所在的公司遇到的變態(tài)的情況如下:
機(jī)房無(wú)故斷電,網(wǎng)卡故障,磁盤(pán)寫(xiě)入失敗,
經(jīng)常遇到的情況是:jvm crash,內(nèi)存泄漏,這些會(huì)導(dǎo)致放在內(nèi)存的數(shù)據(jù)比較危險(xiǎn)。
還有領(lǐng)域驅(qū)動(dòng)設(shè)計(jì)和數(shù)據(jù)庫(kù)設(shè)計(jì)兩者沒(méi)有必要聯(lián)系。領(lǐng)域驅(qū)動(dòng)是解決復(fù)雜業(yè)務(wù)領(lǐng)域的時(shí)候用的一種設(shè)計(jì)思想,自己在這方面開(kāi)發(fā)比較多,和數(shù)據(jù)庫(kù)這一層設(shè)計(jì)沒(méi)有關(guān)系
對(duì)于性能來(lái)說(shuō),當(dāng)然可以把所有的數(shù)據(jù)都放在內(nèi)存里面,這樣的處理效率***,但是內(nèi)存的數(shù)據(jù)就易丟失的數(shù)據(jù)。設(shè)計(jì)一個(gè)系統(tǒng)架構(gòu)***的問(wèn)題就是權(quán)衡利弊。對(duì)于火車(chē)票系統(tǒng),在出票的流程上,相當(dāng)于金融系統(tǒng)的轉(zhuǎn)賬,余票相當(dāng)于用戶的余額,要保證***優(yōu)先級(jí)的安全性和一致性。這個(gè)性能相比,優(yōu)先級(jí)要高。
談?wù)剬?duì)架構(gòu)的認(rèn)識(shí)
這里在說(shuō)說(shuō)談?wù)勛约簩?duì)架構(gòu)的認(rèn)識(shí)吧,架構(gòu)不是說(shuō)就只管系統(tǒng)的性能,架構(gòu)是全局觀。涉及到安全性,可用性,性能,數(shù)據(jù)一致性,可擴(kuò)展性等等。每個(gè)系統(tǒng)的應(yīng)用特點(diǎn)不一樣,所以思考的重點(diǎn)不一樣。金融類(lèi)系統(tǒng)對(duì)可用性和安全性數(shù)據(jù)一致性要求非常高,不能有任何的妥協(xié),寧可犧牲性能,這就是為什么銀行喜歡用IBM的產(chǎn)品。新浪這樣的網(wǎng)站,性能很重要,但是如果丟失的用戶少量數(shù)據(jù),無(wú)所謂,所以數(shù)據(jù)可以放在內(nèi)存里面,甚至可以用nodejs這樣的新技術(shù)來(lái)實(shí)現(xiàn)。鐵道部這樣的***系統(tǒng),可用性一定是在***位的,其次是數(shù)據(jù)一致性,然后才是性能。就扯這么多,每個(gè)人的觀點(diǎn)不一樣,但是架構(gòu)就是這么虛的東東。關(guān)系型數(shù)據(jù)庫(kù)目前證明還是最可靠的,你能想象金融類(lèi)帳務(wù)系統(tǒng)用的是NoSql這樣的對(duì)事務(wù)要求不高的數(shù)據(jù)庫(kù)嗎?所以關(guān)系型適合在購(gòu)票這樣的核心應(yīng)用。其他的庫(kù)可以用NoSql來(lái)實(shí)現(xiàn),比如會(huì)員庫(kù),沒(méi)有問(wèn)題。
渠道購(gòu)票分配
上一篇文章提到了這個(gè)渠道訂票的需求,目前有兩種方式進(jìn)行數(shù)據(jù)庫(kù)層面的設(shè)計(jì),***種是各個(gè)渠道的數(shù)據(jù)切割開(kāi),互補(bǔ)影響,也就是說(shuō)我網(wǎng)絡(luò)訂票不影響窗口售票,我想這個(gè)需求還是比較合理的,有限保證窗口票,那么可以把數(shù)據(jù)庫(kù)水平分割,按照渠道來(lái)設(shè)計(jì)

這種設(shè)計(jì)的***好處,就是各個(gè)渠道訂票完全是分割開(kāi)的,互相都不影響,但是這樣***的問(wèn)題就是事先算好每個(gè)渠道的票的配合,比如窗口100張,網(wǎng)絡(luò)20張,代售200張,電話30張。非常不靈活,比如假設(shè)我窗口還有票,但是窗口沒(méi)有人買(mǎi),怎么辦,那只能其他渠道來(lái)賣(mài)。這樣也比較浪費(fèi),畢竟大多數(shù)情況下,鐵道部的購(gòu)票還是系統(tǒng)還不是那么繁忙的。
另外一種設(shè)計(jì)就是在渠道層做流量控制,讓流量控制這一層負(fù)責(zé)票數(shù)分配

這種設(shè)計(jì)方式就是比較考驗(yàn)渠道層,渠道層需要做流量控制,這樣分配的***問(wèn)題,就是分配均勻,所以很好的算法。但是數(shù)據(jù)庫(kù)層統(tǒng)一了,可擴(kuò)展性比較強(qiáng)。容易進(jìn)行擴(kuò)容,也不會(huì)造成硬件的浪費(fèi)。
兩種設(shè)計(jì)方式體現(xiàn)的思想不一樣,各有利弊。不過(guò)從更傾向于第二種設(shè)計(jì)方式,比較靈活。而且渠道流量這一層本身就必須的,這一層可以設(shè)計(jì)的比較厚,而且可以大量使用緩存或者NoSql。
余票庫(kù)的再分析
1 余票庫(kù)的分庫(kù)策略
昨天討論余票庫(kù)分庫(kù)策略,想起和一個(gè)鐵路工程師聊起,再想想自己電話訂票的時(shí)候,可以發(fā)現(xiàn)更好的分庫(kù)方式。下面是從百度百科搜到的鐵道部的組織架構(gòu):
| 鐵路局是中國(guó)鐵路管理體制的特色產(chǎn)物,是中國(guó)鐵路四級(jí)(現(xiàn)在為三級(jí))體制的重要組成部分。中國(guó)目前有18個(gè)鐵路局(公司),分別是:哈爾濱、沈陽(yáng)、北京、呼和浩特、鄭州、濟(jì)南、上海、南昌、廣鐵集團(tuán)、柳州(2007年已搬遷至南寧)、成都、昆明、蘭州、烏魯木齊、青藏鐵路公司、太原、西安、武漢。 | 
鐵道部下面分為18個(gè)鐵路局,我估計(jì)每個(gè)鐵路局負(fù)責(zé)的車(chē)次不一樣,那么分庫(kù)就可以按照鐵路局分庫(kù),這樣就可以分為18個(gè)數(shù)據(jù)庫(kù)。但是考慮到余票庫(kù)的實(shí)際數(shù)據(jù)量并不大,只是高并發(fā),我們沒(méi)有必要分成18個(gè)庫(kù)。但是我估計(jì)由于利益分配,這個(gè)18個(gè)鐵路局應(yīng)該每個(gè)鐵路局都有自己的數(shù)據(jù)中心。但是我們這是純技術(shù)層面的分析,先不考慮利益和實(shí)際情況。我們可以按照鐵局路分庫(kù),但是前提是負(fù)責(zé)賣(mài)票的車(chē)次都不一樣,否則一個(gè)車(chē)次,分到兩個(gè)庫(kù)里面系統(tǒng)會(huì)變的很復(fù)雜。假設(shè)范圍分為四個(gè),東南西北,比如(哈爾并,沈陽(yáng),北京,呼和浩特)一個(gè)庫(kù)。這樣我們就有一個(gè)簡(jiǎn)單的模型了,那么在梳理一下一次典型的購(gòu)票數(shù)據(jù)流

其中虛線圈起來(lái)的部分是要保持?jǐn)?shù)據(jù)一致性。
簡(jiǎn)單的說(shuō)就是 余票減少一張,車(chē)票庫(kù)待支付記錄就會(huì)多一條;車(chē)票支付成功,車(chē)票狀態(tài)要變更,支付數(shù)據(jù)完成,短信要發(fā)送,當(dāng)然這個(gè)要看你對(duì)一致性要求有多高,車(chē)票購(gòu)票成功,短信發(fā)送不一定要成功。但是車(chē)票支付成功,支付數(shù)據(jù)總要有,并且是成功的吧。這個(gè)要進(jìn)行對(duì)賬的,否則就是一筆糊涂賬。據(jù)說(shuō)鐵道部還會(huì)建立會(huì)員營(yíng)銷(xiāo)系統(tǒng),那么越來(lái)越多的功能就會(huì)更復(fù)雜,比如支付成功,積分增加一百,積分以后可以進(jìn)行車(chē)票的支付等等。不過(guò)這個(gè)不是核心,如果能繼續(xù)寫(xiě),在分析吧。
至于在分布式環(huán)境下如何保持?jǐn)?shù)據(jù)一致性,這個(gè)我會(huì)專門(mén)寫(xiě)幾篇文章來(lái)進(jìn)行分析,我覺(jué)得這個(gè)是比較有價(jià)值的。
2 如何確定余票
這個(gè)是第二篇博文中我沒(méi)有寫(xiě)的,我覺(jué)得這個(gè)是最復(fù)雜的,現(xiàn)在繼續(xù)分析。
確定余票的因素:日期,車(chē)次(假設(shè)動(dòng)車(chē),普通車(chē)次不重復(fù)),出發(fā)站,到達(dá)站,席位
其他三個(gè)很容易從數(shù)據(jù)庫(kù)中獲取,這里不說(shuō)了,主要是出發(fā)站,到達(dá)站兩個(gè)維度。
如果通過(guò)其實(shí)出發(fā)站和到達(dá)站進(jìn)行查詢,首先我們根據(jù)車(chē)站確認(rèn)可以通的車(chē)次,可以簡(jiǎn)化為對(duì)N個(gè)車(chē)次查詢,在根據(jù)出發(fā)站,到達(dá)站進(jìn)行分析
假設(shè) 車(chē)次Z27,坐票,20121001,中途經(jīng)過(guò)5站(A,B,C,D,E),共有100張,簡(jiǎn)化記錄為(A->E) = 100
假設(shè)用戶U1買(mǎi)了從A->E的車(chē)票一張,那么還剩下99張, 就是 (A->E) 99
假設(shè)用戶U2買(mǎi)了從A->C,那么 (A->E) = 98 ,(A->C)=98 (C->E) = 99
假設(shè)用戶U3買(mǎi)了從C->D, 那么 (A->E) =97 ,(A->C) = 98 , (C->E) = 98 (C->D) = 98 , (D->E) 99
看來(lái)越來(lái)越復(fù)雜,但是我們發(fā)現(xiàn)這個(gè)和二叉樹(shù)有關(guān),看一下下面的圖,不斷構(gòu)造一個(gè)樹(shù)的過(guò)程,而且判斷票和也查找節(jié)點(diǎn)有關(guān),找到之后此節(jié)點(diǎn)票數(shù)-1,所有的父節(jié)點(diǎn)票數(shù)-1。我算法不好,只能想到這個(gè)算法了,不知道有沒(méi)有更好的算法,這個(gè)樹(shù)不需要實(shí)時(shí)更新,放在內(nèi)存里面。這樣就方便查詢了。

整個(gè)架構(gòu)的基本模型
把***篇和第二票文章整理的內(nèi)容在綜合整理以下,在應(yīng)用在豐富以下,可以搭建一個(gè)簡(jiǎn)單的分布式系統(tǒng)的應(yīng)用原型,透過(guò)這個(gè)原型,我們?cè)诓粩嗟耐晟葡到y(tǒng)
 
目前鐵道部可能的架構(gòu)模型
***看到鐵道部的組織架構(gòu),感覺(jué)鐵道部的系統(tǒng)架構(gòu)可能大致是這樣的:隨便亂太猜想的,下面一個(gè)簡(jiǎn)單的模型,實(shí)際情況遠(yuǎn)遠(yuǎn)比這個(gè)復(fù)雜。

由于數(shù)據(jù)中心是分布的,所以系統(tǒng)很慢。因?yàn)閿?shù)據(jù)這一層路由,都是遠(yuǎn)程調(diào)用啊。同時(shí)鐵道部的應(yīng)用應(yīng)該也是分布部署的,由于數(shù)據(jù)中心不集中,花在系統(tǒng)間通信的成本太高。感覺(jué)這個(gè)可能是鐵道部?jī)?nèi)部的政治格局導(dǎo)致的,以前的銀行都是這么搞的,每個(gè)省都有自己的一套系統(tǒng)。
后續(xù)
寫(xiě)了這么多,先休息一段時(shí)間吧,后續(xù)有時(shí)間在繼續(xù)分析這個(gè)系統(tǒng),今天也恰好看到一個(gè)新聞:
據(jù)介紹,12306互聯(lián)網(wǎng)購(gòu)票系統(tǒng)是基于中國(guó)鐵路客票發(fā)售和預(yù)訂系統(tǒng)(簡(jiǎn)稱客票系統(tǒng))這一核心系統(tǒng)構(gòu)建的。客票系統(tǒng)在10余年的運(yùn)營(yíng)過(guò)程中先后完成6次升級(jí):1.0版本實(shí)現(xiàn)了計(jì)算機(jī)售票取代人工硬板票,2.0版本實(shí)現(xiàn)了區(qū)域級(jí)聯(lián)網(wǎng),3.0版本實(shí)現(xiàn)了全國(guó)聯(lián)網(wǎng)售票,4.0版本實(shí)現(xiàn)了與清分清算系統(tǒng)的對(duì)接,5.0版本實(shí)現(xiàn)了席位復(fù)用和共用,5.2版本實(shí)現(xiàn)了實(shí)名制售票、電子客票和電子支付。
由于2.0版本是區(qū)域級(jí)別售票,3.0實(shí)現(xiàn)全國(guó)聯(lián)網(wǎng)售票,但是我估計(jì)所謂實(shí)現(xiàn)全國(guó)聯(lián)網(wǎng)售票,因?yàn)槭窃?.0的基礎(chǔ)上通過(guò)適配和路由搭建的,鐵道部應(yīng)該還沒(méi)有統(tǒng)一的數(shù)據(jù)中心,數(shù)據(jù)應(yīng)該是各個(gè)鐵路局控制的。
4.0版本主要做清分系統(tǒng),這個(gè)就是內(nèi)部的核算系統(tǒng),應(yīng)該算是鐵道部?jī)?nèi)部最為復(fù)雜的一個(gè)系統(tǒng)了,比如我賣(mài)了1000張票,應(yīng)該得多少錢(qián),應(yīng)付給代售點(diǎn)和合作商戶做多少錢(qián)。
5.0可能就是上面說(shuō)的同一個(gè)位置,由于區(qū)域段不同,可以買(mǎi)兩張以上的票,只要鐵路段不重復(fù),也就是我說(shuō)的余票樹(shù)模型。
5.2就是實(shí)名制和增加了電子支付和電子客票,這個(gè)應(yīng)該稍微簡(jiǎn)單一點(diǎn),只是增加了一種支付工具和驗(yàn)票手段。所以版本號(hào)就沒(méi)有怎么升級(jí)。
看看新的客票系統(tǒng)的愿景;
鐵道部透露,新一代客票系統(tǒng)實(shí)現(xiàn)了四方面創(chuàng)新。一是服務(wù)模式創(chuàng)新,系統(tǒng)支撐包括票務(wù)服務(wù)、旅行服務(wù)等各種延伸服務(wù)在內(nèi)的預(yù)訂業(yè)務(wù)。二是營(yíng)銷(xiāo)理念創(chuàng)新,對(duì)鐵路列車(chē)開(kāi)行、運(yùn)力調(diào)整、票價(jià)優(yōu)惠等提出合理化建議;制定鐵路客戶常旅客計(jì)劃,建立旅客積分、獎(jiǎng)勵(lì)制度。三是管理手段創(chuàng)新,滿足淡旺季不同客流特點(diǎn)下的售票組織需要。四是技術(shù)架構(gòu)創(chuàng)新,研發(fā)高性能核心交易平臺(tái)。
從業(yè)務(wù)角度來(lái)看,
1 鐵道部想建立客戶模型,目前鐵道部還沒(méi)有客戶模型,畢竟實(shí)名制剛開(kāi)始,區(qū)分優(yōu)質(zhì)客戶以及黑名單。未來(lái)可能你座的越多,可能走優(yōu)先貴賓通道上車(chē)等等
2 建立積分模型,這個(gè)主要是用來(lái)營(yíng)銷(xiāo),和航空和銀行一樣,估計(jì)就是換禮品什么的
3 技術(shù)架構(gòu)創(chuàng)新,我覺(jué)得這個(gè)是最重要的,現(xiàn)在的架構(gòu)可能因?yàn)闅v史的原因,比較弱。
4 高性能核心交易平臺(tái):這個(gè)是必須的,類(lèi)似淘寶那樣的交易平臺(tái)。從全球性來(lái)看,ebay的交易平臺(tái)比較強(qiáng)大,不過(guò)淘寶最近的交易數(shù)據(jù)不知道超過(guò)ebay沒(méi)有。這個(gè)交易平臺(tái)未來(lái)會(huì)不會(huì)開(kāi)放,也是一個(gè)想想的空間。
未來(lái)還可以想想的是,一旦鐵道部建立的會(huì)員模型,更有可能往金融上面去靠攏,建立自己的賬戶模型,推出更多的支付方式,比如預(yù)存款,聯(lián)名卡等等。鐵道部相當(dāng)于擁有最多實(shí)名制會(huì)員的公司,想象空間很大。但是前提是系統(tǒng)要做得好,別再被人罵。
原文鏈接:http://www.cnblogs.com/aigongsi/archive/2012/09/20/2694155.html
【編輯推薦】















 
 
 
 
 
 
 