日日操夜夜添-日日操影院-日日草夜夜操-日日干干-精品一区二区三区波多野结衣-精品一区二区三区高清免费不卡

公告:魔扣目錄網為廣大站長提供免費收錄網站服務,提交前請做好本站友鏈:【 網站目錄:http://www.ylptlb.cn 】, 免友鏈快審服務(50元/站),

點擊這里在線咨詢客服
新站提交
  • 網站:51998
  • 待審:31
  • 小程序:12
  • 文章:1030137
  • 會員:747

本文較長,可提前收藏。

用戶中心,幾乎是所有互聯網公司,必備的子系統。隨著數據量不斷增加,吞吐量不斷增大,用戶中心的架構,該如何演進呢。

什么是用戶中心業務?

用戶中心是一個通用業務,主要提供用戶注冊、登錄、信息查詢與修改的服務

用戶中心的數據結構是怎么樣的?

用戶中心的核心數據結構為:

User(uid, login_name, passwd, sex, age, nickname, …)

其中:

(1)uid為用戶ID,為主鍵;

(2)login_name, passwd, sex 等是用戶屬性;

其系統架構又是怎么樣的呢?

在業務初期,單庫單表,配合用戶中心微服務,就能滿足絕大部分業務需求,其典型的架構為:

用戶中心,1億數據,架構如何設計?

 

(1)user-center:用戶中心服務,對調用者提供友好的RPC接口;

(2)user-db:對用戶進行數據存儲;

當數據量越來越大,例如達到1億注冊量時,會出現什么問題呢?

隨著數據量越來越大,單庫無法承載所有的數據,此時需要對數據庫進行水平切分

常見的水平切分算法有“范圍法”和“哈希法”。

水平切分,什么是范圍法?

范圍法,以用戶中心的業務主鍵uid為劃分依據,采用區間的方式,將數據水平切分到兩個數據庫實例上去:

用戶中心,1億數據,架構如何設計?

 

(1)user-db1:存儲0到1千萬的uid數據;

(2)user-db2:存儲1千萬到2千萬的uid數據;

范圍法有什么優點?

(1)切分策略簡單,根據uid,按照范圍,user-center很快能夠定位到數據在哪個庫上;

(2)擴容簡單,如果容量不夠,只要增加user-db3,拓展2千萬到3千萬的uid即可;

范圍法有什么缺點?

(1)uid必須要滿足遞增的特性

(2)數據量不均,新增的user-db3,在初期的數據會比較少;

(3)請求量不均,一般來說,新注冊的用戶活躍度會比較高,故user-db2往往會比user-db1負載要高,導致服務器利用率不平衡;

畫外音:數據庫層面的負載均衡,既要考慮數據量的均衡,又要考慮負載的均衡。

水平切分,什么是哈希法?

哈希法,也是以用戶中心的業務主鍵uid為劃分依據,采用哈希的方式,將數據水平切分到兩個數據庫實例上去:

用戶中心,1億數據,架構如何設計?

 

(1)user-db1:存儲奇數的uid數據;

(2)user-db2:存儲偶數的uid數據;

哈希法有什么優點?

(1)切分策略簡單,根據uid,按照hash,user-center很快能夠定位到數據在哪個庫上;

(2)數據量均衡,只要uid是隨機的,數據在各個庫上的分布一定是均衡的;

(3)請求量均衡,只要uid是隨機的,負載在各個庫上的分布一定是均衡的;

畫外音:如果采用分布式id生成器,id的生成,一般都是隨機的。

哈希法有什么缺點?

(1)擴容麻煩,如果容量不夠,要增加一個庫,重新hash可能會導致數據遷移;

用戶中心架構,實施了水平切分之后,會帶來什么新的問題呢?

使用uid來進行水平切分之后,對于uid屬性上的查詢,可以直接路由到庫,假設訪問uid=124的數據,取模后能夠直接定位db-user1:

用戶中心,1億數據,架構如何設計?

 

但對于非uid屬性上的查詢,就悲劇了,例如login_name屬性上的查詢:

用戶中心,1億數據,架構如何設計?

 

假設訪問login_name=shenjian的數據,由于不知道數據落在哪個庫上,往往需要遍歷所有庫,當分庫數量多起來,性能會顯著降低。

用戶中心,非uid屬性查詢,有哪些業務場景?

任何脫離業務的架構設計都是耍流氓。

