由12306.cn談談網站性能技術

業務

任何技術都離不開業務需求,因此,要說明性能問題,首先仍是想先說說業務問題。css

  • 其一有人可能把這個東西和QQ或是網遊相比。但我以爲這二者是不同的,網遊和QQ在線或是登陸時訪問的更多的是用戶本身的數據,而訂票系統訪問的是中心的票量數據,這是不同的。不要以爲網遊或是QQ能行你就覺得這是同樣的。網遊和QQ 的後端負載相對於電子商務的系統仍是簡單。
  • 其二有人說春節期間訂火車的這個事好像網站的秒殺活動。的確很類似,可是若是你的思考不在表面的話,你會發現這也有些不同。火車票這個事,還有不少查詢操做,查時間,查座位,查鋪位,一個車次不 行,又查另外一個車次,其伴隨着大量的查詢操做,下單的時候須要對數據庫操做。而秒殺,直接殺就行了。另外,關於秒殺,徹底能夠作成只接受前N個用戶的請求(徹底不操做後端的任何數據, 僅僅只是對用戶的下單操做log),這種業務,只要把各個服務器的時間精確同步了就能夠了,無需在當時操做任何數據庫。能夠訂單數夠後,中止秒殺,而後批量寫數據庫。火車票這個豈止是秒殺那麼簡單。能不能買到票得當時告訴用戶啊。
  • 其三有人拿這個系統和奧運會的票務系統比較。我以爲仍是不同。雖然奧運會的票務系統當年也一上線就廢了。可是奧運會用的是抽獎的方式,也就是說不存在先來先得的搶的方式,並且,是過後抽獎,事前只須要收信息,事前不須要保證數據一致性,沒有鎖,很容易水平擴展。
  • 其四訂票系統應該和電子商務的訂單系統很類似,都是須要對庫存進行:1)佔住庫存,2)支付(可選),3)扣除庫存的操做。這個是須要有一致性的檢查的,也就是在併發時須要對數據加鎖的。B2C的電商基本上都會把這個事幹成異步的,也就是說,你下的訂單並非立刻處理的,而是延時處理的,只有成功處理了,系統纔會給你一封確認郵件說是訂單成功。我相信有不少朋友都收到認單不成功的郵件。這就是說,數據一致性在併發下是一個瓶頸

 

  • 其五鐵路的票務業務很變態,其採用的是忽然放票,而有的票又遠遠不夠你們分,因此,你們纔會有搶票這種有中國特點的業務的作法。因而當票放出來的時候,就會有幾百萬人甚至上千萬人殺上去,查詢,下單。幾十分鐘內,一個網站能接受幾千萬的訪問量,這個是很恐怖的事情。聽說12306的高峯訪問是10億PV,集中在早8點到10點,每秒PV在高峯時上千萬。

多說幾句:html

  • 庫存是B2C的惡夢,庫存管理至關的複雜。不信,你能夠問問全部傳統和電務零售業的企業,看看他們管理庫存是多麼難的一件事。否則,就不會有那麼多人在問凡客的庫存問題了。(你還能夠看看《喬布斯傳》,你就知道爲何Tim會接任Apple的CEO了,由於他搞定了蘋果的庫存問題)
  • 對於一個網站來講,瀏覽網頁的高負載很容易搞定,查詢的負載有必定的難度去處理,不過仍是能夠經過緩存查詢結果來搞定,最難的就是下單的負載。由於要訪問庫存啊,對於下單,基本上是用異步來搞定的。去年雙11節,淘寶的每小時的訂單數大約在60萬左右,京東一天也才能支持40萬(竟然比12306還差),亞馬遜5年前一小時可支持70萬訂單量。可見,下訂單的操做並無咱們相像的那麼性能高。
  • 淘寶要比B2C的網站要簡單得多,由於沒有倉庫,因此,不存在像B2C這樣有N個倉庫對同一商品庫存更新和查詢的操做。下單的時候,B2C的 網站要去找一個倉庫,又要離用戶近,又要有庫存,這須要不少計算。試想,你在北京買了一本書,北京的倉庫沒貨了,就要從周邊的倉庫調,那就要去看看瀋陽或 是西安的倉庫有沒有貨,若是沒有,又得看看江蘇的倉庫,等等。淘寶的就沒有那麼多事了,每一個商戶有本身的庫存,庫存分到商戶頭上了,反而有利於性能。
  • 數據一致性纔是真正的性能瓶頸。有 人說nginx能夠搞定每秒10萬的靜態請求,我不懷疑。但這只是靜態請求,理論值,只要帶寬、I/O夠強,服務器計算能力夠,並支持的併發鏈接數頂得住10萬TCP連接的創建 的話,那沒有問題。但在數據一致性面前,這10萬就完徹底全成了一個可望不可及的理論值了。

我說那麼多,我只是想從業務上告訴你們,咱們須要從業務上真正瞭解春運鐵路訂票這樣業務的變態之處。前端

前端性能優化技術

要解決性能的問題,有不少種經常使用的方法,我在下面列舉一下,我相信12306這個網站使用下面的這些技術會讓其性能有質的飛躍。nginx

1、前端負載均衡程序員

經過DNS的負載均衡器(通常在路由器上根據路由的負載重定向)能夠把用戶的訪問均勻地分散在多個Web服務器上。這樣能夠減小Web服務器的請求負載。由於http的請求都是短做業,因此,能夠經過很簡單的負載均衡器來完成這一功能。最好是有CDN網絡讓用戶鏈接與其最近的服務器(CDN一般伴隨着分佈式存儲)。(關於負載均衡更爲詳細的說明見「後端的負載均衡」)ajax

2、減小前端連接數redis

我看了一下12306.cn,打開主頁須要建60多個HTTP鏈接,車票預訂頁面則有70多個HTTP請求,如今的瀏覽器都是併發請求的。因此,只要有100萬個用戶,就會有6000萬個連接,太多了。一個登陸查詢頁面就行了。把js打成一個文件,把css也打成一個文件,把圖標也打成一個文件,用css分塊展現。把連接數減到最低。算法

3、減小網頁大小增長帶寬數據庫

這個世界不是哪一個公司都敢作圖片服務的,由於圖片太耗帶寬了。如今寬帶時代很難有人能體會到當撥號時代作個圖頁都不敢用圖片的情形(如今在手機端瀏覽也是這個情形)。我查看了一下12306首頁的須要下載的總文件大小大約在900KB左右,若是你訪問過了,瀏覽器會幫你緩存不少,只需下載10K左右的文件。可是咱們能夠想像一個極端一點的案例,1百萬用戶同時訪問,且都是第一次訪問,每人下載量須要1M,若是須要在120秒內返回,那麼就須要,1M * 1M /120 * 8 = 66Gbps的帶寬。很驚人吧。因此,我估計在當天,12306的阻塞基本上應該是網絡帶寬,因此,你可能看到的是沒有響應。後面隨着瀏覽器的緩存幫助12306減小不少帶寬佔用,因而負載一下就到了後端,後端的數據處理瓶頸一下就出來。因而你會看到不少http 500之類的錯誤。這說明服務器垮了。後端

4、前端頁面靜態化

靜態化一些不覺變的頁面和數據,並gzip一下。還有一個並態的方法是把這些靜態頁面放在/dev/shm下,這個目錄就是內存,直接從內存中把文件讀出來返回,這樣能夠減小昂貴的磁盤I/O。

5、優化查詢

不少人查詢都是在查同樣的,徹底能夠用反向代理合並這些併發的相同的查詢。這樣的技術主要用查詢結果緩存來實現,第一次查詢走數據庫得到數據,並把數據放到緩存,後面的查詢通通直接訪問高速緩存。爲每一個查詢作Hash,使用NoSQL的技術能夠完成這個優化。(這個技術也能夠用作靜態頁面)

