91欧美超碰AV自拍|国产成年人性爱视频免费看|亚洲 日韩 欧美一厂二区入|人人看人人爽人人操aV|丝袜美腿视频一区二区在线看|人人操人人爽人人爱|婷婷五月天超碰|97色色欧美亚州A√|另类A√无码精品一级av|欧美特级日韩特级

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評論與回復
登錄后你可以
  • 下載海量資料
  • 學習在線課程
  • 觀看技術視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會員中心
創(chuàng)作中心

完善資料讓更多小伙伴認識你,還能領取20積分哦,立即完善>

3天內(nèi)不再提示

你們知道為什么要分庫分表嗎

上海磐啟微電子有限公司 ? 來源:愛笑的架構(gòu)師 ? 作者:雷架 ? 2021-08-16 10:37 ? 次閱讀
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

在文章開頭先拋幾個問題:

(1)什么時候才需要分庫分表呢?我們的評判標準是什么?

(2)一張表存儲了多少數(shù)據(jù)的時候,才需要考慮分庫分表?

(3)數(shù)據(jù)增長速度很快,每天產(chǎn)生多少數(shù)據(jù),才需要考慮做分庫分表?

這些問題你都搞清楚了嗎?相信看完這篇文章會有答案。

為什么要分庫分表?

首先回答一下為什么要分庫分表,答案很簡單:數(shù)據(jù)庫出現(xiàn)性能瓶頸。用大白話來說就是數(shù)據(jù)庫快扛不住了。

數(shù)據(jù)庫出現(xiàn)性能瓶頸,對外表現(xiàn)有幾個方面:

大量請求阻塞

在高并發(fā)場景下,大量請求都需要操作數(shù)據(jù)庫,導致連接數(shù)不夠了,請求處于阻塞狀態(tài)。

SQL 操作變慢

如果數(shù)據(jù)庫中存在一張上億數(shù)據(jù)量的表,一條 SQL 沒有命中索引會全表掃描,這個查詢耗時會非常久。

存儲出現(xiàn)問題

業(yè)務量劇增,單庫數(shù)據(jù)量越來越大,給存儲造成巨大壓力。

從機器的角度看,性能瓶頸無非就是CPU、內(nèi)存、磁盤、網(wǎng)絡這些,要解決性能瓶頸最簡單粗暴的辦法就是提升機器性能,但是通過這種方法成本和收益投入比往往又太高了,不劃算,所以重點還是要從軟件角度入手。

數(shù)據(jù)庫相關優(yōu)化方案

數(shù)據(jù)庫優(yōu)化方案很多,主要分為兩大類:軟件層面、硬件層面。

軟件層面包括:SQL 調(diào)優(yōu)、表結(jié)構(gòu)優(yōu)化、讀寫分離、數(shù)據(jù)庫集群、分庫分表等;

硬件層面主要是增加機器性能。

SQL 調(diào)優(yōu)

SQL 調(diào)優(yōu)往往是解決數(shù)據(jù)庫問題的第一步,往往投入少部分精力就能獲得較大的收益。

SQL 調(diào)優(yōu)主要目的是盡可能的讓那些慢 SQL 變快,手段其實也很簡單就是讓 SQL 執(zhí)行盡量命中索引。

開啟慢 SQL 記錄

如果你使用的是 Mysql,需要在 Mysql 配置文件中配置幾個參數(shù)即可。

slow_query_log=on

long_query_time=1

slow_query_log_file=/path/to/log

調(diào)優(yōu)的工具

常常會用到 explain 這個命令來查看 SQL 語句的執(zhí)行計劃,通過觀察執(zhí)行結(jié)果很容易就知道該 SQL 語句是不是全表掃描、有沒有命中索引。

select id, age, gender from user where name = ‘愛笑的架構(gòu)師’;

返回有一列叫“type”,常見取值有:

ALL、index、range、 ref、eq_ref、const、system、NULL(從左到右,性能從差到好)

ALL 代表這條 SQL 語句全表掃描了,需要優(yōu)化。一般來說需要達到range 級別及以上。

表結(jié)構(gòu)優(yōu)化

以一個場景舉例說明:

