分佈式、高併發、高性能場景(搶購、秒殺、搶票、限時競答)數據一致性解決方案

技術指標:php

PV(Page View, 頁面瀏覽量)在千萬級別
QPS(Query Per Second, 每秒處理請求數)在百萬級別
數據量在千億級別
接口響應速度不能超過150毫秒
用戶提交請求到頁面呈現不能超過3秒html

架構設計:
1. 從LAMP架構轉爲面向服務架構(服務能夠用多種開發語言實現,不受一種開發語言限制)
2. 對海量數據作Sharding分片,分庫分表
3. 從有狀態服務改成無狀態接口服務(便於分佈式部署)
4. 精心設計的數據層(存儲、壓縮、索引)
5. 分佈式系統最終瓶頸(CPU、內存、存儲、網絡)
6. 日誌服務化,每一個服務能夠用不一樣的開發語言,考慮多種開發語言的兼容性,定義標準化的日誌是把分佈在不一樣機器上的日誌關聯起來的惟一且有效的辦法
7. 對請求入口作負載均衡後再到達應用層前端

頁面優化:
1. 靜態文件壓縮,優化HTTP請求鏈接數,以減小寬帶需求,讓頁面更快加載出來
2. 靜態資源作CDN部署
3. 先後端作數據分離,讓搜索服務解耦,在高併發狀況下更靈活作負載均衡(前端使用Vue.js、AngularJs等,數據來源能夠不限編程語言)
4. 後端數據大部分來自緩存,加載快,給用戶更快的體驗linux

後端編碼:
1. 高併發多線程寫入同一個文件的時候,會存現「線程安全」的問題,致使結果和預期不一致,經常使用的方法是給代碼邏輯加上「鎖」。
2. 秒殺和搶購的場景中,還有另一個問題,就是「超發(超賣)」,若是在這方面控制不慎,會產生髮送過多的狀況。咱們也曾經據說過,某些電商搞搶購活動,買家成功拍下後,商家卻不認可訂單有效,拒絕發貨。這裏的問題,也許並不必定是商家奸詐,而是系統技術層面存在超發風險致使的。redis

數據層架構優化:
1. 商品詳情、商品庫存等,能夠放在緩存(redis集羣),避免頻繁去數據庫取數據,提升商品信息的讀能力
2. 數據庫讀寫分離,分庫分表實現負載均衡
3. 若是數據庫有查詢緩存功能,則使用數據庫查詢緩存功能(Query Cache功能,若是使用,記得定時清理碎片:Flush Query Cache)
4. 其餘數據庫細節優化(參考其餘網絡文章)shell

系統層優化:
1. 修改linux內核參數,適應高併發場景(具體參考網絡相關文章)數據庫

業務優化:
秒殺和搶購收到了「海量」的請求,實際上裏面的水分是很大的。有不少是第三方搶購輔助工具發送的請求,這些都是屬於做弊的手段。編程

做弊方法和防護方法:
1. 做弊行爲:同一個賬號,一次性發出多個請求
防護方法:在程序入口處,1個賬號只容許接收一個請求,其餘請求過濾。或者,本身實現一個服務,將同一個帳號的請求放入一個隊列中,處理完一個,再處理下一個。後端

2. 多個帳號,一次性發送多個請求
不少賬號註冊功能,在發展早期是沒有任何限制的,很容易就能註冊不少個賬號。所以,一些特殊的工做室會編寫自動註冊腳本,積累一大批「殭屍賬號」(微博中的殭屍粉),數量龐大,專門作各類「刷」的行爲,如搶購、刷票、轉發抽獎等。
防護方法:
1).使用創新的驗證碼,好比回答問題或者執行某些簡單的操做,把真實的用戶和輔助工具區分來開。
2).直接禁止IP,雖然可能致使誤傷,可是在實際場景中能夠得到很好的效果。緩存