對於火車票量的查詢,我的以爲不要顯示數字,就顯示一個「有」或「無」就行了,這樣能夠大大簡化系統複雜度,並提高性能。

6、緩存的問題

緩存能夠用來緩存動態頁面,也能夠用來緩存查詢的數據。緩存一般有那麼幾個問題:

1)緩存的更新。也叫緩存和數據庫的同步。有這麼幾種方法,一是緩存time out,讓緩存失效,重查,二是,由後端通知更新,一量後端發生變化,通知前端更新。前者實現起來比較簡單,但實時性不高,後者實現起來比較複雜 ,但實時性高。

2)緩存的換頁。內存可能不夠,因此,須要把一些不活躍的數據換出內存,這個和操做系統的內存換頁和交換內存很類似。FIFO、LRU、LFU都是比較經典的換頁算法。相關內容參看Wikipeida的緩存算法

3)緩存的重建和持久化。緩存在內存,系統總要維護,因此,緩存就會丟失,若是緩存沒了,就須要重建,若是數據量很大,緩存重建的過程會很慢,這會影響生產環境,因此,緩存的持久化也是須要考慮的。

諸多強大的NoSQL都很好支持了上述三大緩存的問題。

後端性能優化技術

前面討論了前端性能的優化技術,因而前端可能就不是瓶頸問題了。那麼性能問題就會到後端數據上來了。下面說幾個後端常見的性能優化技術。

1、數據冗餘

關於數據冗餘,也就是說,把咱們的數據庫的數據冗餘處理,也就是減小錶鏈接這樣的開銷比較大的操做,但這樣會犧牲數據的一致性。風險比較大。不少人把NoSQL用作數據,快是快了,由於數據冗餘了,但這對數據一致性有大的風險。這須要根據不一樣的業務進行分析和處理。(注意:用關係型數據庫很容易移植到NoSQL上,可是反過來從NoSQL到關係型就難了)

2、數據鏡像

幾乎全部主流的數據庫都支持鏡像,也就是replication。數據庫的鏡像帶來的好處就是能夠作負載均衡。把一臺數據庫的負載均分到多臺上,同時又保證了數據一致性(Oracle的SCN)。最重要的是,這樣還能夠有高可用性,一臺廢了,還有另外一臺在服務。

數據鏡像的數據一致性多是個複雜的問題,因此咱們要在單條數據上進行數據分區,也就是說,把一個暢銷商品的庫存均分到不一樣的服務器上,如,一個暢銷商品有1萬的庫存,咱們能夠設置10臺服務器,每臺服務器上有1000個庫存,這就好像B2C的倉庫同樣。

3、數據分區

數據鏡像不能解決的一個問題就是數據表裏的記錄太多,致使數據庫操做太慢。因此,把數據分區。數據分區有不少種作法,通常來講有下面這幾種:

1)把數據把某種邏輯來分類。好比火車票的訂票系統能夠按各鐵路局來分,可按各類車型分,能夠按始發站分,能夠按目的地分……,反正就是把一張表拆成多張有同樣的字段可是不一樣種類的表,這樣,這些表就能夠存在不一樣的機器上以達到分擔負載的目的。

2)把數據按字段分,也就是堅着分表。好比把一些不常常改的數據放在一個表裏,常常改的數據放在另外多個表裏。把一張表變成1對1的關係,這樣,你能夠減小表的字段個數,一樣能夠提高必定的性能。另外,字段多會形成一條記錄的存儲會被放到不一樣的頁表裏,這對於讀寫性能都有問題。但這樣一來會有不少複雜的控制。

3)平均分表。由於第一種方法是並不必定平均分均,可能某個種類的數據仍是不少。因此,也有采用平均分配的方式,經過主鍵ID的範圍來分表。

4)同一數據分區。這個在上面數據鏡像提過。也就是把同一商品的庫存值分到不一樣的服務器上,好比有10000個庫存,能夠分到10臺服務器上,一臺上有1000個庫存。而後負載均衡。

這三種分區都有好有壞。最經常使用的仍是第一種。數據一旦分區,你就須要有一個或是多個調度來讓你的前端程序知道去哪裏找數據。把火車票的數據分區,並放在各個省市,會對12306這個系統有很是有意義的質的性能的提升

4、後端系統負載均衡

前面說了數據分區,數據分區能夠在必定程度上減輕負載,可是沒法減輕熱銷商品的負載,對於火車票來講,能夠認爲是大城市的某些主幹線上的車票。這就須要使用數據鏡像來減輕負載。使用數據鏡像,你必然要使用負載均衡,在後端,咱們可能很難使用像路由器上的負載均衡器,由於那是均衡流量的,由於流量並不表明服務器的繁忙程度。所以,咱們須要一個任務分配系統,其還能監控各個服務器的負載狀況。

任務分配服務器有一些難點:

  • 負載狀況比較複雜。什麼叫忙?是CPU高?仍是磁盤I/O高?仍是內存使用高?仍是併發高?仍是內存換頁率高?你可能須要所有都要考慮。這些信息要發送給那個任務分配器上,由任務分配器挑選一臺負載最輕的服務器來處理。
  • 任務分配服務器上須要對任務隊列,不能丟任務啊,因此還須要持久化。而且能夠以批量的方式把任務分配給計算服務器。
  • 任務分配服務器死了怎麼辦?這裏須要一些如Live-Standby或是failover等高可用性的技術。咱們還須要注意那些持久化了的任務的隊列如何轉移到別的服務器上的問題。

我看到有不少系統都用靜態的方式來分配,有的用hash,有的就簡單地輪流分析。這些都不夠好,一個是不能完美地負載均衡,另外一個靜態的方法的致命缺陷是,若是有一臺計算服務器死機了,或是咱們須要加入新的服務器,對於咱們的分配器來講,都須要知道的。

還有一種方法是使用搶佔式的方式進行負載均衡,由下游的計算服務器去任務服務器上拿任務。讓這些計算服務器本身決定本身是否要任務。這樣的好處是能夠簡化系統的複雜度,並且還能夠任意實時地減小或增長計算服務器。可是惟一很差的就是,若是有一些任務只能在某種服務器上處理,這可能會引入一些複雜度。不過整體來講,這種方法多是比較好的負載均衡。

5、異步、 throttle 和 批量處理

異步、throttle(節流閥) 和批量處理都須要對併發請求數作隊列處理的。

  • 異步在業務上通常來講就是收集請求,而後延時處理。在技術上就是能夠把各個處理程序作成並行的,也就能夠水平擴展了。可是異步的技術問題大概有這些,a)被調用方的結果返回,會涉及進程線程間通訊的問題。b)若是程序須要回滾,回滾會有點複雜。c)異步一般都會伴隨多線程多進程,併發的控制也相對麻煩一些。d)不少異步系統都用消息機制,消息的丟失和亂序也會是比較複雜的問題。
  • throttle 技術其實並不提高性能,這個技術主要是防止系統被超過本身不能處理的流量給搞垮了,這實際上是個保護機制。使用throttle技術通常來講是對於一些本身沒法控制的系統,好比,和你網站對接的銀行系統。
  • 批量處理的技術,是把一堆基本相同的請求批量處理。好比,你們同時購買同一個商品,沒有必要你買一個我就寫一次數據庫,徹底能夠收集到必定數量的請求,一次操做。這個技術能夠用做不少方面。好比節省網絡帶寬,咱們都知道網絡上的MTU(最大傳輸單元),以態網是1500字節,光纖能夠達到4000多個字節,若是你的一個網絡包沒有放滿這個MTU,那就是在浪費網絡帶寬,由於網卡的驅動程序只有一塊一塊地讀效率纔會高。所以,網絡發包時,咱們須要收集到足夠多的信息後再作網絡I/O,這也是一種批量處理的方式。批量處理的敵人是流量低,因此,批量處理的系統通常都會設置上兩個閥值,一個是做業量,另外一個是timeout,只要有一個條件知足,就會開始提交處理。