“user”表中有 user_id、nickname 等字段,“order”表中有order_id、user_id等字段,如果想拿到用戶昵稱怎么辦?一般情況是通過 join 關聯(lián)表操作,在查詢訂單表時關聯(lián)查詢用戶表,從而獲取導用戶昵稱。

但是隨著業(yè)務量增加,訂單表和用戶表肯定也是暴增,這時候通過兩個表關聯(lián)數(shù)據(jù)就比較費力了,為了取一個昵稱字段而不得不關聯(lián)查詢幾十上百萬的用戶表,其速度可想而知。

這個時候可以嘗試將 nickname 這個字段加到 order 表中(order_id、user_id、nickname),這種做法通常叫做數(shù)據(jù)庫表冗余字段。這樣做的好處展示訂單列表時不需要再關聯(lián)查詢用戶表了。

冗余字段的做法也有一個弊端,如果這個字段更新會同時涉及到多個表的更新,因此在選擇冗余字段時要盡量選擇不經(jīng)常更新的字段。

架構(gòu)優(yōu)化

當單臺數(shù)據(jù)庫實例扛不住,我們可以增加實例組成集群對外服務。

當發(fā)現(xiàn)讀請求明顯多于寫請求時,我們可以讓主實例負責寫,從實例對外提供讀的能力;

如果讀實例壓力依然很大,可以在數(shù)據(jù)庫前面加入緩存如 redis,讓請求優(yōu)先從緩存取數(shù)據(jù)減少數(shù)據(jù)庫訪問。

緩存分擔了部分壓力后,數(shù)據(jù)庫依然是瓶頸,這個時候就可以考慮分庫分表的方案了,后面會詳細介紹。

硬件優(yōu)化

硬件成本非常高,一般來說不可能遇到數(shù)據(jù)庫性能瓶頸就去升級硬件。

在前期業(yè)務量比較小的時候,升級硬件數(shù)據(jù)庫性能可以得到較大提升;但是在后期,升級硬件得到的收益就不那么明顯了。

分庫分表詳解

下面我們以一個商城系統(tǒng)為例逐步講解數(shù)據(jù)庫是如何一步步演進。

單應用單數(shù)據(jù)庫

在早期創(chuàng)業(yè)階段想做一個商城系統(tǒng),基本就是一個系統(tǒng)包含多個基礎功能模塊,最后打包成一個 war 包部署,這就是典型的單體架構(gòu)應用。

如上圖,商城系統(tǒng)包括主頁 Portal 模板、用戶模塊、訂單模塊、庫存模塊等,所有的模塊都共有一個數(shù)據(jù)庫,通常數(shù)據(jù)庫中有非常多的表。

因為用戶量不大,這樣的架構(gòu)在早期完全適用,開發(fā)者可以拿著 demo到處找(騙)投資人。

一旦拿到投資人的錢,業(yè)務就要開始大規(guī)模推廣,同時系統(tǒng)架構(gòu)也要匹配業(yè)務的快速發(fā)展。

多應用單數(shù)據(jù)庫

在前期為了搶占市場,這一套系統(tǒng)不停地迭代更新,代碼量越來越大,架構(gòu)也變得越來越臃腫,現(xiàn)在隨著系統(tǒng)訪問壓力逐漸增加,系統(tǒng)拆分就勢在必行了。

為了保證業(yè)務平滑,系統(tǒng)架構(gòu)重構(gòu)也是分了幾個階段進行。

第一個階段將商城系統(tǒng)單體架構(gòu)按照功能模塊拆分為子服務,比如:Portal 服務、用戶服務、訂單服務、庫存服務等。

如上圖,多個服務共享一個數(shù)據(jù)庫,這樣做的目的是底層數(shù)據(jù)庫訪問邏輯可以不用動,將影響降到最低。

多應用多數(shù)據(jù)庫

隨著業(yè)務推廣力度加大,數(shù)據(jù)庫終于成為了瓶頸,這個時候多個服務共享一個數(shù)據(jù)庫基本不可行了。我們需要將每個服務相關的表拆出來單獨建立一個數(shù)據(jù)庫,這其實就是“分庫”了。

