用uid分庫,uname上的查詢怎麼辦?

2021-02-26 架構師之路

1分鐘系列

 

【緣起】

用戶中心是幾乎每一個公司必備的基礎服務,用戶註冊、登錄、信息查詢與修改都離不開用戶中心。

 

當數據量越來越大時,需要多用戶中心進行水平切分。最常見的水平切分方式,按照uid取模分庫:

通過uid取模,將數據分布到多個資料庫實例上去,提高服務實例個數,降低單庫數據量,以達到擴容的目的。

 

水平切分之後:

uid屬性上的查詢可以直接路由到庫,如上圖,假設訪問uid=124的數據,取模後能夠直接定位db-user1。

 

對於uname上的查詢,就不能這麼幸運了:

uname上的查詢,如上圖,假設訪問uname=shenjian的數據,由於不知道數據落在哪個庫上,往往需要遍歷所有庫【掃全庫法】,當分庫數量多起來,性能會顯著降低。

 

用uid分庫,如何高效實現上的查詢,是本文將要討論的問題。

 

【索引表法】

思路:uid能直接定位到庫,uname不能直接定位到庫,如果通過uname能查詢到uid,問題解決

解決方案

1)建立一個索引表記錄uname->uid的映射關係

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

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

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

潛在不足:多一次資料庫查詢,性能下降一倍

 

【緩存映射法】

思路:訪問索引表性能較低,把映射關係放在緩存裡性能更佳

解決方案

1)uname查詢先到cache中查詢uid,再根據uid定位資料庫

2)假設cache miss,採用掃全庫法獲取uname對應的uid,放入cache

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

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

潛在不足:多一次cache查詢

 

uname生成uid

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

解決方案

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

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

潛在不足:該函數設計需要非常講究技巧,有uid生成衝突風險

 

uname基因融入uid

思路:不能用uname生成uid,可以從uname抽取「基因」,融入uid中

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

 

解決方案

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

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

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

4)生成64bit的uid,由id和uname_gene拼裝而成,並按照uid分庫插入數據

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

 

【總結】

業務場景:用戶中心,數據量大,通過uid分庫後,通過uname路由不到庫

解決方案

1)掃全庫法:遍歷所有庫

2)索引表法:資料庫中記錄uname->uid的映射關係

3)緩存映射法:緩存中記錄uname->uid的映射關係

4)uname生成uid

5)uname基因融入uid

==【完】==

推薦閱讀:

一分鐘掌握資料庫垂直拆分

資料庫秒級平滑擴容架構方案

58到家資料庫30條軍規解讀