因此,只要是異步,通常都會有throttle機制,通常都會有隊列來排隊,有隊列,就會有持久化,而系統通常都會使用批量的方式來處理

雲風同窗設計的「排隊系統」 就是這個技術。這和電子商務的訂單系統很類似,就是說,個人系統收到了你的購票下單請求,可是我尚未真正處理,個人系統會跟據我本身的處理能力來throttle住這些大量的請求,並一點一點地處理。一旦處理完成,我就能夠發郵件或短信告訴用戶你來能夠真正購票了。

在這裏,我想經過業務和用戶需求方面討論一下雲風同窗的這個排隊系統,由於其從技術上看似解決了這個問題,可是從業務和用戶需求上來講可能仍是有一些值得咱們去深刻思考的地方:

1)隊列的DoS攻擊。首先,咱們思考一下,這個隊是個單純地排隊的嗎?這樣作還不夠好,由於這樣咱們不能杜絕黃牛,並且單純的ticket_id很容易發生DoS攻擊,好比,我發起N個 ticket_id,進入購票流程後,我不買,我就耗你半個小時,很容易我就可讓想買票的人幾天都買不到票。有人說,用戶應該要用身份證來排隊, 這樣在購買裏就必須要用這個身份證來買,但這也還不能杜絕黃牛排隊或是號販子。由於他們能夠註冊N個賬號來排隊,但就是不買。黃牛這些人這個時候只須要幹一個事,把網站搞得正常人不能訪問,讓用戶只能經過他們來買。

2)對列的一致性?對這個隊列的操做是否是須要鎖?只要有鎖,性能必定上不去。試想,100萬我的同時要求你來分配位置號,這個隊列將會成爲性能瓶頸。你必定沒有數據庫實現得性能好,因此,可能比如今還差

3)隊列的等待時間。購票時間半小時夠不夠?多很少?要是那時用戶正好不能上網呢?若是時間短了,用戶不夠時間操做也會抱怨,若是時間長了,後面在排隊的那些人也會抱怨。這個方法可能在實際操做上會有不少問題。另外,半個小時太長了,這徹底不現實,咱們用15分鐘來舉例:有1千萬用戶,每個時刻只能放進去1萬個,這1萬個用戶須要15分鐘完成全部操做,那麼,這1千萬用戶所有處理完,須要1000*15m = 250小時,10天半,火車早開了。(我並不是亂說,根據鐵道部專家的說明:這幾天,平均一天下單100萬,因此,處理1000萬的用戶須要十天。這個計算可能有點簡單了,我只是想說,在這樣低負載的系統下用排隊可能都不能解決問題

4)隊列的分佈式。這個排隊系統只有一個隊列好嗎?還不足夠好。由於,若是你放進去的能夠購票的人若是在買同一個車次的一樣的類型的票(好比某動車臥鋪),仍是等於在搶票,也就是說系統的負載仍是會有可能集中到其中某臺服務器上。所以,最好的方法是根據用戶的需求——提供出發地和目的地,來對用戶進行排隊。而這樣一來,隊列也就能夠是多個,只要是多個隊列,就能夠水平擴展了。

我以爲徹底能夠向網上購物學習。在排隊(下單)的時候,收集好用戶的信息和想要買的票,並容許用戶設置購票的優先級,好比,A車次臥鋪買 不到就買 B車次的臥鋪,若是還買不到就買硬座等等,而後用戶把所需的錢先充值好,接下來就是系統徹底自動地異步處理訂單。成功不成功都發短信或郵件通知用戶。這樣,系統不只能夠省去那半個小時的用戶交互時間,自動化加快處理,還能夠合併相同購票請求的人,進行批處理(減小數據庫的操做次數)。這種方法最妙的事是能夠知道這些排隊用戶的需求,不但能夠優化用戶的隊列,把用戶分佈到不一樣的隊列,還能夠像亞馬遜的心願單同樣,讓鐵道部作車次統籌安排和調整(最後,排隊系統(下單系統)仍是要保存在數據庫裏的或作持久化,不能只放在內存中,否則機器一down,就等着被罵吧)。

小結

寫了那麼多,我小結一下:

0)不管你怎麼設計,你的系統必定要能容易地水平擴展。也就是說,你的整個數據流中,全部的環節都要可以水平擴展。這樣,當你的系統有性能問題時,「加3倍的服務器」纔不會被人譏笑。

1)上述的技術不是一朝一夕能搞定的,沒有長期的積累,基本無望。咱們能夠看到,不管你用哪一種都會引起一些複雜性。

2)集中式的賣票很難搞定,使用上述的技術可讓訂票系統能有幾佰倍的性能提高。而在各個省市建分站,分開賣票,是能讓現有系統性能有質的提高的最好方法

3)春運前夕搶票且票量供遠小於求這種業務模式是至關變態的,讓幾千萬甚至上億的人在某個早晨的8點鐘同時登陸同時搶票的這種業務模式是變態中的變態。業務形態的變態決定了不管他們怎麼辦幹必定會被罵。

4)爲了那麼一兩個星期而搞那麼大的系統,而其它時間都在閒着,有些惋惜了,這也就是鐵路才幹得出來這樣的事了。