單數(shù)據(jù)庫的能夠支撐的并發(fā)量是有限的,拆成多個庫可以使服務間不用競爭,提升服務的性能。

如上圖,從一個大的數(shù)據(jù)中分出多個小的數(shù)據(jù)庫,每個服務都對應一個數(shù)據(jù)庫,這就是系統(tǒng)發(fā)展到一定階段必要要做的“分庫”操作。

現(xiàn)在非?;鸬奈⒎占軜?gòu)也是一樣的,如果只拆分應用不拆分數(shù)據(jù)庫,不能解決根本問題,整個系統(tǒng)也很容易達到瓶頸。

分表

說完了分庫,那什么時候分表呢?

如果系統(tǒng)處于高速發(fā)展階段,拿商城系統(tǒng)來說,一天下單量可能幾十萬,那數(shù)據(jù)庫中的訂單表增長就特別快,增長到一定階段數(shù)據(jù)庫查詢效率就會出現(xiàn)明顯下降。

因此,當單表數(shù)據(jù)增量過快,業(yè)界流傳是超過500萬的數(shù)據(jù)量就要考慮分表了。當然500萬只是一個經(jīng)驗值,大家可以根據(jù)實際情況做出決策。

那如何分表呢?

分表有幾個維度,一是水平切分和垂直切分,二是單庫內(nèi)分表和多庫內(nèi)分表。

水平拆分和垂直拆分

就拿用戶表(user)來說,表中有7個字段:id,name,age,sex,nickname,description,如果 nickname 和 description 不常用,我們可以將其拆分為另外一張表:用戶詳細信息表,這樣就由一張用戶表拆分為了用戶基本信息表+用戶詳細信息表,兩張表結(jié)構(gòu)不一樣相互獨立。但是從這個角度來看垂直拆分并沒有從根本上解決單表數(shù)據(jù)量過大的問題,因此我們還是需要做一次水平拆分。

還有一種拆分方法,比如表中有一萬條數(shù)據(jù),我們拆分為兩張表,id 為奇數(shù)的:1,3,5,7……放在 user1, id 為偶數(shù)的:2,4,6,8……放在 user2中,這樣的拆分辦法就是水平拆分了。

水平拆分的方式也很多,除了上面說的按照 id 拆表,還可以按照時間維度取拆分,比如訂單表,可以按每日、每月等進行拆分。

每日表:只存儲當天的數(shù)據(jù)。

每月表:可以起一個定時任務將前一天的數(shù)據(jù)全部遷移到當月表。

歷史表:同樣可以用定時任務把時間超過 30 天的數(shù)據(jù)遷移到 history表。

總結(jié)一下水平拆分和垂直拆分的特點:

垂直切分:基于表或字段劃分,表結(jié)構(gòu)不同。

水平切分:基于數(shù)據(jù)劃分,表結(jié)構(gòu)相同,數(shù)據(jù)不同。

單庫內(nèi)拆分和多庫拆分

拿水平拆分為例,每張表都拆分為了多個子表,多個子表存在于同一數(shù)據(jù)庫中。比如下面用戶表拆分為用戶1表、用戶2表。

在一個數(shù)據(jù)庫中將一張表拆分為幾個子表在一定程度上可以解決單表查詢性能的問題,但是也會遇到一個問題:單數(shù)據(jù)庫存儲瓶頸。

所以在業(yè)界用的更多的還是將子表拆分到多個數(shù)據(jù)庫中。比如下圖中,用戶表拆分為兩個子表,兩個子表分別存在于不同的數(shù)據(jù)庫中。

一句話總結(jié):分表主要是為了減少單張表的大小,解決單表數(shù)據(jù)量帶來的性能問題。

分庫分表帶來的復雜性

既然分庫分表這么好,那我們是不是在項目初期就應該采用這種方案呢?不要激動,冷靜一下,分庫分表的確解決了很多問題,但是也給系統(tǒng)帶來了很多復雜性,下面簡要說一說。

(1)跨庫關聯(lián)查詢

在單庫未拆分表之前,我們可以很方便使用 join 操作關聯(lián)多張表查詢數(shù)據(jù),但是經(jīng)過分庫分表后兩張表可能都不在一個數(shù)據(jù)庫中,如何使用 join 呢?