在進行架構討論之前,先來對業務進行簡要分析,用戶中心非uid屬性上,有兩類典型的業務需求

第一大類,用戶側,前臺訪問,最典型的有兩類需求:

(1)用戶登錄:通過登錄名login_name查詢用戶的實體,1%請求屬于這種類型;

(2)用戶信息查詢:登錄之后,通過uid來查詢用戶的實例,99%請求屬這種類型;

用戶側的查詢,基本上是單條記錄的查詢,訪問量較大,服務需要高可用,并且對一致性的要求較高

第二大類,運營側,后臺訪問,根據產品、運營需求,訪問模式各異,按照年齡、性別、頭像、登陸時間、注冊時間來進行查詢。

運營側的查詢,基本上是批量分頁的查詢,由于是內部系統,訪問量很低,對可用性的要求不高,對一致性的要求也沒這么嚴格。

對于這兩類不同的業務需求,應該使用什么樣的架構方案來解決呢?

總的來說,針對這兩類業務需求,架構設計的核心思路為:

(1)用戶側,采用“建立非uid屬性到uid的映射關系”的架構方案;

(2)運營側,采用“前臺與后臺分離”的架構方案;

用戶側,如何實施“建立非uid屬性到uid的映射關系”呢?

常見的方法有四種

(1)索引表法;

(2)緩存映射法;

(3)生成uid法;

(4)基因法;

接下來,咱們一一介紹。

什么是,索引表法?

索引表法的思路是:uid能直接定位到庫,login_name不能直接定位到庫,如果通過login_name能查詢到uid,問題便能得到解決。

具體的解決方案如下:

(1)建立一個索引表記錄login_name與uid的映射關系;

(2)用login_name來訪問時,先通過索引表查詢到uid,再通過uid定位相應的庫

(3)索引表屬性較少,可以容納非常多數據,一般不需要分庫;

(4)如果數據量過大,可以通過login_name來分庫;

索引表法,有什么缺點呢?

數據訪問,會增加一次數據庫查詢,性能會有所下降。

什么是,緩存映射法?

緩存映射法的思路是:訪問索引表性能較低,把映射關系放在緩存里,能夠提升性能。

具體的解決方案如下:

(1)login_name查詢先到cache中查詢uid,再根據uid定位數據庫;

(2)假設cache miss,掃描所有分庫,獲取login_name對應的uid,放入cache;

(3)login_name到uid的映射關系不會變化,映射關系一旦放入緩存,不會更改,無需淘汰,緩存命中率超高;

(4)如果數據量過大,可以通過login_name進行cache水平切分;

緩存映射法,有什么缺點呢?

仍然多了一次網絡交互,即一次cache查詢。

什么是,生成uid法?

生成uid法的思路是:不進行遠程查詢,由login_name直接得到uid。

具體的解決方案如下:

(1)在用戶注冊時,設計函數login_name生成uid,uid=f(login_name),按uid分庫插入數據;

(2)用login_name來訪問時,先通過函數計算出uid,即uid=f(login_name)再來一遍,由uid路由到對應庫;

生成uid法,有什么缺點呢?

該函數設計需要非常講究技巧,且有uid生成沖突風險

畫外音:uid沖突,是業務無法接受的,故生產環境中,一般不使用這個方法。

什么是,基因法?

基因法的思路是:不能用login_name生成uid,但可以從login_name抽取“基因”,融入uid中

假設分8庫,采用uid%8路由,潛臺詞是,uid的最后3個bit決定這條數據落在哪個庫上,這3個bit就是所謂的“基因”。

具體的解決方案如下:

用戶中心,1億數據,架構如何設計?

 

(1)在用戶注冊時,設計函數login_name生成3bit基因,login_name_gene = f(login_name),如上圖粉色部分;

(2)同時,生成61bit的全局唯一id,作為用戶的標識,如上圖綠色部分;

(3)接著把3bit的login_name_gene也作為uid的一部分,如上圖黃色部分;

(4)生成64bit的uid,由id和login_name_gene拼裝而成,并按照uid分庫插入數據;

(5)用login_name來訪問時,先通過函數由login_name再次復原3bit基因,login_name_gene = f(login_name),通過login_name_gene%8直接定位到庫;

畫外音:基因法,有點意思,在分庫時經常使用。

用戶側,如何實施“前臺與后臺分離”的架構方案呢?