評論區:

  • 某隻

    2012年1月16日08:43 | #1

    讀完以爲學到了很多東西,服務器優化也好,買票的心態也好

  • Zind

    2012年1月16日08:50 | #2

    雲風的「排隊系統」,連接 404 了

  • jimmy

    2012年1月16日08:52 | #3

    拜讀了

  • rensn

    2012年1月16日08:57 | #4

    訂票其實還有一個特色:各車次的分管鐵路局是固定的!若是按鐵路局將系統分割,負載將大大分散。就如10086.cn同樣,他會要求你先輸入手機號後跳轉到各個分公司的系統。

  • Astar

    2012年1月16日08:59 | #5

    /system-analysis/20120116/317409.html

  • WRW

    2012年1月16日09:00 | #6

    很全面的分析,學習了。

  • imzrh

    2012年1月16日09:11 | #7

    好文章,讓沒有機會接觸大型網絡設計的我瞭解了很多東西。

    「數據鏡像的數據一致性多是個問題,因此咱們要吧在單條數據上進行數據分區」
    感受這句不是很好讀啊。而且」吧「是個錯字吧。

  • haitao

    2012年1月16日09:15 | #8

    沒提到把「選線路和支付徹底分開」,昨天鐵道部本身也認可應該這麼作。。。。。。。
    http://blog.csdn.net/sz_haitao/article/details/7174037

    另外,12306好像沒有鎖票的機制,因此出現大量的已支付卻沒買到票

    • 陳皓

      2012年1月16日09:31 | #9

      你沒有仔細看個人文章。我提到過的。在排隊那一節。

  • biglazy

    2012年1月16日09:25 | #10

    「網遊和QQ在線或是登陸時訪問的更多的是用戶本身的數據」,非遊戲從業者,不過感受遊戲裏某些公共事件都是在讀寫公共資源,有時候規模也不小呢;不過副本技術確實極大的縮小了這個規模。

  • 墮落天使

    2012年1月16日09:32 | #11

    空話。。。基本都是空話。。。

  • Terry Sun

    2012年1月16日09:32 | #12

    最後一句說的好. 真是苦了不能也不會上網的農民工兄弟了

  • Dem

    2012年1月16日09:39 | #13

    「如,一個暢銷商品有1萬的庫存,咱們能夠設置10臺服務器,每臺服務器上有100個庫存,這就好像B2C的倉庫同樣。」應該是1000個庫存吧,少了個0

  • liuxiaori

    2012年1月16日09:41 | #14

    信息量很足啊。文中提到能夠使用緩存,好比如今12306是10分鐘更新一次,緩存每10分鐘都會失效,刷新緩存帶來的峯值要怎麼處理?

  • laneovcc

    2012年1月16日09:45 | #15

    用排隊+配額申請制,
    一句話update轉換成insert操做, 非要說像的話, 這像個廣告系統

  • forrest

    2012年1月16日09:54 | #16

    鐵道部的放票模式不作更改,運力不提高,單靠優化網站仍是被罵。
    假設鐵道部有能力優化,那麼能夠預見,在很短的時間內,票就被賣出去了,沒有買到票的人就會罵鐵道部,票都被黃牛買了。

  • raymond

    2012年1月16日09:54 | #17

    星期一一大早就受教了,謝謝

  • buzzlight

    2012年1月16日09:55 | #18

    我以爲須要注意一點火車票和電子商務的不一樣,車次是有限的,不像淘寶這樣商品無限多,並且業務邏輯簡單得多。這樣能夠很容易的按照車次分區,每一個車次是單獨的隊列,甚至徹底能夠放在內存,不一樣車次間不存在鎖的問題,即便同車次也能夠優化鎖粒度。另外,查詢結果不必可刻意要求和實際票務狀況同步一致,能夠偏差一秒鐘,查車次和查餘票分開,這樣90%的查詢時能夠緩存的。假設車票在開票10分鐘內就被搶完, 根據每列車的座位數和每一個座位被賣的次數,能夠估算每一個車次,每秒要處理幾個請求,實際也沒幾個。

    另外不一樣於電子商務的庫存,每一個座位能夠被賣幾回,用位運算實現很簡單。

    人們之因此用外掛刷票,由於網站爛,登錄難,下單難,付款難等等,若是訂票過程流暢,外掛天然就沒人用了,再加上簡單可靠的防刷新和限流措施,應付如今的量沒問題,鐵道部的數據不可信,看他們說他們處理的是世界頂尖的難題就知道。

  • 絕望生魚片

    2012年1月16日09:56 | #19

    一個次車。。一臺服務器。。。

  • 大麥頭

    2012年1月16日09:57 | #20

    「1)佔住庫存,2)支付(可選),3)扣除庫存的操做。」 請問博主您認爲12306的訂票環節,佔住庫存這個操做發生在哪一個步驟?

    • 陳皓

      2012年1月16日10:01 | #21

      發生在你update數據庫的時候。票量=票量-1的時候。

  • aaa

    2012年1月16日10:10 | #22

    技術方面不懂,不過我認爲對於12306網站的庫存管理,和普通B2C的電商庫存管理,有不少不同的地方
    1. 春運期間,運力不足,訂單始終大於庫存,但庫存是固定的,即車票的最大限額。
    2.閒暇時間,訂單小於庫存,但車次固定,座位固定,庫存也是固定的,即使是一個乘客,也會開一班列車
    鐵道部幾乎不用考慮訂單和庫存之間的供求關係,普通電商過於看重庫存管理,是由於懼怕庫存積壓過多,直接影響到企業資金鍊的運行,而這個問題對於鐵道部根本不存在,鐵道部只要考慮怎麼把固定的車票數量快速,流暢,均勻的分發到每位乘客手裏就OK了。

    並且我感受,這麼多年應付春運的經驗,鐵道部對於減輕售票壓力的方案也會很成熟的,不過確定都沒有用在這個網站上面上。

  • haitao

    2012年1月16日10:12 | #23

    @buzzlight

    由於無票了,用戶不甘心,反覆刷——訪問壓力大10倍
    由於網頁慢、死,因此用戶不停的刷——訪問壓力大100倍
    這是惡性循環:越是慢,訪問量越大

    若是,網頁流暢了,哪怕仍是無票,就不存在這99倍的刷新了,而只是10倍的刷新
    這是良性循環:越是快,訪問量反而少了

  • bengxia

    2012年1月16日10:15 | #24

    帶寬、CPU、存儲都不是緊缺資源,一切的根源在於票太少人太多。一到春運運量能翻好幾倍,運力只能提高一倍還不到。更好的系統是必須的,可是買不到票仍是捱罵。
    一個能夠考慮的辦法是:限制300千米之內的短程票,分流到公路客運去,這樣能夠緩解一點點壓力。
    最好能依據統計分析來肯定:最小的瓶頸在哪。
    但是,鐵老大基本上是無視的,他們認爲丫屁民老百姓就該受罪。

  • soxunyi

    2012年1月16日10:18 | #25

    查詢和下單等操做用到的數據,應該是從鐵道部客票系統已有的數據接口來直接獲取數據。12306.cn和客票系統共享之前的老數據庫。老舊的系統,必然適應不了如今的春運的變態需求。文中談及的數據庫優化的技術,目前來講12306.cn無能爲力。

  • 大麥頭

    2012年1月16日10:23 | #26

    陳皓 :
    發生在你update數據庫的時候。票量=票量-1的時候。

    那麼是否是隱含這個意思:針對某個車次有一條數據庫記錄用於登記剩餘的車票,致使訂購某車次的全部訂單都要等待鎖定這條記錄而且更新?若是是這麼設計的,確實有點那啥。通常來講一個車次的票量有限,徹底能夠用一個in memory的test-and-set(reduce)的操做來進行控制,熱門車次的票量很快就會下降到零,後面的訂單都test不過去,能夠直接拒絕了。

    • 陳皓

      2012年1月16日10:27 | #27

      併發下的數據一致性。放在內存裏也同樣要上鎖作互斥。數據庫本身原本也有緩存技術,其也是放在內存裏的。

  • aqssxlzc

    2012年1月16日10:29 | #28

    我以爲不少人沒用過這個網站就來發表意見,這個網站雖然反覆的提示用戶太多稍後再試,但是絕對沒有說掛掉或者慢的狀況。只要登錄進去,訂單成功提交,後續過程基本沒有頁面慢死的狀況。估計他是直接從請求中抽取一部分人登錄來控制在線用戶數量,而後再提交的訂單中抽出一部分進入付款來控制售票速度。

  • 大麥頭

    2012年1月16日10:33 | #29

    陳皓 :
    併發下的數據一致性。放在內存裏也同樣要上鎖作互斥。數據庫本身原本也有緩存技術,其也是放在內存裏的。

    (1)數據庫鎖不可怕,大量訂單都要鎖定同一資源纔可怕
    (2)用數據庫的鎖來作票量更新和統計,帶上事務就要慢好幾拍;若是這個票量更新要和每筆訂單的事務合併提交,那就更要慢上N倍。

  • kino

    2012年1月16日10:36 | #30

    咱們都知道,鐵道部不能知足全部人的要求,因此這樣一個系統如何實現相對公平性,特別是此次對於電腦操做不會或較弱的人就不公平。
    好比若是系統採用了排隊系統後,不從技術角度考慮, 我這裏還有幾個問題想不通。

    1. 何時開始排隊,由於你們知道票是上午十點或下午三點出票。
    這個隊伍是一直存在,從系統運行時起。仍是天天從新排。
    若是天天從新排,在重排的那一刻,還在系統裏的人如何理?我想這裏大部分人是踢出來,否則重排就沒意義了。
    若是隊伍一直存在,進入的人是能夠永遠在裏面,仍是有策略的踢出來。這裏 永遠在裏面應該不可能。
    若是有策略的踢出來,好比過一小時踢出來,那若是我要買的票在三點出票,我會想我要在兩點多一點進入系統,
    而買票的人應該都是這種想法,那我應該何時開始排隊,才能保證我能在兩點多一點進入系統,天哪,感受這個無解,絕望!

    2. 假如隊伍會在天天清空並在天天三點開始排隊,但在排隊的那一刻起,領到的號靠前的條件是什麼?
    應該是手速和網速。若是這樣的話,咱們能夠看看排在隊伍前面的是些什麼人:
    程序刷的, 遊戲高手, IT重業人員, 都市白領, 普通受過教育接觸計算機的人 文化低(對應操做計算機的能力)的外來務工人員。
    程序刷能夠禁,但效果如何就不清楚了。

    若是是這樣的話,與現有系統比,不一樣之處就在於
    現有系統在人們試了無數次後,給人絕望
    而排隊後,一開始就給人絕望,你的號碼是1000000,在你的前面還有999999人等待處理。

    對於一個具體的會操做電腦的普通人而言:
    現有系統:試了無數次,網頁崩潰無數次,拼盡了耐心,終於買到了一張票。
    排隊系統: 放棄吧,你在這買不到票

    若是開始排隊算做比賽的話,那就是職業運動員和業餘運動員的
    固然,我絕對不是在說現有的系統好!我只是在說咱們全部的技術都做好了,仍是不能從業務角度實現它的合理公平性。
    沒事,瞎想的!

  • 鋼盅郭子

    2012年1月16日10:36 | #31

    把公款吃喝的錢省下來,夠作 N 次春運訂票模擬測試了,也就不難發現問題並解決了

  • wwwwwww

    2012年1月16日10:40 | #32

    「那麼,這1千萬用戶所有處理完,須要1000*15m = 250小時,10天半,火車早開了。」
    之前都是人工排隊的時候, 春運又是如何處理過來的? 難道會是由於排隊來不及, 而火車開着空車走的嗎?
    實際上, 我認爲, 只須要把排隊搬到網上來, 多開些窗口, 並使用一些防止黃牛刷隊列的技術(這個方法能夠有不少), 網絡定票系統就夠了, 其它都是多想.

  • aqssxlzc

    2012年1月16日10:42 | #33

    @kino
    因此我以爲正確的方法實際上是抽獎,在全部請求中抽獎,中獎的登錄入系統,在全部訂單請求中抽獎,中獎的進入支付。這樣比排隊系統公平不少,每一個訂單都有中獎的機會。

  • wwwwwww

    2012年1月16日10:47 | #34

    雲風的方案可靠就表如今把現實中的購火車票排隊系統經過網絡來實現, 效率確定要比現實排隊高多了.
    先排到隊, 而後再查詢, 再買票…總體火車購票系統的需求不就是這樣嗎?
    另外, 負載小, 壓力小, 實現簡單靠譜.

    • 陳皓

      2012年1月16日10:54 | #35

      不必定啊。只要不分站,不分佈式,全局排隊估計還不如現實中的排隊。

  • wwwwwww

    2012年1月16日11:02 | #36

    你想的太複雜了, 典型的程序員思惟, 現實中的排隊怎麼會比網絡隊列高效呢? 就像雲風說的, 排到隊的, 每一個隊列的後臺用人工一對一服務都處理的過來…
    @陳皓

  • invalid

    2012年1月16日11:10 | #37

    aqssxlzc :
    我以爲不少人沒用過這個網站就來發表意見,這個網站雖然反覆的提示用戶太多稍後再試,但是絕對沒有說掛掉或者慢的狀況。只要登錄進去,訂單成功提交,後續過程基本沒有頁面慢死的狀況。估計他是直接從請求中抽取一部分人登錄來控制在線用戶數量,而後再提交的訂單中抽出一部分進入付款來控制售票速度。

    也就是說……他們已經用了雲風那種系統了,只是具體細節可能稍微不一樣。

  • cc

    2012年1月16日11:18 | #38

    「集中式的賣票很難搞定,使用上述的技術可讓訂票系統能有幾佰倍的性能提高。而在各個省市建分站,分開賣票,是能讓現有系統性能有質的提高的最好方法。」
    顯然是忽悠不懂技術的,

  • cc

    2012年1月16日11:22 | #39

    文章中一堆」可能「,技術對比不夠深刻,B2C,亞馬遜,淘寶,QQ和網遊。看標籤雲就能知道是研究啥的

    • 陳皓

      2012年1月16日11:30 | #40

      @cc 期待你也寫一篇。

  • M Jwo

    2012年1月16日11:28 | #41

    我認爲鐵道部的必定都知道上文的全部東西,由於我這樣通常的人就知道了,也都會放進去考慮,個人系統正好是跨舊系統查詢與追求效能,與鐵道部需求很像,固然流量差不少。
    我想主要的問題應該是當初估計尖峯流量是一億,最後來了十億,第二是後端系統承受不住,或是交換資料的部份承受不住,由於後端系統是內網舊系統,新舊系統溝通還要兼顧效能會有極大挑戰,就算通常採用異步MQ等方式,可是量那麼大可能也是吃不完,總不能下單後十小時纔給結果。
    不過這篇文章很值得想開發大系統的人去思考一下,我想仍是要通過這些問題的洗禮後天然就會了,我就是這樣系統搞掛幾回, PM下臺幾個就會了,反正怎麼換也不會換掉技術人員。鐵道部的人下次出來應該也都很強了,沒有通過這些問題真的死過的,也沒人會要你去設計這類的系統。

  • watchdb

    2012年1月16日11:32 | #42

    寫的很是好,偶有空逐個瞭解下你寫的每個技術,值得學習,致敬!!!

  • ivan

    2012年1月16日11:38 | #43

    網絡購票跟大學的選課系統是否是差很少

  • ethan

    2012年1月16日11:40 | #44

    我看到的幾點以下:
    第一,從訪問結果來看12306.cn已經使用了CDN網絡,提供商名字忘記了,能夠查出來
    第二,從訪問動態頁面的結果看,12306.cn用的應該是ngnix+Jboss
    第三,12306.cn和奧運訂票系統同樣由太極集團製做
    第四,從訪問結果看CDN基本上沒出什麼問題,每次500都是由Jboss返回的。我的理解,是jboss掛了

  • joylnwang

    2012年1月16日11:44 | #45

    分析的很全面,學習了。

  • M Jwo

    2012年1月16日11:46 | #46

    @M Jwo
    補充,那麼多人用hibernate的甚至EJB,這樣的系統這類O/RM的個人經驗是擋不住的,仍是直接弄memcache/Coherence, 資料庫用 partition table等比較穩

  • abadcafe

    2012年1月16日12:05 | #47

    樓主最後提出的方案,技術上是最好的,但政治上有風險…

    想一想看, 鐵道部已經被說成」最大的黃牛」多少年了, 若是搞成這種訂單延遲處理的方式, 確定會被說成」黑幕」放票…

  • 七劍下廚房

    2012年1月16日12:05 | #48

    大麥頭 :

    陳皓 :
    併發下的數據一致性。放在內存裏也同樣要上鎖作互斥。數據庫本身原本也有緩存技術,其也是放在內存裏的。

    (1)數據庫鎖不可怕,大量訂單都要鎖定同一資源纔可怕
    (2)用數據庫的鎖來作票量更新和統計,帶上事務就要慢好幾拍;若是這個票量更新要和每筆訂單的事務合併提交,那就更要慢上N倍。

    前兩天翻了一下你們的評價,如今最大的瓶頸是 提交訂單很是慢,很是困難,其次是支付接口常常出問題;登陸和查詢不是那麼緊。
    提交訂單瓶頸的緣由我估計是,鐵路內部採用了網絡支付限制,大約是1萬張(忘記從哪裏看到的),可是可能同時就是n多人同時搶票,這樣,客觀形成了一個排隊效應;排在後面的人還要等前面的人去支付,再去更新數據庫,把事務加到裏面了,那是至關慢。
    解決問題的首要一步是肯定這個系統達到什麼效果,鐵道部定時發票的節奏是不可能改變的,那套數據庫也是不可能改變的,支付銀行你也是沒辦法去改變的。僧多粥少,刷票也是不可避免的,你也不可能作到人人上去就能買到票。這個系統建設的目的就是,用戶能快速登陸,查詢,若是有票可以很快買到,或者很快被告知不被買到,並且可以避免黃牛。那麼,這個系統就是成功的。
    反過來看看,如今的網站呢?用戶沒法感知是否成功,明明看了有票就是提交不上,提交上了半天不響應,而後說不讓你買了,好不容易買了交了錢了,支付那邊又超時了。
    因此說,我對12306的想法是:
    1.找個好的產品經理,像用戶看到票有而後就是提交不上去,一點其餘可供感知的東西都沒有,這種設計水平我就不說了;
    2.優化網絡流程,例如能夠把網絡支付作到網站裏,或者徹底是異步支付;網絡放票,能夠作成按片不定時放,上午放上海,下午放杭州,隨機放票,避免形成過多的併發;
    3.再就是作好負載均衡,共享數據信息之類。其實我以爲查詢之類的能夠用阿里雲之類的來搞定啊,春運期間,搞定核心數據流程就OK了。

  • buzlight

    2012年1月16日12:09 | #49

    按車次作服務分區不必定每一個車次建一個數據庫,memory或者redis均可以,座位號是key,每一個座位用bit集合標示某一站有沒有賣。利用redis的原子操做,比數據庫簡單並且高效 @絕望生魚片

  • Fenng

    2012年1月16日12:22 | #50

    1. Tim會接任Apple的CEO了,由於他搞定了蘋果的庫存問題
    這個徹底是兩回事.

    2.集中在早8點到10點,每秒PV在高峯時上千萬
    這個數字有問題

    3.去年雙11節,淘寶的每小時的訂單數大約在60萬左右
    錯,淘寶峯值是278萬筆/小時

    4. 淘寶要比B2C的網站要簡單得多,由於沒有倉庫 
    這個是臆測。複雜度同樣的。

    5. 數據鏡像
    至少對於Oracle來講,目前沒法作到有效的鏡像,鏡像更可能是爲了數據安全可靠

    6. 數據一致性纔是真正的性能瓶頸
    數據一致性並不是業務難題,併發能力支撐纔是難題

    • 陳皓

      2012年1月16日13:11 | #51

      1)我讀的是喬布斯傳裏的說法。
      2)關於峯值,願聞其詳。
      3)峯值278萬沒有問題,我仍是說,淘寶的系統比較簡單,由於沒有他庫。不過淘寶當時已經在極限上了,準備關一些省市流量了。
      4)看來你不知倉庫的壓力。複雜度徹底不同。這點你外行了。
      5)數據鏡像有便可以保持負載也但是爲了高可用性。
      6)數據一致性是很耗性能的,併發的的難點是操做那些共享的數據,這你應該知道啊。

      謝謝你的回覆,不過沒有看到你的思考哦。呵呵。

  • sarstime

    2012年1月16日12:31 | #52

    琢磨着這兩天博主就會討論這個熱點問題,結果今天就看到了。 還有一部分業務是關於退票和改簽的, 能夠搞一個退票,改簽票的提醒機制,好比註冊到一個排隊隊列,若是有退,改簽的票出來,就能夠發個短信提醒隊列裏的人。

  • pooch

    2012年1月16日12:36 | #53

    「而在各個省市建分站,分開賣票,是能讓現有系統性能有質的提高的最好方法。」

    能詳細說說這個數據切分方案嗎?我的感受按省市很難分啊,由於火車是途徑各省市的,不是各省市固定票額啊。
    好比一趟北京始發,西安終點的車,若是在北京賣出了一張北京到鄭州的某座位車票,那麼這個座位接下來只能從鄭州以西開始賣了,因此在鄭州買票的時候,就要去查在以前的站到底賣出了哪些車票,區間是怎麼樣的。

    我的以爲,12306自己就應該是做爲一個終端接入鐵路原有購票系統,本質上來講,和窗口,電話處於同一位置,都須要去中心查詢,下單,但網站的特殊性帶來了麻煩,不像窗口——有排隊,電話——超出服務能夠佔線,上述2種均可以控制住流量,至少不會引發自身的崩潰。而對於網站,通常的狀況都應該提供7*24的服務,頻頻不能提供服務,天然會引來不少罵聲。

    對於鐵道部來講,如今若是去改造原有購票系統,牽扯麪感受比較廣,先不說開發成本,光是迴歸窗口和電話業務估計就須要半年。因此,只能好好改造12306了

  • mikespook

    2012年1月16日12:37 | #54

    有些例證確實值得商榷,不過既然是務虛,那就更虛一點吧~~~
    讓 CAP 來套用一下這個系統吧。

  • cafe貓

    2012年1月16日13:04 | #55

    這個世界任何事物都是相對的。有陰就有樣。一樣,有排隊的地方就有黃牛,排隊和黃牛是兩個對立相生的。我以爲。鐵道部花那麼大力氣去搞個訂票網站,很不免有刷票,外掛什麼的。並且對那麼大的高併發訪問需求,還要注意鎖定資源,支付什麼的。這是給本身找難題。
    爲何不這樣?鐵道部就只管開放查詢,訂票,退票的接口。把接口開放出來,給其餘的B2C,好比淘寶,京東,易訊什麼的有經驗的電商。而後。鐵道部嚴格把關有訂票資格的網站,只讓有資格的電商或代理商才能訪問接口?
    個人思路就是開放! 儘可能把難題開放出去。只要把握住關鍵的就好了。

  • 無限

    2012年1月16日13:09 | #56

    一些想法,歡迎斧正

    1. 春運的火車票就固定的那麼多,並不會像作b2c那樣不斷的涌進來新的商品,因此總的查詢雖然多,實際上是能夠劃分紅許多相互之間沒有聯繫的小查詢的,好比想坐某個車次的幾十萬或者幾百萬人在查詢某車次的。

    2. 數據一致性也不是問題,春運這個票量全放內存裏並不大,能夠考慮採用redis集羣模式,實時同步寫操做到各個cluster去,因此能夠保證每一個agent服務那的數據也是即時的。

    3. 不顯示票數而顯示有或無,這個技術上當然好,不過考慮到天朝的官府公信力,若是隻顯示有或無,恐怕會引發更大的懷疑,搞不到票的人有可能鬧事,網民也會起鬨,因此最好仍是顯示票數,非可是顯示票數,最好是哪一個身份證買的都顯示出來,這樣才能消鉺民怨。

    4, 我卻是以爲春運這種暴增的任務能夠考慮出動飛艇運輸,參加博文 http://geek42.info/article/enhancement-of-beijing-traffic.rst

  • jiacheo

    2012年1月16日13:14 | #1

    Fenng :
    1. Tim會接任Apple的CEO了,由於他搞定了蘋果的庫存問題
    這個徹底是兩回事.
    2.集中在早8點到10點,每秒PV在高峯時上千萬
    這個數字有問題
    3.去年雙11節,淘寶的每小時的訂單數大約在60萬左右
    錯,淘寶峯值是278萬筆/小時
    4. 淘寶要比B2C的網站要簡單得多,由於沒有倉庫 
    這個是臆測。複雜度同樣的。
    5. 數據鏡像
    至少對於Oracle來講,目前沒法作到有效的鏡像,鏡像更可能是爲了數據安全可靠
    6. 數據一致性纔是真正的性能瓶頸
    數據一致性並不是業務難題,併發能力支撐纔是難題

    仍是馮大輝老師說的實在. 爲了突出系統複雜性, 把其餘的業務看得太簡單了.

  • Johnny

    2012年1月16日13:23 | #2

    1. 12306其實並非那麼爛,12306高峯期的表現跟加三倍服務器的京東比仍是要好很多的,淘寶那次1元賣支付寶寶令的時候,掛的比12306還難看。
    2. Redis、分表分庫、排隊隊列什麼的,這些東西知道是作什麼的是一回事,敢用到線上去另外一回事,特別是這麼大的壓力,淘寶爲了去O,去小型機而投入的研發力量以及積累下來的經驗,我相信比12306的合同還要貴的吧。並且這些東西解決的問題對於一個不差錢的主來講其實也算不了什麼大問題。
    3. 12306若是真的只用了幾千萬的話,說實話真的不算貴,建一千米高鐵花的錢都比這要多。
    4. 看到一幫子人罵來罵去的,看到不少人的評論內容,感受有些人的水平可能還不如12306的開發人員。
    5. 12306有了總比沒有好,並且身邊不少人包括我本身確實在上面買到了票,雖然刷了無數次才登進去,這已是一種進步了,但是仍是不少人在噴,咱們部門噴的最厲害的兩人,一個是坐飛機回家的,一個是坐汽車回家的,他們都是「聽別人說買不到票」,這個怎麼回事呢。

  • NinGoo

    2012年1月16日13:26 | #3

    3)峯值278萬沒有問題,我仍是說了,淘寶的系統比較簡單,由於沒有他庫。不過淘寶當時已經在極限上了,準備關一些省市流量了。

    流量和交易系統的支撐量是兩碼事,100億pv刷頁面,10億pv下單,能是一回事麼,呵呵。沒有倉庫,庫存仍是同樣要減的,不然超賣就能夠搞死任何一個活動了。

    作技術的,寫技術分析文章,仍是不要以道聽途說來臆測的好。

  • NinGoo

    2012年1月16日13:27 | #4

    NinGoo :
    3)峯值278萬沒有問題,我仍是說了,淘寶的系統比較簡單,由於沒有他庫。不過淘寶當時已經在極限上了,準備關一些省市流量了。
    流量和交易系統的支撐量是兩碼事,100億pv刷頁面,10億pv下單,能是一回事麼,呵呵。沒有倉庫,庫存仍是同樣要減的,不然超賣就能夠搞死任何一個活動了。
    作技術的,寫技術分析文章,仍是不要以道聽途說來臆測的好。

    10億pv刷頁面,10億pv下單,很差意思,多敲了個0,哈哈

    • 陳皓

      2012年1月16日13:30 | #5

      我就知道最終會在這些細節上有人較真。你遠遠不明白,幾個集中的物理倉庫,和各個商戶各自的庫他的差異。你也就沒法理解我說的。

  • 耗子

    2012年1月16日13:32 | #6

    我以爲,後臺用純C寫cgi,前臺用ajax減小整張html返回,配合上述的措施,應該會好不少的。

  • 啄米鳥

    2012年1月16日13:33 | #7

    官方不是說IBM有解決辦法而他們並無採納麼,因此問題仍是在領導層,不是技術層。

  • Gil

    2012年1月16日13:56 | #8

    1. 不少時候沒法登錄系統, 我在想這個跟外掛有沒有關係, 畢竟一個外掛等於不少人同時登陸. 寫這個外掛的人該拉出去斃了.
    2. 訂單提交比較慢. 這個其實若是真的按照車次來分的話, 彷佛數據一致的狀況不會那麼糟糕. 固然系統怎麼設計的不清楚, 表級鎖仍是行級鎖不清楚, 或許只是一個作全局統計的地方存在瓶頸. 這個要詳細trouble shooting.

    別的地方彷佛沒以爲有多少很差的地方, 這個網站能夠打分60分了.

    其實, 在社會供給不足的狀況下, 仍是計劃經濟, 配給制發票吧. 我們作不到每一個人都有票, 何須讓這麼多人耗時耗力的爭奪呢. 乾脆鐵道部就提供一個預訂系統, 提早一個月提交預訂信息, 分級: 例如先保證老人, 兒童, 殘疾人, 學生, 按照優先等級來分配, 咱們這些年輕人就不要去爭奪了. 最後分到票的坐火車, 沒有票的本身想辦法.

  • Gil

    2012年1月16日13:57 | #9

    @啄米鳥 我以爲若是IBM出方案, 仍是讓咱們本身的公司來解決這個問題吧.

  • Shawnone

    2012年1月16日14:03 | #10

    後臺提升性能的,關於技術方向有不少資料,但最關鍵的仍是怎樣和業務需求結合。我以爲業務中還漏了重要的一點 – 席位複用。這個對排隊,數據一致性等技術都會形成影響。也是和電子商務的訂單系統的一個很大不一樣。

  • Allen

    2012年1月16日14:16 | #11

    @kino
    我以爲前面若是有幾十萬人我以爲不算問題,還有隊伍確定在必定的時候是要清空的,一直排着也不符合常理,之前沒12306的時候不也是天天早上清空一次嗎?

    對變態的業務邏輯只能用變態的業務模型來知足。票(大學)是稀缺資源,不夠是正常的。可是隻看到有人報怨本身沒考好,沒報好,沒人有抱怨志願填報不合理。
    固然咱們用不着讓買票人也去參加考試而後憑分數來排定買票的排隊次序。在互聯網售票已經能夠開始運做(雖然運做的還不完美),咱們就把排隊的廣場放在網絡上吧。

    春運期間售票若是能改爲如下流程我以爲12306將能知足廣大票友的需求
    售票分爲如下幾個階段:
    實名註冊期 => 需求收集期 => 秒殺搶票期 => 後臺賣票期 => 訂單確認付款期 => 取票\刷卡上車期

    假定某年春運第一天爲1月30號,提早10天(20號)能夠拿票來看

    10號(所購票前20天12306開放購票意向收集與用戶註冊),相似大學報志願同樣,每身份證限購五張,可提交最多所購票當天6個不一樣車次購票請求,購票請求按優先級從上到下將會在後臺售票時依次嘗試知足
    18號零點前爲購票需求收集截止期。
    18號早上9點開始開放搶票,用戶保持已登陸狀態開始搶位置,系統顯示當前排隊的位置,刷新沒用,越刷越日後排,一次點擊就夠了!!19號零點前搶票結束 –您要是實在不着急買票,能夠等到最後一秒再來搶,不過買不到票您可別怨鐵道路
    19號零點後臺運行賣票程序,按照18號搶票排隊的順序賣票依次處理售票,售一張則發一個郵件與短信確認,24小時內需確認,逾期則收回。–固然,若是您請票心切,提早把錢存到12306的我的購票帳號裏也行,鐵道部恨不得您在那能存些餘額呢。
    20號可拿到紙票,或付款後便可以在鐵道部數據庫中查到購票記錄可屆時刷卡上車

    比方說某人今天網速不佳,或選的車次都太熱門沒買到票,那好,今天沒買到30號出發的票,我再修改一下個人車次信息,明天早上9點我再換個網速好點的地方再去搶個好位置,說不定明天他就能如願買到31的票。

    這個方案有兩個「亮」點:
    1)搶票。不搶是不行的,中國人這麼多,資源又那麼少,鐵道運力有限的狀況下你能不搶??你不在網上刷網頁搶,就得冬天一大早起來排隊去搶,或者打電話搶,你選擇怎麼搶??
    2)後臺賣票程序。這個比起什麼高併發,數據庫瓶頸,多臺server,數據庫一致性等等問題簡單到不知道哪裏去了。後臺賣票程序運行的時候定在晚上0點到早上7點之間,7個小時其它地方不賣票,光這個程序讀數據庫中收集好的購票意向信息逐個處理,7個小時處理不完接下來一天的購票信息嗎?若是真處理不完那麼具體細節設計上咱們再好好探討一下

    排隊系統是從雲風那裏讀到的。事在人爲,若是不人爲設置障礙或者鐵道部本身就沒打算好好賣,票絕對沒有那麼難賣

  • 奇石

    2012年1月16日14:40 | #12

    我以爲問題在於領導,固然了12360的技術人員也都是垃圾。
    1. 一個訂票的熱點網頁,能作出800K大小,須要幾十個鏈接,這徹底不可容忍的。若是誰說這均可以容忍,那你不配當程序員。
    2. 訂票爲什麼必定要搶?難道不能夠以1個小時,或者是1天爲一個週期,進行抽籤?每一個週期,你們隨時選票,而後進行抽籤,這樣即保證了公平性,又能夠不用把網站搞垮。
    3. 關於建分站的問題,這個本文做者純屬瞎扯淡。各省創建分站,結果是各個省份自制,且不說制度很亂,並且效果也不會好。由於創建單一的購買渠道,在這個渠道處也能夠進行分流,何須讓個省市去作?並且,從資源利用率來講,單一的網站能夠更合理的利用資源。
    4. 我以爲若是有現有的雲計算服務能夠用的話,鐵道部不該該本身從服務器作起。由於第一,你無法作的比別人更好,第二,你作這麼個東西,只是那麼幾天使用,不值得。若是不信任商業公司,能夠簽定保密協議,若是泄密,重重地處罰。

  • NinGoo

    2012年1月16日14:44 | #13

    陳皓 :
    我就知道最終會在這些細節上有人較真。你遠遠不明白,幾個集中的物理倉庫,和各個商戶各自的庫他的差異。你也就不管理解我說的。

    不是非要和你在細節上較真,可是作技術的,不較真細節來談架構就是扯淡。就跟你說「集中在早8點到10點,每秒PV在高峯時上千萬。」,我不清楚這能持續多少秒?若是持續一分鐘,不就6億pv沒了?那一天14億pv都集中到這幾秒了吧。

    倉庫庫存管理和調度確實是難度,我認可我不懂,因此我也沒法去評論說12306或者京東在這一塊容易仍是難。若是把倉庫庫存管理調度和下單系統徹底耦合在一塊兒設計,那確實是難度很是高的問題。

    一個業務,難仍是容易,從不一樣的角度去看多是不同的,若是你先假設了難,而後找論點來支撐,那怎麼都是難的。若是先假設了容易,找論點來支撐,發現又沒有那麼難了。因此辯論難仍是易,是很相互說服的。各自的經驗會得出不同的結果。

    12306的pv,有多少部分是在刷登陸的?有多少pv是在刷票務信息的?有多少在刷下單的?有多少在刷支付的?不要看到14億就想固然的認爲交易系統壓力大,就是高併發交易。我沒有作過火車票交易系統,但從機票系統來看,壓力基本都集中在搜索票務信息上,真正的下單壓力其實不大。各機票代理都要從中航信去獲取票務信息,這方面提及來比12306本身一家人來作的難度更大了。

    真想給12306平反或者支招,仍是多找些數據,多作些研究,別隨便百度一把出來幾個數字就引用爲論據,像你的博客關於裏說不到45歲不寫書,我想是一個道理的。

    • 陳皓

      2012年1月16日15:20 | #14

      1)高峯時段意思是一個尖,不是持續。
      2)倉庫是集中管理的,這個和車票是同樣的。淘寶的庫存分擔到了每一個商戶身上。是我沒說清?
      3)在放票的時候,12306的有多少人登陸,就有多少人查詢,就有多少人下單。這是剛需,和上網買東西不同。難道這也很難理解?
      4)機票的業務能和火車票這種比嗎?能作飛機的人原本就少,並且機票整年能夠買。代理公司或是旅行團,一次訂N張票,批量操做。

      不是我說不清楚,是你必定要挑刺罷了。我沒有給12306支招,我談的是高性能的技術。你的理解能力須要提升。

  • 利物浦的亨德森

    2012年1月16日14:48 | #15

    學生已是提早了。通常高校都會提早20多天通知回家的學生訂票的。主要是硬座票。可是學生裏面仍是有部分車次是很難弄到票的。主要是山東和四川。這說明即便是劃出一個小部分人羣來,在相對集中的幾天內,鐵道部的運力仍是不足。做爲學生我知道這個。

    老人和殘疾人人數較少,並且有相關的證實文件,確實能夠。

    兒童就很差說了,至少在目前來講兒童缺少像身份證同樣的證實去保證系統可以識別這個用戶就是個兒童。這個可能須要醫院,公安局等多個部門共同改革纔可能。重點是家長會放心兒童一人上車????即便可以證實了。這也是個問題。

    固然配額制的話,在供給有限的狀況下,那就是巨大的尋租和腐敗的空間了。誰先拿票,誰不拿票?即便有個評估標準,不說執行狀況和評估所須要花費的資金和人力成本了。那也須要一個十分信息公開透明的機制和設計去保障,至少在目前來講尚未哪一個政府部門作到。估計等到財政預算公開的那天,這個就實現了。。。。。因此一旦配額,那就是超級黃牛的時代了。

    因此我的認爲仍是回到經濟學的基本框架中來。
    (1)提升運力,同時創建靈活的火車時刻表。這個就是增長供給。具體數據不是很清楚,可是春運這十幾天確定是峯值,不過平時又沒那麼多人。若是簡單的堆車皮,平時的運營成本過高。因此火車的發車和訂價機制就要放開。經過靈活的車次和價格來引導平常需求和下降運營成本。固然一方面要保證天天都有到其餘地方的車,同時還要保證低成本,少空車,這個我以爲是一個較複雜的優化問題。重點是買車容易,修路難。提升運力修鐵路須要時間。。。。。。

    (2)錯峯放假。這個就是減小需求。核心的假期就是除夕及以後的三天。你們都集中在這個時候,必然有搞不到票的。加上學生假期也是那個時候。因此能夠考慮規定春節前10天和後10天不出售學生票。讓學生的需求在高峯期
    前消化掉。至於其餘行業的。老闆們行行好,別死拉着員工非得等到春節前兩天才讓回了吧。。。。
    @Gil

  • mdqyz

    2012年1月16日14:57 | #16

    其實12306不是什麼「訂票」系統,而是「購票」系統,因此纔有那麼多同步問題,由於你必須去「搶」當前放出來的那點票,而不能「訂」將來放出來的票,也不支持模糊的訂票需求。
    另外,餘票查詢,車次查詢等等都不該該是數據庫同步的,因此實際上同步的只有「佔庫存」這個操做,但也能夠設計成把需求放入按每日車次的隊列,先完成支付的先得,異步處理隊列再通知用戶就能夠了。這樣基本上就沒有用戶能夠參與的同步事件,準備好足夠的服務器就能夠解決全人類的訂票要求了吧。

  • bones7456

    2012年1月16日15:09 | #17

    @Fenng
    278w實際上是平均值,雙十一的峯值接近500w。而雙十二的0點這一小時,成交筆數超過650w。

  •  

    2012年1月16日16:17 | #20

    1:數據層:高併發下對數據存取的壓力經過分區化來實現,擴展性由讀遠大於寫的特性則增長copy來處理讀請求,數據一致性就用單寫來保證。 2:業務邏輯上:只要放票方式是如此,必然帶來購票人羣在放票瞬間的高峯涌入,除非已經作好系統負載能力等於峯值的準備,不然只能經過削峯的形式處理,好比排隊系統。 3:支持大輝的前5點,第六點實際上說的跟陳皓說的差很少是一碼事,平行擴展的時候在保證可用性的前提下,併發能力的提升須要經過增長數據的copy來實現,同步報文丟失的可能性增大,一致性就會受到影響,強制保證一致性必然帶來併發能力的降低,不知道我對CAP的理解對不對…

相關文章
相關標籤/搜索