不信你看看,MySQL分庫分表沒有那麼難

2021-01-08 騰訊網

資料庫分庫分表估計很多夥伴都沒有實踐過,就是因為自己公司的業務不是很多,沒有那麼多數據。假如有一天項目的人數上來了,你寫的系統支撐不住了,希望這篇文章帶給你一絲絲的思路。

前言

在面試過程中你是不是會經常遇到對於資料庫分庫分表你有什麼方案啊!

在平時看博客時你是不是也經常刷到MySQL如何分庫分表。

然而你是不是點進去看了不到10秒就直接退出窗口。

那是因為寫的文章不是什麼水平切分,就是垂直切割,在一個自身所在的公司根本使用不到。

如果你只知道分庫分表但是不知道怎麼弄的話,花個五分鐘看完你會收穫到不一樣的思路。

一、初始架構

公司的規模小,項目針對的用戶群體屬於小眾。日活就幾千、幾萬的用戶這樣的數據每天的資料庫單表增加一般不會超過10萬。並發更不沾邊了。

這種項目規模,我們就是認真、快速開發業務邏輯,提升用戶體驗,從而提升項目的用戶粘度並達到收納更多用戶的準備。

這個時候我們項目一臺16核32G的伺服器就完全可以了,可以將資料庫單獨放一個伺服器,也可以都放在一個伺服器。

這個時候項目架構圖是這個樣子的。

二、用戶開始激增解決方案

在經歷了第一階段後,由於項目的用戶體驗度極高,項目又吸引了大量的用戶。

這時我們項目日活達到了百萬級別,註冊用戶也超過了千萬。這個數據是咔咔根據之前公司項目數據推算的。

這時每天單表數據新增達到了100萬,並發請求每秒也達到了上萬。這時單系統就扛不住了。

假設每天就固定新增100萬,每月就是3000萬 ,一年就是接近5億數據。

資料庫以這種速度運行下去,數據到2000W到3000W還能勉強撐住,但是你會發現資料庫日誌會出現越來越多的慢查詢。

雖說並發1W,但是我們可以部署個10臺機器或者20臺機器,平均每臺機器承擔500到1000的請求,還是綽綽有餘的。

但是資料庫方面還是用一臺伺服器支撐著每秒上萬的請求,那麼你將會遇到以下問題。

資料庫所在的伺服器磁碟IO、網絡帶寬、CPU負載、內存消耗都會非常高

單表數據已經很大,SQL性能已經已經出現下坡階段,加上資料庫伺服器負載太高導致性能下降,會直接導致SQL性能更差

這個時候最明顯的感覺,就是用戶獲取一個數據可能需要10s以上的時間才會返回。

如果前期伺服器配置不是很高的話,你就會面臨資料庫宕機的情況

那麼這個時候我們要怎麼對項目進行架構的優化呢!

根據大佬們的經驗是資料庫的連接數每秒控制在2000即可、那麼我們1W並發的情況下部署5臺機器,每臺機器都部署一個同樣結構的資料庫。

此時在5臺資料庫擁有同樣的資料庫。表名規則可以這樣設置。

這時每個project庫都有一個相同的表,比如db_project1有tb_play_recode1、db_project2有tb_play_recode2......

這樣就實現了一個基本的分庫分表的思路,從原來一臺資料庫伺服器變成了5臺資料庫伺服器,從原來一個庫變成了5個庫,原來的一張表變成了5張表。

這時我們就需要藉助資料庫中間件來完成寫數據,例如mycat。

這個時候就需要使用播放記錄表的自增ID進行取模5,比如每天播放記錄新增100W數據。此時20W數據會落到db_project1的db_play_recode1,其它的四個庫分別也會落入20W數據。

查詢數據時就根據播放記錄的自增ID進行取模5,就可以去對應的資料庫,從對應的表裡查詢數據即可。

實現了這個架構後,我們再來分析一下。

原來播放記錄就一張表,現在變成了5張表,那麼每個表就變成了1/5

按照原項目的推算,一年如有1億數據,每張表就只有2000w數據。