前臺用戶側,業務需求基本都是單行記錄的訪問,只要建立非uid屬性login_name到uid的映射關系,就能解決問題。

后臺運營側,業務需求各異,基本是批量分頁的訪問,這類訪問計算量較大,返回數據量較大,比較消耗數據庫性能。

此時的架構,存在什么問題?

此時,前臺業務和后臺業務共用一批服務和一個數據庫,有可能導致,由于后臺的“少數幾個請求”的“批量查詢”的“低效”訪問,導致數據庫的cpu偶爾瞬時100%,影響前臺正常用戶的訪問(例如,登錄超時)。

畫外音:本質上,是系統的耦合。

用戶中心,1億數據,架構如何設計?

 

而且,為了滿足后臺業務各類“奇形怪狀”的需求,往往會在數據庫上建立各種索引,這些索引占用大量內存,會使得用戶側前臺業務uid/login_name上的查詢性能與寫入性能大幅度降低,處理時間增長。

對于這一類業務,應該采用“前臺與后臺分離”的架構方案。

什么是,前臺與后臺分離的架構方案?

用戶中心,1億數據,架構如何設計?

 

用戶側前臺業務需求架構依然不變,產品運營側后臺業務需求則抽取獨立的 web / service / db 來支持,解除系統之間的耦合,對于“業務復雜”“并發量低”“無需高可用”“能接受一定延時”的后臺業務:

(1)可以去掉service層,在運營后臺web層通過dao直接訪問db;

(2)不需要反向代理,不需要集群冗余;

(3)不需要訪問實時庫,可以通過MQ或者線下異步同步數據;

(4)在數據庫非常大的情況下,可以使用更契合大量數據允許接受更高延時的“索引外置”或者“HIVE”的設計方案;

用戶中心,1億數據,架構如何設計?

 

總結

用戶中心,是典型的“單KEY”類業務,這一類業務,都可以使用上述架構方案

常見的數據庫水平切分方式有兩種

(1)范圍法;

(2)哈希法;

水平切分后碰到的問題是:

(1)通過uid屬性查詢能直接定位到庫,通過非uid屬性查詢不能定位到庫

非uid屬性查詢,有兩類典型的業務

(1)用戶側,前臺訪問,單條記錄的查詢,訪問量較大,服務需要高可用,并且對一致性的要求較高;

(2)運營側,后臺訪問,根據產品、運營需求,訪問模式各異,基本上是批量分頁的查詢,由于是內部系統,訪問量很低,對可用性的要求不高,對一致性的要求也沒這么嚴格;

針對這兩類業務,架構設計的思路是

(1)用戶側,采用“建立非uid屬性到uid的映射關系”的架構方案;

(2)運營側,采用“前臺與后臺分離”的架構方案;

前臺用戶側,“建立非uid屬性到uid的映射關系”,有四種常見的實踐

(1)索引表法:數據庫中記錄login_name與uid的映射關系;

(2)緩存映射法:緩存中記錄login_name與uid的映射關系;

(3)生成uid法:login_name生成uid;

(4)基因法:login_name基因融入uid;

后臺運營側,“前臺與后臺分離”的最佳實踐是

(1)前臺、后臺系統 web/service/db 分離解耦,避免后臺低效查詢引發前臺查詢抖動;

(2)可以采用數據冗余的設計方式;

(3)可以采用“外置索引”(例如ES搜索系統)或者“大數據處理”(例如HIVE)來滿足后臺變態的查詢需求;

任何脫離業務的架構設計都是耍流氓。

來源公眾號:架構師之路

作者:58沈劍

分享到:
標簽:架構
用戶無頭像

網友整理

注冊時間:

網站:5 個   小程序:0 個  文章:12 篇

  • 51998

    網站

  • 12

    小程序

  • 1030137

    文章

  • 747

    會員

趕快注冊賬號,推廣您的網站吧!
最新入駐小程序

數獨大挑戰2018-06-03

數獨一種數學游戲,玩家需要根據9

答題星2018-06-03

您可以通過答題星輕松地創建試卷

全階人生考試2018-06-03

各種考試題,題庫,初中,高中,大學四六

運動步數有氧達人2018-06-03

記錄運動步數,積累氧氣值。還可偷

每日養生app2018-06-03

每日養生,天天健康

體育訓練成績評定2018-06-03

通用課目體育訓練成績評定