分庫分表:用戶中心,單key業務如何進行數據庫切分

用戶中心數據庫切分架構實踐|場景介紹

    用戶中心是一個十分常見的業務系統,涵蓋用戶登錄、註冊、信息查詢與修改等服務。

      用戶的核心元數據爲:

       User(uid,login_name,nickname,password,sex,age)

      其中   ●   uid :用戶ID,主鍵

                ●    login_name,nickname,password,sex,age :用戶的其他屬性

在業務初期,單表單庫就能滿足業務需求:


用戶中心數據庫切分方法|範圍法

當數據量越來越大時,需要對數據庫進行水平切分,常見的切分算法有“範圍法”和“哈希法”

範圍法:以用戶中心的業務uid爲劃分依據,將數據水平切分到兩個數據庫實例上去:


範圍法的優點:

• 切分策略簡單,根據uid,按照範圍,user- center很快能夠定位到數據在哪個庫上
• 擴容簡單,如果容量不夠,只要增加user-db3即可


範圍法的不足是:

• uid必須要滿足遞增的特性
• 數據量不均,新增的user-db3,在初期的數據會比較少
• 請求量不均,一般來說,新註冊的用戶活躍度會比較高,故user-db2往往會比user-db1負載要高,導致服務器利用率不平衡

用戶中心數據庫切分方法|哈希法

哈希法:以用戶中心的業務uid爲劃分依據,將數據水平切分到兩個數據庫實例上去:


哈希法的優點是:

•切分策略簡單,根據uid,按照範圍,user- center很快能夠定位到數據在哪個庫上
•數據量均衡:只要uid是均衡的,數據在各個庫上的分佈一定是均衡的
•請求量均衡:只要uid是均衡的,負載在各個庫上的分佈一定是均衡的


哈希法的不足是:

•擴容麻煩,如果需要增加一個庫,需要重新hash,這有可能會導致數據遷移,給平滑升級帶來困難。

用戶中心數據查詢需求分析

任何脫離業務的架構設計都是耍流氓,在進行架構討論之前,首先要對業務進行簡要分析,看看錶結構上有哪些查詢需求。

根據業務經驗,用戶中心往往有以下幾類業務需求:

(1)用戶側,前臺訪問,最典型的有兩類需求

用戶登錄:通過login_name/email/phone查詢用戶實體,1%的請求屬於這種類型。

用戶信息查詢:登錄之後,通過uid來查詢用戶的實例,99%請求屬於這種類型。

用戶側查詢的基本特點是:基本是單條記錄查詢,訪問量大,服務要求高可用,並且對一致性要求較高。

(2)運營側,後臺訪問。

需要滿足產品及運營層面的各類需求,訪問模式各異,按照年齡、性別、登錄時間、註冊時間等屬性來 進行查詢。運營側需求的的基本特點是:大量的批量分頁查詢需求,訪問量較低,對可用性要求不高,對一致性的要求也沒有這麼嚴格。

用戶中心數據查詢需求解決方案-用戶側

1.索引表法:

思路:uid可以直接定位到數據庫,login_name不可以直接定位到庫。建立login_name到login_id的映射關係。

  解決方案:

• 建立一個索引表記錄login_name->uid的映射關係
• 用login_name來訪問時,先通過索引表查詢到uid,再定位相應的庫
• 索引表屬性較少,可以容納非常多數據,一般不需要分庫
 • 如果數據量過大,可以通過login_name來分庫

  • 不足:多一次數據庫查詢,性能下降一倍。

2.緩存映射法:

   思路:訪問索引表的性能比較低。將映射放在緩存中可以獲得更好的性能體驗。

   解決方案:

• login_name查詢先到cache中查詢uid,再根據uid定位數據庫
• 假設cachemiss,採用掃全庫法獲取login_name對應的uid,放入cache
• login_name到uid的映射關係不會變化,映射關係一旦放入緩存,不會更改,無需淘汰,緩存命中率超高
• 如果數據量過大,可以通過login_name進行cache水平切分

  • 不足:多一次cache查詢。

3.login_name生成uid

    思路:不進行遠程查詢,由login_name直接得到uid

    解決方案:

      • 在用戶註冊時,設計函數login_name生成uid,uid=f(login_name),按uid分庫插入數據
      • 用login_name進行登錄時,先通過函數計算出uid,再由uid路由到對應數據庫進行查詢。

  •     不足:對login_name到uid的生成函數要求較高,有uid生成衝突的風險

4.login_name基因融入uid

思路:從login_name抽取“基因” 融入uid中。

解決方案:

      • 在用戶註冊時,設計函數login_name生成4bit基因,login_name_gene=f(login_name),如上圖粉色部分
      • 同時,生成60bit的全局唯一id,作爲用戶的標識,如上圖綠色部分
      • 接着把4bit的login_name_gene也作爲uid的一部分,如上圖屎黃色部分
      • 生成64bit的uid,由id和login_name_gene拼裝而成,並按照uid分庫插入數據
      • 用login_name來訪問時,先通過函數由login_name再次復原4bit基因,login_name_gene=f(login_name),通過  login_name_gene%8直接定位到庫

用戶中心數據查詢需求解決方案-運營側

後臺運營側的查詢需求各異,基本是批量的分頁查詢,計算量和返回數據量較大,比較消耗數據庫性能

此時如果後臺業務和前臺業務共用一批服務和同一個數據庫。有可能會導致後臺少數幾個請求的批量查詢的低效訪問造成數據庫服務器cpu瞬時100%,影響前臺用戶的正常訪問。

另外,由於後臺業務的查詢需求多種多樣,需要在數據庫上建立多種索引,這些索引會佔用大量的內存和磁盤,從而造成前臺業務的uid/login_name的查詢和寫入性能大幅度降低,處理時間增長。

對這一類業務,應該採用“前後臺分離”的架構方案



原文:https://blog.csdn.net/sunhuiliang85/article/details/78418546 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章