<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          螞蟻一面:談?wù)勀銓ψx寫分離以及分庫分表的理解,回答出這些應(yīng)該是...

          共 3766字,需瀏覽 8分鐘

           ·

          2021-03-25 18:31


          讀寫分離

          何為讀寫分離?

          見名思意,根據(jù)讀寫分離的名字,我們就可以知道:讀寫分離主要是為了將對數(shù)據(jù)庫的讀寫操作分散到不同的數(shù)據(jù)庫節(jié)點(diǎn)上。 這樣的話,就能夠小幅提升寫性能,大幅提升讀性能。

          我簡單畫了一張圖來幫助不太清楚讀寫分離的小伙伴理解。

          1fd0e5a3226e67dc0dbef65281535e2f.webp讀寫分離

          一般情況下,我們都會選擇一主多從,也就是一臺主數(shù)據(jù)庫負(fù)責(zé)寫,其他的從數(shù)據(jù)庫負(fù)責(zé)讀。主庫和從庫之間會進(jìn)行數(shù)據(jù)同步,以保證從庫中數(shù)據(jù)的準(zhǔn)確性。這樣的架構(gòu)實(shí)現(xiàn)起來比較簡單,并且也符合系統(tǒng)的寫少讀多的特點(diǎn)。

          讀寫分離會帶來什么問題?如何解決?

          讀寫分離對于提升數(shù)據(jù)庫的并發(fā)非常有效,但是,同時(shí)也會引來一個(gè)問題:主庫和從庫的數(shù)據(jù)存在延遲,比如你寫完主庫之后,主庫的數(shù)據(jù)同步到從庫是需要時(shí)間的,這個(gè)時(shí)間差就導(dǎo)致了主庫和從庫的數(shù)據(jù)不一致性問題。這也就是我們經(jīng)常說的 主從同步延遲 。

          主從同步延遲問題的解決,沒有特別好的一種方案(可能是我太菜了,歡迎評論區(qū)補(bǔ)充)。你可以根據(jù)自己的業(yè)務(wù)場景,參考一下下面幾種解決辦法。

          1.強(qiáng)制將讀請求路由到主庫處理。

          既然你從庫的數(shù)據(jù)過期了,那我就直接從主庫讀取嘛!這種方案雖然會增加主庫的壓力,但是,實(shí)現(xiàn)起來比較簡單,也是我了解到的使用最多的一種方式。

          比如 Sharding-JDBC 就是采用的這種方案。通過使用 Sharding-JDBC 的 HintManager 分片鍵值管理器,我們可以強(qiáng)制使用主庫。

          HintManager?hintManager?=?HintManager.getInstance();
          hintManager.setMasterRouteOnly();
          //?繼續(xù)JDBC操作

          對于這種方案,你可以將那些必須獲取最新數(shù)據(jù)的讀請求都交給主庫處理。

          2.延遲讀取。

          還有一些朋友肯定會想既然主從同步存在延遲,那我就在延遲之后讀取啊,比如主從同步延遲 0.5s,那我就 1s 之后再讀取數(shù)據(jù)。這樣多方便?。》奖闶欠奖?,但是也很扯淡。

          不過,如果你是這樣設(shè)計(jì)業(yè)務(wù)流程就會好很多:對于一些對數(shù)據(jù)比較敏感的場景,你可以在完成寫請求之后,避免立即進(jìn)行請求操作。比如你支付成功之后,跳轉(zhuǎn)到一個(gè)支付成功的頁面,當(dāng)你點(diǎn)擊返回之后才返回自己的賬戶。

          另外,《MySQL 實(shí)戰(zhàn) 45 講》[1]這個(gè)專欄中的《讀寫分離有哪些坑?》[2]這篇文章還介紹了很多其他比較實(shí)際的解決辦法,感興趣的小伙伴可以自行研究一下。

          如何實(shí)現(xiàn)讀寫分離?

          不論是使用哪一種讀寫分離具體的實(shí)現(xiàn)方案,想要實(shí)現(xiàn)讀寫分離一般包含如下幾步:

          1. 部署多臺數(shù)據(jù)庫,選擇一種的一臺作為主數(shù)據(jù)庫,其他的一臺或者多臺作為從數(shù)據(jù)庫。
          2. 保證主數(shù)據(jù)庫和從數(shù)據(jù)庫之間的數(shù)據(jù)是實(shí)時(shí)同步的。
          3. 系統(tǒng)將寫請求交給主數(shù)據(jù)庫處理,讀請求交給從數(shù)據(jù)庫處理。

          落實(shí)到項(xiàng)目本身的話,常用的方式有兩種:

          1.代理方式

          3f9b640db0081464c02baf4f529f2c01.webp讀寫分離-代理層

          我們可以在應(yīng)用和數(shù)據(jù)中間加了一個(gè)代理層。應(yīng)用程序所有的數(shù)據(jù)請求都交給代理層處理,代理層負(fù)責(zé)分離讀寫請求,將它們路由到對應(yīng)的數(shù)據(jù)庫中。

          提供類似功能的中間件有 MySQL Router(官方)、Atlas(基于 MySQL Proxy)、Maxscale、MyCat。

          2.組件方式

          在這種方式中,我們可以通過引入第三方組件來幫助我們讀寫請求。

          這也是我比較推薦的一種方式。這種方式目前在各種互聯(lián)網(wǎng)公司中用的最多的,相關(guān)的實(shí)際的案例也非常多。如果你要采用這種方式的話,推薦使用 sharding-jdbc ,直接引入 jar 包即可使用,非常方便。同時(shí),也節(jié)省了很多運(yùn)維的成本。

          你可以在 shardingsphere 官方找到sharding-jdbc 關(guān)于讀寫分離的操作[3]。

          分庫分表

          讀寫分離主要應(yīng)對的是數(shù)據(jù)庫讀并發(fā),沒有解決數(shù)據(jù)庫存儲問題。試想一下:如果 MySQL 一張表的數(shù)據(jù)量過大怎么辦?

          換言之,我們該如何解決 MySQL 的存儲壓力呢?

          答案之一就是 分庫分表。

          何為分庫?

          分庫 就是將數(shù)據(jù)庫中的數(shù)據(jù)分散到不同的數(shù)據(jù)庫上。

          下面這些操作都涉及到了分庫:

          • 你將數(shù)據(jù)庫中的用戶表和用戶訂單表分別放在兩個(gè)不同的數(shù)據(jù)庫。
          • 由于用戶表數(shù)據(jù)量太大,你對用戶表進(jìn)行了水品切分,然后將切分后的 2 張用戶表分別放在兩個(gè)不同的數(shù)據(jù)庫。

          何為分表?

          分表 就是對單表的數(shù)據(jù)進(jìn)行拆分,可以是垂直拆分,也可以是水平拆分。

          何為垂直拆分?

          簡單來說,垂直拆分是對數(shù)據(jù)表列的拆分,把一張列比較多的表拆分為多張表。

          舉個(gè)例子:我們可以將用戶信息表中的一些列單獨(dú)抽出來作為一個(gè)表。

          何為水平拆分?

          簡單來說,水平拆分是對數(shù)據(jù)表行的拆分,把一張行比較多的表拆分為多張表。

          舉個(gè)例子:我們可以將用戶信息表拆分成多個(gè)用戶信息表,這樣就可以避免單一表數(shù)據(jù)量過大對性能造成影響。

          《從零開始學(xué)架構(gòu)》[4] 中的有一張圖片對于垂直拆分和水平拆分的描述還挺直觀的。

          2d5c7ca734ee196bbbb23137877d3bd4.webp

          什么情況下需要分庫分表?

          遇到下面幾種場景可以考慮分庫分表:

          • 單表的數(shù)據(jù)達(dá)到千萬級別以上,數(shù)據(jù)庫讀寫速度比較緩慢(分表)。
          • 數(shù)據(jù)庫中的數(shù)據(jù)占用的空間越來越大,備份時(shí)間越來越長(分庫)。
          • 應(yīng)用的并發(fā)量太大(分庫)。

          分庫分表會帶來什么問題呢?

          記住,你在公司做的任何技術(shù)決策,不光是要考慮這個(gè)技術(shù)能不能滿足我們的要求,是否適合當(dāng)前業(yè)務(wù)場景,還要重點(diǎn)考慮其帶來的成本。

          引入分庫分表之后,會給系統(tǒng)帶來什么挑戰(zhàn)呢?

          • join 操作 :同一個(gè)數(shù)據(jù)庫中的表分布在了不同的數(shù)據(jù)庫中,導(dǎo)致無法使用 join 操作。這樣就導(dǎo)致我們需要手動進(jìn)行數(shù)據(jù)的封裝,比如你在一個(gè)數(shù)據(jù)庫中查詢到一個(gè)數(shù)據(jù)之后,再根據(jù)這個(gè)數(shù)據(jù)去另外一個(gè)數(shù)據(jù)庫中找對應(yīng)的數(shù)據(jù)。
          • 事務(wù)問題 :同一個(gè)數(shù)據(jù)庫中的表分布在了不同的數(shù)據(jù)庫中,如果單個(gè)操作涉及到多個(gè)數(shù)據(jù)庫,那么數(shù)據(jù)庫自帶的事務(wù)就無法滿足我們的要求了。
          • 分布式 id :分庫之后, 數(shù)據(jù)遍布在不同服務(wù)器上的數(shù)據(jù)庫,數(shù)據(jù)庫的自增主鍵已經(jīng)沒辦法滿足生成的主鍵唯一了。我們?nèi)绾螢椴煌臄?shù)據(jù)節(jié)點(diǎn)生成全局唯一主鍵呢?這個(gè)時(shí)候,我們就需要為我們的系統(tǒng)引入分布式 id 了。
          • ......

          另外,引入分庫分表之后,一般需要 DBA 的參與,同時(shí)還需要更多的數(shù)據(jù)庫服務(wù)器,這些都屬于成本。

          分庫分表有沒有什么比較推薦的方案?

          ShardingSphere 項(xiàng)目(包括 Sharding-JDBC、Sharding-Proxy 和 Sharding-Sidecar)是當(dāng)當(dāng)捐入 Apache 的,目前主要由京東數(shù)科的一些巨佬維護(hù)。

          72f5c3fe21aedf7e6e257470de104eea.webp

          ShardingSphere 絕對可以說是當(dāng)前分庫分表的首選!ShardingSphere 的功能完善,除了支持讀寫分離和分庫分表,還提供分布式事務(wù)、數(shù)據(jù)庫治理等功能。

          另外,ShardingSphere 的生態(tài)體系完善,社區(qū)活躍,文檔完善,更新和發(fā)布比較頻繁。

          艿艿之前寫了一篇分庫分表的實(shí)戰(zhàn)文章,各位朋友可以看看:《芋道 Spring Boot 分庫分表入門》 。

          除了分庫分表,還有其他方法么?

          另外的話,除了這分庫分表種解決方案之外,目前還有很多公司使用了目前比較火的一個(gè)開源的分布式關(guān)系型數(shù)據(jù)庫 TiDB

          對于,TiDB 來說根本不用擔(dān)心數(shù)據(jù)庫存儲壓力,可以為我們節(jié)省很多事情。

          并且,TiDB 天然支持水平擴(kuò)容或者縮容、金融級高可用,并且,兼容 MySQL 5.7 協(xié)議和 MySQL 生態(tài)。非常適合高可用、強(qiáng)一致要求較高、數(shù)據(jù)規(guī)模較大等各種應(yīng)用場景。

          相關(guān)閱讀:

          • 我們?yōu)槭裁捶艞?MongoDB 和 MySQL,選擇 TiDB?[5]
          • 神器 TiDE 在手,一鍵快速上車 TiDB - PingCAP[6]

          參考資料

          [1]

          《MySQL 實(shí)戰(zhàn) 45 講》: https://time.geekbang.org/column/intro/100020801?code=ieY8HeRSlDsFbuRtggbBQGxdTh-1jMASqEIeqzHAKrI%3D

          [2]

          《讀寫分離有哪些坑?》: https://time.geekbang.org/column/article/77636

          [3]

          sharding-jdbc 關(guān)于讀寫分離的操作: https://shardingsphere.apache.org/document/legacy/3.x/document/cn/manual/sharding-jdbc/usage/read-write-splitting/

          [4]

          《從零開始學(xué)架構(gòu)》: https://time.geekbang.org/column/intro/100006601?code=i00Nq3pHUcUj04ZWy70NCRl%2FD2Lfj8GVzcGzZ3Wf5Ug%3D

          [5]

          我們?yōu)槭裁捶艞?MongoDB 和 MySQL,選擇 TiDB?: https://juejin.im/post/6877727080675868679

          [6]

          神器 TiDE 在手,一鍵快速上車 TiDB - PingCAP: https://pingcap.com/blog-cn/-tide-in-tidb/


          怎么在Java中自定義注解?

          2021-03-15

          2a21393c4ac2ff625ae5d113d2aad780.webp

          再來工具篇,10個(gè)解放雙手實(shí)用在線工具

          2021-03-14

          71708f16f0201b6e49729917232eb20f.webp

          Java中的枚舉,一些不為人知的干貨都在這了

          2021-03-14

          0523a4f4898be373b93406782b373847.webp

          瀏覽 50
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評論
          圖片
          表情
          推薦
          點(diǎn)贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  亚洲丝袜性爱 | 国产又粗又长又硬免费视频 | 亚洲成人免费在线观看 | 黄色片视频网站 | 三级片在线观看中文字幕 |