有幾種方案可以解決:

字段冗余:把需要關聯(lián)的字段放入主表中,避免 join 操作;

數(shù)據(jù)抽象:通過ETL等將數(shù)據(jù)匯合聚集,生成新的表;

全局表:比如一些基礎表可以在每個數(shù)據(jù)庫中都放一份;

應用層組裝:將基礎數(shù)據(jù)查出來,通過應用程序計算組裝;

(2)分布式事務

單數(shù)據(jù)庫可以用本地事務搞定,使用多數(shù)據(jù)庫就只能通過分布式事務解決了。

常用解決方案有:基于可靠消息(MQ)的解決方案、兩階段事務提交、柔性事務等。

(3)排序、分頁、函數(shù)計算問題

在使用 SQL 時 order by, limit 等關鍵字需要特殊處理,一般來說采用分片的思路:

先在每個分片上執(zhí)行相應的函數(shù),然后將各個分片的結(jié)果集進行匯總和再次計算,最終得到結(jié)果。

(4)分布式 ID

如果使用 Mysql 數(shù)據(jù)庫在單庫單表可以使用 id 自增作為主鍵,分庫分表了之后就不行了,會出現(xiàn)id 重復。

常用的分布式 ID 解決方案有:

UUID

基于數(shù)據(jù)庫自增單獨維護一張 ID表

號段模式

Redis 緩存

雪花算法(Snowflake)

百度uid-generator

美團Leaf

滴滴Tinyid

這些方案后面會寫文章專門介紹,這里不再展開。

(5)多數(shù)據(jù)源

分庫分表之后可能會面臨從多個數(shù)據(jù)庫或多個子表中獲取數(shù)據(jù),一般的解決思路有:客戶端適配和代理層適配。

業(yè)界常用的中間件有:

shardingsphere(前身 sharding-jdbc)

Mycat

總結(jié)

如果出現(xiàn)數(shù)據(jù)庫問題不要著急分庫分表,先看一下使用常規(guī)手段是否能夠解決。

分庫分表會給系統(tǒng)帶來巨大的復雜性,不是萬不得已建議不要提前使用。作為系統(tǒng)架構(gòu)師可以讓系統(tǒng)靈活性和可擴展性強,但是不要過度設計和超前設計。在這一點上,架構(gòu)師一定要有前瞻性,提前做好預判。大家學會了嗎?

編輯:jq

聲明:本文內(nèi)容及配圖由入駐作者撰寫或者入駐合作網(wǎng)站授權(quán)轉(zhuǎn)載。文章觀點僅代表作者本人,不代表電子發(fā)燒友網(wǎng)立場。文章及其配圖僅供工程師學習之用,如有內(nèi)容侵權(quán)或者其他違規(guī)問題,請聯(lián)系本站處理。 舉報投訴
  • cpu
    cpu
    +關注

    關注

    68

    文章

    11277

    瀏覽量

    224951
  • 數(shù)據(jù)

    關注

    8

    文章

    7335

    瀏覽量

    94755
  • SQL
    SQL
    +關注

    關注

    1

    文章

    789

    瀏覽量

    46695
  • 磁盤
    +關注

    關注

    1

    文章

    398

    瀏覽量

    26470

原文標題:我們?yōu)槭裁匆謳旆直恚?/p>

文章出處:【微信號:gh_6a53af9e8109,微信公眾號:上海磐啟微電子有限公司】歡迎添加關注!文章轉(zhuǎn)載請注明出處。

收藏 人收藏
加入交流群
微信小助手二維碼

掃碼添加小助手

