摘要:開篇金幣積分商城下稱商城是眾多內的一個產品,隨著使用的用戶越來越多,商城對于用戶留存的提升,扮演著重要的角色做為提高用戶黏性的核心產品,在擁有很好用戶體驗的同時,也必須存在著一個高效穩定的系統。分析上述兩點,得到結論按用戶進行分庫分表。
開篇
分庫分表金幣(積分)商城(下稱“商城”)是眾多App內的一個產品,隨著App使用的用戶越來越多,商城對于用戶留存的提升,扮演著重要的角色;做為提高用戶黏性的核心產品,在擁有很好用戶體驗的同時,也必須存在著一個高效、穩定的系統。
商城,是一個基于虛擬貨幣(下稱“金幣”)進行運營的產品,也就意味著,我們需要給用戶發放金幣,用于用戶兌換各種獎品。我們需要詳細記錄用戶金幣的收支情況,并提供給用戶查詢。在redis、memcache盛行的時代,構建一個幾十萬QPS的只讀系統并不復雜,需要做到:無狀態服務+多級緩存,并且能夠進行水平擴展,應該就差不多了。而商城需要記錄每秒十萬的用戶行為,需要的是每秒數十萬(這里翻倍了)的數據讀寫(insert&update)操作,這種量級是無法在單實例數據上完成的,那么該如何分庫分表。
分庫分表原則Tip 1 . 在做設計時,首先要明確3個事情
業務場景,不要空談設計,場景是什么
目標,系統需要做到的目標是什么
分析上述兩點,得到什么結論
那么,對于用戶行為數據的場景是:1.用戶A查詢自己的所有金幣記錄(不能查別人的),2.查看商城內金幣數量分布情況。對于第二個場景可以直接通過大數據進行統計分析(不進行詳細解讀)。對于第一個場景,系統需要做到的目標是:用戶A只進行一次查詢,就可以得到所有數據(不考慮分頁場景)。分析上述兩點,得到結論:按用戶id進行分庫分表。(分析過程有些磨嘰了,哈哈,忍著)
原則明確后,能夠開始進行分庫分表嗎?不能。需要進一步確認,如何分?分多少?擴容成本?對于數據庫擴容,我們選擇以2的N次冪進行擴容,這種方式的好處是,進行擴容時,只需要將數據copy一份就可以,上層應用增加數據庫節點,無需考慮數據遷移問題(可靠性高),不好的地方是,會產生臟數據,這個問題并沒太多影響,按照擴容后規則,刪除即可。對于分表,我們將金幣記錄在每個庫中拆成5份。
Tip 2 .為什么要進行分庫分表
服務器資源(cpu、磁盤、內存、IO)遇到瓶頸
數據量變大,數據操作(crud)開銷變大
部署圖如下:
數據編號=uid%4,表編號=uid%5
算法流程圖如下:
目前業內對分庫實現方案有兩種
客戶端分庫分表,在客戶端完成分庫分表操作,直接鏈接數據庫。
中間件(例如:cobar),客戶端鏈接中間件,由中間件完成分庫分表操作。
這兩種方案各有利弊,客戶端分庫分表由于直連數據庫,所以性能比使用中間件要高。而使用中間件,能夠很好的將分庫分表操作與客戶端隔離,數據調整對上層透明,便于統一管理。
訂單id生成策略為什么要關注id生成策略?全局唯一,全局有序,業務隔離,不容易被猜到等等,這些都不是關鍵。重點討論下,如何讓看似無意義的id,對系統后續擴展帶來意義。
Java領域著名的唯一id應該算是uuid了,不過uuid太長,而且包含字母,不適合做為訂單id。通過調研,我們借鑒了Twitter的Snowflake算法來實現,算法思想是在64位長整型數字中,存儲node編號,并且有序,同時支持并發。
為了便于訂單數據后期擴展,我們有必要在訂單id生成時,就將其做好分庫分表準備(雖然目前訂單量不多)
其中serverid,占2位,最大支持2^2臺服務器(0-3),dbid占6位,最大支持2^6個數據庫,其他以此類推。
最終一致性訂單數據除了用戶維度查詢外,還有通過商品維度來查詢的場景,例如:按照商品,進行訂單發貨。為了解決這個問題,我們對應的策略是,將訂單數據進行冗余,并按照商品維度進行存儲。方案雖然簡單,但是保持兩個訂單庫數據的一致性是一件很麻煩的事情。
顯然單機數據庫事務是無法解決的(數據不在同一個數據庫中),所以要保證數據一致性,需要引入強一致性的分布式事務,這個方案先不談實現成本問題,就憑其超低的效率,這是我們無法接收的。所以引入異步數據同步,來實現數據的最終一致性。當然,異步同步數據也會帶來數據不一致(消息總線丟消息,嘿嘿),所以我們又引入了實時監控服務,實時計算數據差異,并進行一致性同步。
流程圖如下:
數據庫高可用Tip 3 . 類似這種存在多個緯度的數據存儲問題,都可以采用這種方案來解決
這是個經典的議題了,我們在這個方案上,并無創新,用幾張圖來簡單說明下。
如何讓商城在大流量下存活?這是一個類似搶購或者秒殺場景如何應對的問題,對于這個問題在@沈劍 的《秒殺系統優化思路》中已經寫的很清晰了,那么,我再補充一下。
中心思路路仍然是”逐層消耗流量“,應用層面對大流量情況下,很有可能自身難保,還沒來得及攔截流量,自身就已經OOM了。那么該如何優化這個方案?見下圖:
在ngx層進行優化,有兩個方案:
達到應用層最大處理能力時,Hold住流量,讓請求排隊,逐步施放流量到應用層。
達到應用層最大處理能力時,拋棄多余流量。
我們采用的第二個方案。視頻課程
==【完】==
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/67103.html
摘要:可水平擴展,可以添加更多服務器來擴展您的數據庫需要管理員是否開發人員和管理員都可以使用適用場景會計師事務所和銀行,以及需要具有清晰架構的結構化數據的其他公司。 今天的主題是從MongoDB漫談數據庫,在日常的項目中,我們一般都是使用的mysql作為數據庫,但是一旦有問題,又常常會聽到類似要不換成MongoDB試試的聲音,因此就讓我們這些小白來隨便聊聊數據庫 什么是數據庫 我們就用最簡單...
閱讀 2247·2021-11-22 09:34
閱讀 2012·2021-09-22 15:22
閱讀 2015·2019-08-29 15:05
閱讀 2104·2019-08-26 10:43
閱讀 3406·2019-08-26 10:26
閱讀 876·2019-08-23 18:29
閱讀 3518·2019-08-23 16:42
閱讀 1994·2019-08-23 14:46