相關焦點

  • MySQL:網際網路公司常用分庫分表方案匯總
    1、IO瓶頸第一種:磁碟讀IO瓶頸,熱點數據太多,資料庫緩存放不下,每次查詢時會產生大量的IO,降低查詢速度 -> 分庫和垂直分表。第二種:網絡IO瓶頸,請求的數據太多,網絡帶寬不夠 -> 分庫。
  • 數據蔣堂 | 時序數據從分表到分庫
    不過,在實戰中,分區表的效果在某些場景下並不好,而且使用時也有些約束條件,並不總好用且能用的。結果,在實際業務中,我們常常會看到對於這種大數據採用手工物理分表的方案。所謂物理分表,就是人為將一個大表分成若干較小的物理數據表。
  • 簡單粗暴的分庫分表設計方案
    缺點:(1)需要在前期規劃好分庫和分表的數量,不能動態擴展;(2)分頁查詢需要基於shard-key,限制業務的查詢場景;DDAL的實現:<bean id="idRule" class="org.hellojavaer.ddal.ddr.shard.rule.SpelShardRouteRule">
  • 分庫分表常見概念解讀+Sharding-JDBC實戰
    垂直分庫很大程度上取決於業務的劃分,但有時候業務間的劃分並不是那麼清晰,比如:訂單數據的拆分要考慮到與其他業務間的關聯關係,並不是說直接把訂單相關的表放在一個庫裡這麼簡單。在一定程度上,垂直分庫似乎提升了一些資料庫性能,可實際上並沒有解決由於單表數據量過大導致的性能問題,所以就需要配合水平切分方式來解決。
  • 分庫分表:TiDB,求別搶飯碗!
    由於 Oracle、MySQL 資料庫並不是面向分布式環境而設計,因此即使勉強通過分庫、分表或中間件的方式,在資料庫層面做了分片,從本質上看也只是複製了相同的堆棧,而非針對分布式系統進行存儲和計算優化,這正是進行跨業務查詢或跨物理機查詢和寫入十分繁瑣的本質原因。
  • 用R進行文件系統管理(一)
    用R進行文件系統管理R的極客理想系列文章,涵蓋了R的思想,使用,工具,創新等的一系列要點,以我個人的學習和體驗去詮釋R的強大。
  • 面試官:說說Mysql資料庫分庫分表,並且會有哪些問題
    也就是一臺伺服器的資源例如CPU、內存、IO、磁碟等是有限的,所以這時候分庫分表就上啦!分庫分庫講白了就是比如現在你有一個資料庫伺服器,資料庫中有兩張表分別是用戶表和訂單表。如果要分庫的話現在你需要買兩臺機子,搞兩個資料庫分別放在兩臺機子上,並且一個資料庫放用戶表,一個資料庫放訂單表這樣存儲壓力就分擔到兩個伺服器上了,但是會帶來新的問題,所以東西變複雜了都會有新的問題產生。
  • 一文快速入門分庫分表中間件 Sharding-JDBC(必修課)
    ,對分庫分表的拆分方式有了一定的了解。(表),它由數據源名稱和數據表組成,例如上圖中 order_db_1.t_order_0、order_db_2.t_order_1 就表示一個數據節點。和JDBC的貓膩從名字上不難看出,Sharding-JDBC 和 JDBC有很大關係,我們知道 JDBC 是一種 Java 語言訪問關係型資料庫的規範,其設計初衷就是要提供一套用於各種資料庫的統一標準,不同廠家共同遵守這套標準,並提供各自的實現方案供應用程式調用。
  • 一個億級分庫分表項目的實戰全過程解析
    點擊上方"雲時代架構", 右上角選擇「設為星標」精品技術文章準時送上!分庫分表的文章網上非常多,但是大多內容比較零散,以講解知識點為主,沒有完整地說明一個大表的切分、新架構設計、上線的完整過程。另外,表A 和 表B 各自有二、三十個欄位,兩表的主鍵存在一一對應關係,因此,本次分庫分表項目中,還需要將兩個表進行重構融合,將多餘/無用的欄位剔除。在線業務通過分布式鏈路追蹤系統進行查詢,按照表名作為查詢條件,然後按照服務維度進行聚合,找到所有相關服務,寫一個文檔記錄相關團隊和服務。
  • 分庫分表的4個面試連環炮問題!不會就慘了
    用過哪些分庫分表中間件?不同的分庫分表中間件都有什麼優點和缺點?你們具體是如何對資料庫如何進行垂直拆分或水平拆分的?二、面試官心理分析其實這塊肯定是扯到高並發了,因為分庫分表一定是為了支撐高並發、數據量大兩個問題的。
  • UID是什麼?UID和UI哪個好?區別有哪些?
    uid設計師UID和UI區別有哪些?UI即User Interface(用戶界面)的簡稱。UI設計是指對軟體的人機互動、操作邏輯、界面美觀的整體設計。uid設計師的職業規劃UID中UI的含義的用戶界面,UID設計師是指從事對軟體的人機互動、操作邏輯和界面美觀整體設計工作的人,其中包含平面設計、高級網頁設計和手機界面設計等。目前UID設計師是中國信息產業中為搶手的人才之一,尤其是在一線城市及各大省會城市,都是急缺的人才。
  • 特好用!!!8種分布式ID生成方法
    但當主從同步也扛不住的時候就需要分表分庫了,但分庫分表後需要有一個唯一ID來標識一條數據,且這個唯一ID還必須有規則,能輔助我們解決分庫分表的一些問題。資料庫的自增ID顯然不能滿足需求;特別一點的如訂單、優惠券也都需要有唯一ID做標識。此時一個能夠生成全局唯一ID的系統是非常必要的,那麼這個全局唯一ID就叫分布式ID。
  • sqltoy-orm-4.17.5 發布,支持 QueryExecutor 中定義分庫分表
    (原本只支持xml中定義)//分庫dbSharding(String strategy, String... paramNames)//分表tableSharding(String strategy, String[] tables, String... paramNames)
  • MySQL 這該死的 「IN (子查詢)」
    FROM t2 WHERE t1.id=t2.id) AND t1.id%2 = 0;SELECT t1.如下這條SQL,大家覺得他屬於「非關聯子查詢」還是屬於「關聯子查詢」?,假如 t1 表有1億行,並且t1和t2的s1欄位都有索引可用,假設子查詢每執行一次只需要 10微妙(1秒 = 1000毫秒 = 1000000微妙) ,這條簡單的SQL需要執行多久呢,答案是 1000 秒。
  • 分庫分表就能無限擴容嗎,解釋得太好了!
    分庫分表如果你的公司產品很受歡迎,業務繼續高速發展,數據越來越多,SQL 操作越來越慢,那麼資料庫就會成為瓶頸,那麼你肯定會想到分庫分表,不論通過 ID hash 或者 range 的方式都可以。如下圖:這下應該沒問題了吧。任憑你用戶再多,並發再高,我只要無限擴容資料庫,無限擴容應用,就可以了。
  • 分庫分表?如何做到永不遷移數據和避免熱點?
    上圖中訂單數據達到了4000萬,我們也知道mysql單表存儲量推薦是百萬級,如果不進行處理,mysql單表數據太大,會導致性能變慢。使用方案可以參考數據進行水平拆分。把4000萬數據拆分4張表或者更多。當然也可以分庫,再分表;把壓力從資料庫層級分開。
  • [精選] MySQL分庫分表後用PHP如何來完美操作
    】關注公眾號後回覆:652348     獲取提取碼當單表達到幾千萬時,查詢一次要很久,如果有聯合查詢,有可能會死在那分庫分表主要就是解決這個問題,減小資料庫的負擔,縮短查詢時間分庫1)按功能分用PHP例子實現分庫分表操作用兩臺機子簡單以同個業務庫分庫,同個表分表,演示插入、查詢如何定位庫和表並最終成功執行兩臺機子:server1:192.168.1.198server2:192.168.1.199兩臺機子都執行下面操作1、先創建10個資料庫,每個資料庫
  • 如何完成一次快速的查詢
    MySQL查詢慢是什麼體驗?謝邀,利益相關。大多數網際網路應用場景都是讀多寫少,業務邏輯更多分布在寫上。對讀的要求大概就是要快。那麼都有什麼原因會導致我們完成一次出色的慢查詢呢?1.1.4 有什麼好用且簡單的索引方法前面說到大多慢查詢都源於索引,怎麼建立並用好索引。這裡有一些簡單的規則。索引下推:性別欄位不適合建索引,但確實存在查詢場景怎麼辦?如果是多條件查詢,可以建立聯合索引利用該特性優化。覆蓋索引:也是聯合索引,查詢需要的信息在索引裡已經包含了,就不會再回表了。
  • Linux常用命令:nslookup,lsmd5sum,uname,history等
    1. nslookup做DNS的人都知道nslookup(name server lookup:域名查詢)命令是做什麼用的
  • 分庫分表【Sharding-JDBC】入門與項目實戰
    調研下來,發現Sharding-JDBC目前成熟度最高並且應用最廣的Java分庫分表的客戶端組件。本文主要介紹一些 Sharding-JDBC 核心概念以及生產環境下的實戰指南,旨在幫助組內成員快速了解 Sharding-JDBC 並且能夠快速將其使用起來。