加入工程師交流群

    評論

    相關推薦
    熱點推薦

    嵌入式分享#51:為什么手機屏常用MIPI,而車載屏用LVDS?

    為什么? 原因無非就是 MIPI 與 LVDS 兩者技術特性與應用場景結(jié)合的必然結(jié)果 。因此,要想知道為什么,直接對比兩者的技術特性以及兩種應用場景的特點就能得到結(jié)論。 技術特性對比 (1)LVDS 接口 最大優(yōu)點:抗干擾性極強,適配復雜電磁環(huán)境,中長距傳輸穩(wěn)定 采用低壓差
    的頭像 發(fā)表于 02-06 18:28 ?151次閱讀
    嵌入式分享#51:為什么手機屏常用MIPI,而車載屏用LVDS?

    這些都是電能電流參數(shù),你知道它們代表什么含義嗎?

    電能
    電幫主
    發(fā)布于 :2026年02月05日 11:37:32

    芯源的CRC硬件計算誰用過嗎?MCU的CRC你們喜歡用硬件的還是軟件的???

    芯源的CRC硬件計算誰用過嗎?MCU的CRC你們喜歡用硬件的還是軟件的???
    發(fā)表于 12-01 08:25

    大神們,想知道你們都用什么ide編程調(diào)試器? Arduino IDE?還是 e2studio ?還有其他嗎?哪個好用呢

    大神們,想知道你們都用什么ide編程調(diào)試器? Arduino IDE? 還是 e2studio ? 還有其他嗎? 哪個IDE好用呢? 求指點呀
    發(fā)表于 11-30 12:05

    高壓探棒和高壓差探頭有什么區(qū)別?

    我們在使用功率放大器放大信號,或是需要檢測信號的時候,可能都會用到這樣一個測試測量設備,那就是高壓探棒和高壓差探頭,那么你知道高壓探棒和高壓差探頭有什么區(qū)別嗎?一、高壓探棒和差
    的頭像 發(fā)表于 11-19 08:38 ?481次閱讀
    高壓探棒和高壓差<b class='flag-5'>分</b>探頭有什么區(qū)別?

    隔離地過孔放哪里,才能最有效減少高速信號過孔串擾?

    之后,到底地過孔放在哪個位置能最大程度的減小串擾哈!例如下面這個設計圖,兩對信號過孔位置固定后,怎么加地過孔的效果最好呢? 當然一些極端主義的朋友肯定第一時間跳出來,像下面那樣,我全部塞滿那肯定
    發(fā)表于 11-14 14:05

    隔離地過孔放哪里,才能最有效減少高速信號過孔串擾?

    通過這篇文章,你們能看到一些與你們想象不一樣的隔離地過孔的設計方式。。。
    的頭像 發(fā)表于 11-14 14:03 ?107次閱讀
    隔離地過孔<b class='flag-5'>要</b>放哪里,才能最有效減少高速信號過孔串擾?

    TI DMD代碼

    最近開發(fā)DLPLCRC410EVM,想問問大家有沒示例HDL代碼,最好是verilog代碼,從翻網(wǎng)頁也發(fā)現(xiàn)實際上是有的,但是不知道為啥官網(wǎng)沒有下載代碼的地方,求求
    發(fā)表于 09-29 17:40

    萬用應用經(jīng)驗

    電阻檔,指針的表筆輸出電流相對數(shù)字表來說大很多,用R×1Ω檔可以使揚聲器發(fā)出響亮的“噠”聲,用R×10kΩ檔甚至可以點亮發(fā)光二極管(LED)。 3、在電壓檔,指針內(nèi)阻相對數(shù)字表來說比較小,測量
    發(fā)表于 06-09 17:47

    PCB設計仿真,“縫合電容”我怎么可能不知道

    說到“縫合電容”,雖然我已經(jīng)聽你們說過800多遍了,但是還是忍不住問一個很簡單的問題:額,它到底是啥。。。
    的頭像 發(fā)表于 04-28 15:43 ?620次閱讀
    PCB設計仿真,“縫合電容”我怎么可能不<b class='flag-5'>知道</b>

    驅(qū)動板響應時間的測量方法

    你們知道的是驅(qū)動板的響應時間到底應該如何測量?今天我們就來探討一下新的驅(qū)動板知識。
    的頭像 發(fā)表于 03-13 17:12 ?1367次閱讀

    搞SD卡log打印功能時,打印出來的每條指令后面不知道為啥會帶[0m后綴?

    搞SD卡log打印功能時,打印出來的每條指令后面不知道為啥會帶[0m后綴,如圖所示: 哪位大佬教一下怎么去
    發(fā)表于 03-12 06:17