按照每天新增50W數據,每張表每天新增10W數據,這樣是不是就初步緩解了單表數據量過大影響系統性能問題了。

另外每秒1W的請求,這時每臺伺服器平均就2000,瞬間就把並發請求降低到了安全範圍了。

三、保證查詢性能

在上邊的資料庫架構會遇到一個問題,就是單表數據量還是很大,按照每年1億的數據,單表就會有2000W數據,還是太大了。

比如可以將播放記錄表拆分為100張表,然後分散到5臺資料庫伺服器,這時單表的數據就只有100W,那查詢起來還不是灑灑水的啦!

在寫數據時就需要經過倆次路由,先對播放記錄ID取模資料庫數量,這時可以路由到一臺資料庫上,然後再對那臺資料庫上的表數量進行取模,最終就會路由到數據上的一個表裡了。

通過這個步驟就可以讓每個表的數據都非常少,按照100張表,1億數據,落到每個表的數據就只有100W。

這時的系統架構是這個樣子的。

四、配置讀寫分離來按需擴容

以上的架構整體效果已經很不錯了,假設上邊分了100張表還是不滿足需求,可以通過用戶增量計算來配置合理的表。同時還可以保證單表內的SQL執行效率。

這時還會遇到一個問題,假如每臺伺服器承載每秒2000的請求,其中就400是寫入,1600是查詢。

也就是說,增刪改查中增刪改的SQL才佔到了20%的比例,80%的請求都是查詢。

安裝之前的推理,現在所有數據進行翻倍計算,每臺伺服器並發達到了4000請求了。

那麼其中800請求是寫入,3200請求是查詢,如果說安裝目前的情況來擴容,就只需要增加一臺資料庫伺服器即可。但是就會涉及到表的遷移,因為需要遷移一部分表到新的資料庫上,那是很麻煩的事情了。

其實沒有這個必要的,可以使用讀寫分離來解決這個問題,也就是主從複製。

寫的時候走主庫,讀數據時走從庫,這樣就可以讓一個表的讀寫請求分開落到不同的資料庫上去執行。

這樣的設計後,我們在推算一下,假如寫入主庫的請求是400/s ,查詢從庫的請求是就是1800/s,只需要在主庫下配置倆臺從庫即可。

這時的架構是如下的。

實際的生產環境,讀請求的增長速度遠遠高於寫的請求,所以讀寫分離之後,大部分就是擴容從庫支撐更高的讀請求就可以了。

而且另外一個點,對同一個表,如果既寫數據,還讀數據,可能會牽扯到鎖衝突問題,無論讀還是寫性能都會有影響。

所以一旦讀寫分離之後,對主庫的表就僅僅是寫入,沒任何查詢會影響主庫。對從庫就僅僅是查詢了。

五、並發資料庫結構總結

關於並發場景下,資料庫層面的架構是需要進行精心的設計的。

並且在配置主複製時,也會有很多的問題來等著去解決。

本文就是從一個大的角度來梳理一個思路給大家,可以根據自己公司的業務和項目來考慮自己的系統如何分庫分表。

分庫分表的落地需要藉助mycat或者其他資料庫中間件來實現。

這幾天就會再出一篇文章對於本文的一個實現,並且還有很多問題等著去解決。

例如:自增ID問題,主從複製數據不一致問題,在主從複製這塊很多問題,作為程式設計師的我們就是需要不停的打boos獲得最終的勝利。

堅持學習、堅持寫博、堅持分享是咔咔從業以來一直所秉持的信念。希望在偌大網際網路中咔咔的文章能帶給你一絲絲幫助。

