秒殺程序數據庫設計

        上個月有幸去騰訊逛了一圈,面試一個職位,儘管沒被錄取但是過程總體來說仍是愉快的。面試過程當中面試個人小朋友(看年齡大概在26,7歲)問了我一個關於秒殺的問題,他說騰訊遊戲經常會有秒殺的活動,很是屢次會致使server死鎖或壓力太大,應該怎樣設計減輕數據庫server壓力。固然因爲面試的是PHP職位,我作的是C#和JAVA我知道應該沒機會因此本不想太過「配合」的回答,但是看面試個人小朋友看我好像很是不削的樣子(可能因爲面試的是PHP職位而且一上來就讓我作題目,儘管我有點不情願作題但是畢竟是騰訊仍是作了但是PHP接觸的真的很少因此題目差點兒是連蒙帶猜的完畢的,預計不是很是好看),因此仍是認真想了想解決方式。前端

        秒殺說究竟就是瞬間大規模訪問,致使的壓力,前端咱們可以使用集羣技術,數據庫呢?拆表?是個方法,但是假設僅僅是簡單拆表仍然會有問題,畢竟秒殺商品被記錄到表中後用戶秒殺必然是需要經過改動表中已有的秒殺商品記錄來肯定這個商品是否已經被秒走。爲了防止搶到同一條記錄加鎖是必須。而數據庫一鎖性能問題就來了。那怎麼辦呢?我想了一個方法(至少有一點可以肯定騰訊遊戲沒實用這種方法解決),秒殺時並不是立馬去改動數據庫中記錄(進行update操做),而是先向一張表中插入一條記錄,相似進入等待隊列,爲了防止大規模插入操做致使鎖表咱們可以將隊列表拆成多張一樣結構表。有一個job會不斷讀取這些隊列表並依照插入時間排列計算那些記錄被秒殺成功。而client在點擊秒殺button後斷開鏈接,幾秒後再次經過查詢語句來查詢結果,並返回給前臺客戶。面試

         這樣作的優勢秒殺過程是分段的,前臺用戶在秒殺時僅是向(多張隊列表中)某一張隊列表中插入一條記錄,以後便斷開本次鏈接進入等待,job程序經過合併查詢將多張秒殺表合併按插入時間排序,按規則得出秒殺成功的用戶並改動秒殺商品表,代表此商品已被秒殺,前臺程序在等待幾秒後查詢秒殺商品表得到本身是否已秒殺成功。數據庫

         因爲第一步僅僅是插入操做,無需操心同步操做帶來的髒數據問題,因此咱們可以經過拆表來分散壓力減小隔離等級。更新操做是有一個單獨的job程序完畢的,因爲僅僅有一個程序會去改記錄因此就不存在鎖表問題。最後前臺經過查詢語句來獲取結果,因爲查詢商品秒殺結果也不需要不論什麼的順序僅僅需要知道是否是你本身搶到的就好,因此可以使用with(nolock)一類的忽略鎖機制來運行。性能

相關文章
相關標籤/搜索