1.支撐日活百萬用戶的高併發系統,應該如何設計其數據庫架構?
目錄:
1.用多臺服務器來分庫支撐高併發讀寫(將數據和請求都分散到不同的服務器上了)
2.大量分表來保證海量數據下查詢性能(大量分表可以使得單表數據量降低,提高了查詢性能)
3.讀寫分離來支撐按需擴容及性能提升(讀的需求往往都大於寫,利用主從架構,從來作爲讀,可以很容易通過主從的擴容來實現按需擴容;另外讀寫分離還可以由因爲讀寫同一個表可能帶來的鎖衝突問題)
高併發下的數據庫架構設計總結
2.【高併發優化實踐】10倍請求壓力來襲,你的系統會被擊垮嗎?
關於MQ掛掉之後的降級機制的設計:
如果說在高峯期併發量比較高的情況下,接收到一條數據立馬同步寫本地磁盤文件,這個性能絕對是極其差的,會導致系統自身的吞吐量瞬間大幅度下降,這個降級機制是絕對無法在生產環境運行的,因爲自己就會被高併發請求壓垮。
因此當時設計的時候,對降級機制進行了一番精心的設計。
我們的核心思路是一旦MQ中間件故障,觸發降級機制之後,系統接收到一條請求不是立馬寫本地磁盤,而是採用內存雙緩衝 + 批量刷磁盤的機制。curren緩衝區滿了之後就和ready緩存區進行交換。
推文中出現的問題:在交換時ready緩衝區還沒有結束寫入到磁盤的操作,導致所有線程全部陷入等待
解決方案:擴大緩存區
啓發:對系統設計和開發的任何較爲複雜的機制,都必須要參照線上高峯期的最大流量來壓力測試。只有這樣,才能確保任何在系統上線的複雜機制可以經得起線上高峯期的流量的考驗。
3.微服務、註冊中心等高可用相關
3.1、【雙11狂歡的背後】微服務註冊中心如何承載大型系統的千萬級訪問?
總結:
3.1.1.通過上面的分析可以看到,Eureka通過設置適當的請求頻率(拉取註冊表30秒間隔,發送心跳30秒間隔),可以保證一個大規模的系統每秒請求Eureka Server的次數在幾百次。
3.1.2.同時通過純內存的註冊表,保證了所有的請求都可以在內存處理,確保了極高的性能
3.1.3.另外,多級緩存機制,確保了不會針對內存數據結構發生頻繁的讀寫併發衝突操作,進一步提升性能。
3.2、【性能優化之道】每秒上萬併發下的Spring Cloud參數優化實戰
總結:
3.2.1.針對大的負責的多表關聯SQL解決方案:對數據庫就執行簡單的單表查詢和更新,然後複雜的業務邏輯全部放在java系統中來執行,比如一些關聯,或者是計算之類的工作
3.2.2.系統接口超時時間不要搞成幾秒甚至幾十秒的超時,一般超時定義在1秒以內,是比較通用以及合理的。因爲一個接口,理論的最佳響應速度應該在200ms以內,或者慢點的接口就幾百毫秒。如果一個接口響應時間達到1秒+,建議考慮用緩存、索引、NoSQL等各種你能想到的技術手段,優化一下性能。否則你要是胡亂設置超時時間是幾秒,甚至幾十秒,萬一下游服務偶然出了點問題響應時間長了點呢?那你這個線程池裏的線程立馬全部卡死!
3.2.3.設置合理的接口重試機制
3.2.4.涉及到了重試,那麼必須上接口的冪等性保障機制:常見的方案:1、可以在數據庫裏建一個唯一索引,插入數據的時候如果唯一索引衝突了就不會插入重複數據;2、通過redis裏放一個唯一id值,然後每次要插入數據,都通過redis判斷一下,那個值如果已經存在了,那麼就不要插入重複數據了
建議參考方案:
3.3.1、首先你的hystrix資源隔離以及超時這塊,必須設置合理的參數,避免高峯期,頻繁的hystrix線程卡死
3.3.2、其次,針對個別的服務故障,要設置合理的降級策略,保證各個服務掛了,可以合理的降級,系統整體可用!
比如,如果你的某個服務掛了,那麼你的hystrix會走熔斷器,然後就會降級,你需要考慮到各個服務的降級邏輯。
舉一些常見的例子:
如果查詢數據的服務掛了,你可以查本地的緩存
如果寫入數據的服務掛了,你可以先把這個寫入操作記錄日誌到比如mysql裏,或者寫入MQ裏,後面再慢慢恢復
如果redis掛了,你可以查mysql
如果mysql掛了,你可以把操作日誌記錄到es裏去,後面再慢慢恢復數據。
具體用什麼降級策略,要根據業務來定,不是一成不變的。