3. 多個賬號,多個IP發送不一樣請求
「灰色工做室」發現單機IP請求頻率被控制後,他們有的新的進攻方案:不斷變換IP。(IP來源有隨機代理IP、被植入木馬的肉雞,數量龐大等)
防護方法:這種場景下的請求,已經很難分辨出真實用戶或輔助工具。一般只能經過設置業務門檻來限制這種請求,或者經過賬號行爲的「數據挖掘」來提早清理它們。
殭屍賬號有一些共同的特徵,就是賬號極可能屬於同一號碼段,甚至是連號,活躍度不高,等級低,資料不全等。根據這些特色,適當設置參與門檻,例如限制參與的賬號等級等。經過這些方法,也能夠過濾掉一部分殭屍賬號。
(黃牛帳號也是有一些共同特徵的,例如常常搶票和退票,節假日異常活躍等)

系統瓶頸/災難預案:
1. 最簡單的就是有降級的預案,流量超過系統容量後,先把哪些功能砍掉, 須要有明確的優先級 。
2. 線上全鏈路壓測,就是把如今的流量放大到咱們日常流量的五倍甚至十倍(好比下線一半的服務器,縮容而不是擴容),看看系統瓶頸最早發生在哪裏。咱們以前有一些例子,推測系統數據庫會先出現瓶頸,可是實測發現是前端的程序先遇到瓶頸。
3. 搭建分佈式系統,搭建在線Docker集羣, 全部業務共享備用的Docker 集羣資源,這樣能夠極大的避免每一個業務都預留資源,可是實際上流量沒有增加形成的浪費。

 

結語:咱們的挑戰都同樣,就是數據量,bigger and bigger,用戶體驗是faster and faster,業務是more and more。

 

總結: 

1. 面向服務架構(不限開發語言)
2. 有狀態服務改成無狀態接口服務(便於分佈式部署)
3. 海量數據分片,分庫,分表(阿里雲RDS開啓讀寫分離)
4. 前端靜態資源作CDN中轉
5. 最終硬件瓶頸(CPU、內存、存儲、網絡)
6. 日誌服務化(把分佈在不一樣機器上的日誌關聯起來的惟一且有效的辦法)
7. 對請求入口作負載均衡後再到達應用層

 

參考文章:

https://www.cnblogs.com/soundcode/p/5590710.html (保證分佈式系統數據一致性的6種方案)
http://www.infoq.com/cn/articles/solution-of-distributed-system-transaction-consistency (分佈式系統事務一致性解決方案)
https://zhuanlan.zhihu.com/p/21994882 (分佈式系統理論基礎 - 一致性、2PC和3PC)
https://www.zhihu.com/question/50176389/answer/119724104 (網絡遊戲如何保證數據一致性?)
https://coolshell.cn/articles/10910.html (分佈式系統的事務處理)
https://blog.csdn.net/zhoudaxia/article/details/38067003 (如何解決秒殺的性能問題和超賣的討論)
http://www.cnblogs.com/wangrudong003/p/7111789.html (.NetCore+Jexus代理+Redis模擬秒殺商品活動)
http://www.cnblogs.com/zhenghui317/p/5577345.html (千萬級規模高性能、高併發的網絡架構經驗)
http://mt.sohu.com/it/d20170403/131798804_255931.shtml (去哪兒網機票搜索系統的高併發架構設計是怎樣的?)
http://blog.csdn.net/xiaemperor/article/details/38234979 (NodeJS優缺點及適用場景討論)
http://www.cnblogs.com/dinglang/p/6133501.html (緩存在高併發場景下的常見問題)
http://blog.csdn.net/qq_34341290/article/details/53316173 (高併發搶購思路)
http://blog.csdn.net/jimlong/article/details/47805047 (PHP解決搶購、秒殺、搶樓、抽獎等阻塞式高併發庫存防控超量的思路方法)
http://www.jb51.net/article/100050.htm (php結合redis實現高併發下的搶購、秒殺功能的實例)

 

版權聲明:本文采用署名-非商業性使用-相同方式共享(CC BY-NC-SA 3.0 CN)國際許可協議進行許可,轉載請註明做者及出處。
本文標題:高併發高性能場景(搶購、秒殺、搶票、限時競答)解決方案
本文連接:http://www.cnblogs.com/sochishun/p/7003190.html
本文做者:SoChishun (郵箱:14507247#qq.com | 博客:http://www.cnblogs.com/sochishun/)發表日期:2017年6月13日

相關文章
相關標籤/搜索