相關焦點

  • MyCat分庫分表策略詳解
    常見的分庫分表方式有兩種:客戶端模式和伺服器模式,這兩種的典型代表有sharding-jdbc和MyCat。        作為服務端模式的典型代表,MyCat不僅提供了豐富的分庫分表策略,也提供了非常靈活的讀寫分離策略,並且其對客戶端的侵入性是非常小的。本文主要講解MyCat主要提供的分庫分表策略,並且還會講解MyCat如果自定義分庫分表策略。1. 配置格式介紹        在講解MyCat分庫分表策略之前,我們首先介紹一下其配置文件的格式。
  • 面試官:「談談分庫分表吧?」
    應聘者:「前後端分離啊,限流啊,分庫分表啊。。」 面試官:"談談分庫分表吧?" 應聘者:「bala。bala。bala。。」,如果你的id是自增的,而且能保證在進行分庫分表後也是自增的,那麼能進行很好的改造,以id大小水平切分,而且極有可能不用遷移數據。
  • 基於代理的資料庫分庫分表框架 Mycat實踐
    概 述在如今海量數據充斥的網際網路環境下,分庫分表的意義我想在此處就不用贅述了。而分庫分表目前流行的方案最起碼有兩種:方案一:基於應用層的分片,即應用層代碼直接完成分片邏輯方案二:基於代理層的分片,即在應用代碼和底層資料庫中間添加一層代理層,而分片的路由規則則由代理層來進行處理而本文即將要實驗的 MyCAT框架就屬於第二種方案的代表作品。
  • 海量數據,Mysql分庫分表存儲麻煩,試試阿里雲的tableStore?
    為啥要分庫分表你在一個創業型小公司做架構師,做的是電商項目,剛開始註冊人數就幾萬而已,交易最多每天就幾百單數據生成,這種情況下不用分庫分表沒問題的。後面公司項目發展越來越快,用戶活躍數幾十萬,訂單生成數一天幾百萬,這個時候你的資料庫伺服器明顯的扛不住的,單表的數據太多,磁碟資源有限,一系列的壓力最終會導致系統無法使用。這個時候架構師應該想到的是要進行業務劃分,使用sharding-jdbc、mycat進行分庫分表存儲海量的數據。這個是能解決上述的問題的,但是往往不是那麼簡單。
  • MySql DAL中間件總結
    來源:民工哥技術之路ID:jishuroad作者:西門飛冰1.前言mysql作為網際網路公司都會用到的資料庫,如果在使用過程中出現性能問題,會採用mysql的橫向擴展,使用主從複製來提高讀性能,要是解決寫入問題,需要進行分庫分表。
  • 可以不會,不能不知的SpringBoot+Sharding-JDBC分庫分表項目實戰
    你可以不會用,但你不能不知道,就是這麼一種現狀。技術名詞大多晦澀難懂,不要死記硬背理解最重要,當你捅破那層窗戶紙,發現其實它也就那麼回事。什麼是Sharding-JDBC在介紹Sharding-JDBC之前,我們需要先說明下Sharding-Sphere。
  • MySQL資料庫高可用集群搭建-PXC集群部署
    PXC的優點:1)服務高可用;2)數據同步複製(並發複製),幾乎無延遲;3)多個可同時讀寫節點,可實現寫擴展,不過最好事先進行分庫分表,讓各個節點分別寫不同的表或者庫,避免讓galera解決數據衝突;4)新節點可以自動部署,部署操作簡單;5)數據嚴格一致性,尤其適合電商類應用;6)完全兼容MySQL; 一些名詞介紹:WS:write set寫數據集,寫/更新事務IST:Incremental
  • 分庫分表 or NewSQL資料庫?終於看懂應該怎麼選-愛可生
    那麼NewSQL資料庫突破CAP定理限制了嗎?並沒有。分庫分表模式下需要應用設計之初就要明確各表的拆分鍵、拆分方式(range、取模、一致性哈希或者自定義路由表)、路由規則、拆分庫表數量、擴容方式等。相比NewSQL資料庫,這種模式給應用帶來了很大侵入和複雜度,這對大多數系統來說也是一大挑戰。
  • MyCat入門篇-使用案例2:垂直拆分(分庫)
    mycat入門篇配置垂直拆分(分庫)按業務模塊垂直拆分所謂的垂直拆分,就是指把不同業務模塊的表,分部放在不同的MySQL資料庫伺服器上。例如採用如下的拆分方式:訂單模塊的表放在一個MySQL伺服器上。物流模塊的表放在另外一個MySQL伺服器上。用戶模塊的表再放在另外一個MySQL伺服器上。這樣來實現不同業務模塊的表分別放在不同的MySQL實例上,來分攤整個資料庫的壓力。整體的這個概念就是把不同的模塊的表分開存放在不同的MySQL資料庫實例中,我們有時候也稱之為分庫的操作。
  • MySQL教程之MySQL資料庫優化小建議
    背景「那啥,你過來一下!」「怎麼了,我代碼都單元測試了的,沒出問題啊!」我一臉懵逼跑到運維大佬旁邊。「你看看!你看看!多少條報警,趕快優化一下!」運維大佬簡訊列表裡面好多MySQL CPU 100%報警簡訊。再看看項目名稱不就是我前幾天剛發布的項目嗎!?我心底一沉,趕快賠上笑臉。「這個一定優化,馬上優化!那個,能不能看下資料庫監控日誌...」運維大佬又數落了我幾句,然後調開了資料庫監控日誌。
  • 騰訊高工甩出MySQL速成手冊,基礎架構調優三飛
    大勢所趨之下不管你是軟體開發和資料庫管理人員都必須要搞懂MySQL!想要精通MySQL你就必須知道如何設計一個高可用可擴展的企業級MySQL資料庫集群以及高性能高可用MySQL調優方法。但大多數人對於MySQL的學習卻不知道如何入手,對MySQL也是知其然而不知其所以然,那麼怎麼學?不要這不還有網際網路雷鋒(小編我)嘛!今天要與大家介紹的文檔出自一位騰訊高工。
  • MySQL系列二 - 搭建MySQL主從集群
    MySQL系列一 - MySQL安裝軟體環境CentOS 7MySQL5.7虛擬機IP: 192.168.64.123 (Master) / 192.168.64.124 (Slave)環境搭建主節點配置 修改 /etc/my.cnf文件,文件中添加修改後的my.cnf重啟MySQL, 重啟後在 /usr/local/mysql
  • 資料庫基礎:mysql主從集群搭建
    本文轉載自【微信公眾號:java架構師進階之路,ID:gh_a39b0d322dde】經微信公眾號授權轉載,如需轉載與原文作者聯繫前言:Mysql資料庫沒有增量備份的機制,當數據量太大的時候備份是一個很大的問題。還好mysql資料庫提供了一種主從備份的機制,其實就是把主資料庫的所有的數據同時寫到備份的資料庫中。實現mysql資料庫的熱備份。
  • PHP和MySQL開發的8個技巧
    >但是如果後面那個echo語句沒有雙引號引起來的話,就要報錯,因此建議使用花括號:$temp=array("one"=>1,"two"=>2);echo"Thefirstelementis{$temp["one"]}.";?
  • Mycat分庫分表核心技術分析
    NIOReactor新建的Thread,不斷循環將Queue中的SocketChannel取出並註冊到當前NIOReactor關聯的Selector上面;5) 不斷循環Selector返回的SelectionKey進行數據讀取;6) 從DirectByteBufferPoll中先分配一塊內存(trunk=4k);7) 讀取SocketChannel中的數據,如果一個trunk可以讀完數據則進行認證、mysql
  • 高性能Mysql主從架構的複製原理及配置詳解
    請注意當你進行複製時,所有對複製中的表的更新必須在主伺服器上進行。否則,你必須要小心,以避免用戶對主伺服器上的表進行的更新與對從伺服器上的表所進行的更新之間的衝突。mysql支持的複製類型:基於語句的複製:在主伺服器上執行的SQL語句,在從伺服器上執行同樣的語句。MySQL默認採用基於語句的複製,效率比較高。
  • MySQL中的各種自增ID
    也歡迎你分享給更多的朋友。背景MySQL中有各種各樣的自增ID。例如我們最常見的表的自增ID,Xid,事務的ID,線程的ID,表的編號ID,binlog日誌文件的ID等等。這些ID都是有它自己的增長規律的,並不是隨機生成的。MySQL的整體功能設計,有很多地方都依賴於這些ID的增長規律。