自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

分庫(kù)分表,讀寫分離后,數(shù)據(jù)庫(kù)中間件扮演了一個(gè)怎樣的角色?

數(shù)據(jù)庫(kù) MySQL
前面一篇文章圖解分布式系統(tǒng)架構(gòu)(看推薦閱讀)大概講了一下分庫(kù)分表,以及讀寫分離出現(xiàn)的場(chǎng)景,分庫(kù)分表為了解決高并發(fā)和海量數(shù)據(jù)的問(wèn)題。

分庫(kù)分表,讀寫分離會(huì)帶來(lái)哪些問(wèn)題?

前面一篇文章圖解分布式系統(tǒng)架構(gòu)(看推薦閱讀)大概講了一下分庫(kù)分表,以及讀寫分離出現(xiàn)的場(chǎng)景,分庫(kù)分表為了解決高并發(fā)和海量數(shù)據(jù)的問(wèn)題。

分庫(kù)后會(huì)出現(xiàn)新的問(wèn)題

1、跨庫(kù)join問(wèn)題

如有2個(gè)庫(kù),訂單庫(kù),用戶庫(kù),要查詢買了某件商品的所有用戶信息

2、事務(wù)問(wèn)題

用戶下訂單的時(shí)候需要扣減商品庫(kù)存,如果訂單數(shù)據(jù)和商品數(shù)據(jù)在一個(gè)數(shù)據(jù)庫(kù)中,我們可以使用事務(wù)來(lái)保證扣減商品庫(kù)存和生成訂單的操作要么都成功要么都失敗,但分庫(kù)后就無(wú)法使用數(shù)據(jù)庫(kù)事務(wù)了,這時(shí)就要用到分布式事務(wù)了

分表后也會(huì)出現(xiàn)新的問(wèn)題

1、join操作

水平分表后,數(shù)據(jù)分散在多個(gè)表中,如果需要與其他表進(jìn)行join查詢,需要在業(yè)務(wù)代碼或數(shù)據(jù)庫(kù)中間件中進(jìn)行多次join查詢,然后將結(jié)果合并

2、count()操作

業(yè)務(wù)代碼或者數(shù)據(jù)庫(kù)中間件對(duì)每個(gè)表進(jìn)行count(*)操作,然后將結(jié)果相加?;蛘咝陆ㄒ粡埍?,假如表名為“記錄數(shù)表”,包含table_name和row_count兩個(gè)字段,每次插入或刪除子表數(shù)據(jù)成功后,都更新“記錄數(shù)表”

3、order by操作

水平分表后,數(shù)據(jù)分散到多個(gè)字表中,排序操作無(wú)法再數(shù)據(jù)庫(kù)中完成,只能由業(yè)務(wù)代碼或數(shù)據(jù)庫(kù)中間件分別查詢每個(gè)子表中的數(shù)據(jù),然后匯總進(jìn)行排序

而高并發(fā)這個(gè)階段,肯定是需要做讀寫分離的,啥意思?因?yàn)閷?shí)際上大部分的互聯(lián)網(wǎng)公司,一些網(wǎng)站,或者是 app,其實(shí)都是讀多寫少。所以針對(duì)這個(gè)情況,就是寫一個(gè)主庫(kù),但是主庫(kù)掛多個(gè)從庫(kù),然后從多個(gè)從庫(kù)來(lái)讀,那不就可以支撐更高的讀并發(fā)壓力了嗎?

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

其實(shí)很簡(jiǎn)單,就是基于主從復(fù)制架構(gòu),簡(jiǎn)單來(lái)說(shuō),就搞一個(gè)主庫(kù),掛多個(gè)從庫(kù),然后我們就單單只是寫主庫(kù),然后從庫(kù)讀取bin log進(jìn)行重放,這樣主庫(kù)和從庫(kù)數(shù)據(jù)就一樣,只不過(guò)并發(fā)量比較高時(shí),會(huì)有主從同步延時(shí)問(wèn)題

放個(gè)圖理解一下MySQL主從復(fù)制的原理,這塊面試經(jīng)常被問(wèn)到

總的來(lái)說(shuō),MySQL復(fù)制有三個(gè)步驟

1、在主庫(kù)上把數(shù)據(jù)更改記錄到二進(jìn)制日志中(Binary Log)中(這些記錄被稱為二進(jìn)制日志事件)

2、備庫(kù)將主庫(kù)上的日志復(fù)制到自己的中繼日志(Relay Log)中

3、備庫(kù)讀取中繼日志中的事件,將其重放到備庫(kù)數(shù)據(jù)之上

現(xiàn)在理論知識(shí)都有了,就剩怎么實(shí)現(xiàn)了?本來(lái)就是為了實(shí)現(xiàn)一個(gè)功能,現(xiàn)在好了,單寫讀寫分離,跨庫(kù)join,分布式事務(wù),排序操作等就夠你忙的了。

這時(shí)候你就應(yīng)該想起數(shù)據(jù)庫(kù)中間件了,它能幫你進(jìn)行上述操作,把你從復(fù)雜的數(shù)據(jù)處理中解放出來(lái),專注于開(kāi)發(fā)業(yè)務(wù)代碼。

數(shù)據(jù)庫(kù)中間件能幫你做什么?

目前國(guó)內(nèi)用的最多的中間件就是sharding-jdbc,mycat,別的用的很少,不再介紹

而數(shù)據(jù)庫(kù)中間件針對(duì)數(shù)據(jù)源管理,目前主要有兩種思路

1、客戶端模式,在每個(gè)應(yīng)用程序模塊中配置管理自己需要的一個(gè)(或者多個(gè))數(shù)據(jù)源,直接訪問(wèn)各個(gè)數(shù)據(jù)庫(kù),在模塊內(nèi)完成數(shù)據(jù)的整合,sharding-jdbc的實(shí)現(xiàn)方式

2、通過(guò)中間代理層來(lái)統(tǒng)一管理所有的數(shù)據(jù)源,后端數(shù)據(jù)庫(kù)集群對(duì)前端應(yīng)用程序透明,mycat的實(shí)現(xiàn)方式

放兩張圖就能理解區(qū)別了

一般的建議是小公司用sharding-jdbc,大公司用mycat,因?yàn)榫S護(hù)一套mycat集群也需要人力,物力。鑒于篇幅限制,本文就介紹一下mycat的基本使用

以一個(gè)最形象的例子,讓你明白mycat到底幫你做了什么?

先介紹一下什么是分片?簡(jiǎn)單來(lái)說(shuō),就是通過(guò)某種特定的條件,將我們存放在同一個(gè)數(shù)據(jù)庫(kù)中的數(shù)據(jù),分散存放到多個(gè)數(shù)據(jù)庫(kù)上面,以達(dá)到分散單臺(tái)設(shè)備負(fù)載的效果

如上圖所表示,數(shù)據(jù)被分到多個(gè)分片數(shù)據(jù)庫(kù)后,應(yīng)用如果需要讀取數(shù)據(jù),就要需要處理多個(gè)數(shù)據(jù)源的數(shù)據(jù)。如果沒(méi)有數(shù)據(jù)庫(kù)中間件,那么應(yīng)用將直接面對(duì)分片集群,數(shù)據(jù)源切換、事務(wù)處理、數(shù)據(jù)聚合都需要應(yīng)用直接處理,原本該是專注于業(yè)務(wù)的應(yīng)用,將會(huì)花大量的工作來(lái)處理分片后的問(wèn)題,最重要的是每個(gè)應(yīng)用處理將是完全的重復(fù)造輪子。

所以有了數(shù)據(jù)庫(kù)中間件,應(yīng)用只需要集中與業(yè)務(wù)處理,大量的通用的數(shù)據(jù)聚合,事務(wù),數(shù)據(jù)源切換都由中間件來(lái)處理。

那么數(shù)據(jù)庫(kù)中間件是怎么做到的呢?

綠色的部分為mycat的邏輯節(jié)點(diǎn),藍(lán)色的部分為物理節(jié)點(diǎn)(即數(shù)據(jù)庫(kù)的部署地址)

schema:邏輯庫(kù)

通常對(duì)實(shí)際應(yīng)用來(lái)說(shuō),并不需要知道中間件的存在,業(yè)務(wù)開(kāi)發(fā)人員只需要知道

數(shù)據(jù)庫(kù)的概念,所以數(shù)據(jù)庫(kù)中間件可以被看做是一個(gè)或多個(gè)數(shù)據(jù)庫(kù)集群構(gòu)成的邏輯庫(kù)

table:邏輯表

既然有邏輯庫(kù),那么就會(huì)有邏輯表,分布式數(shù)據(jù)庫(kù)中,對(duì)應(yīng)用來(lái)說(shuō),讀寫數(shù)據(jù)的表就是邏輯表。邏輯表,可以是數(shù)據(jù)切分后,分布在一個(gè)或多個(gè)分片庫(kù)中,也可以不做數(shù)據(jù)切分,不分片,只有一個(gè)表構(gòu)成

datanode:分片節(jié)點(diǎn)

數(shù)據(jù)切分后,一個(gè)大表被分到不同的分片數(shù)據(jù)庫(kù)上面,每個(gè)表分片所在的數(shù)據(jù)庫(kù)就是分片節(jié)點(diǎn)

datahost:節(jié)點(diǎn)主機(jī)(上圖藍(lán)色節(jié)點(diǎn))

數(shù)據(jù)切分后,每個(gè)分片節(jié)點(diǎn)(dataNode)不一定都會(huì)獨(dú)占一臺(tái)機(jī)器,同一機(jī)器上面可以有多個(gè)分片數(shù)據(jù)庫(kù),這樣一個(gè)或多個(gè)分片節(jié)點(diǎn)(dataNode)所在的機(jī)器就是節(jié)點(diǎn)主機(jī)(dataHost),為了規(guī)避單節(jié)點(diǎn)主機(jī)并發(fā)數(shù)限制,盡量將讀寫壓力高的分片節(jié)點(diǎn)(dataNode)均衡的放在不同的節(jié)點(diǎn)主機(jī)(dataHost)。

rule:分片規(guī)則

前面講了數(shù)據(jù)切分,一個(gè)大表被分成若干個(gè)分片表,就需要一定的規(guī)則,這樣按照某種業(yè)務(wù)規(guī)則把數(shù)據(jù)分到某個(gè)分片的規(guī)則就是分片規(guī)則,數(shù)據(jù)切分選擇合適的分片規(guī)則非常重要,將極大的避免后續(xù)數(shù)據(jù)處理的難度。

實(shí)戰(zhàn)Mycat

為了快速熟悉各種配置,一般直接從git上下載代碼,本地用idea打開(kāi)啟動(dòng),方便練習(xí)一波,小編演示本文就是用的這種方法

mycat的配置其實(shí)是蠻簡(jiǎn)單的,最主要的是熟悉各配置文件的規(guī)則。如用戶名,密碼,分片規(guī)則,都是在配置文件中定義的

關(guān)于配置文件,conf目錄下主要以下三個(gè)需要熟悉,要是本地測(cè)試用idea打開(kāi)在resources目錄下

小編演示一個(gè)最簡(jiǎn)單的映射配置,找一個(gè)數(shù)據(jù)庫(kù)服務(wù)器,建立3個(gè)庫(kù),db1,db2,db3,把id為0-500 0000的數(shù)據(jù)放在db1,id為500 0001到1000 0000的數(shù)據(jù)放在db2,以此類推

server.xml是Mycat服務(wù)器參數(shù)調(diào)整和用戶授權(quán)的配置文件(省略了一些配置,后面2個(gè)配置文件一樣) 

  1. <mycat:server xmlns:mycat="http://io.mycat/">  
  2.     <user name="root" defaultAccount="true">  
  3.         <property name="password">123456</property>  
  4.         <property name="schemas">TESTDB</property>  
  5.     </user>  
  6. </mycat:server> 

schema.xml是邏輯庫(kù),邏輯表定義以及分片定義的配置文件 

  1. <mycat:schema xmlns:mycat="http://io.mycat/">  
  2.     <!--邏輯庫(kù)名-->  
  3.     <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100">  
  4.        <!--rule的值和rule.xml的實(shí)現(xiàn)對(duì)應(yīng)-->  
  5.         <table name="tb_test" dataNode="dn1,dn2,dn3" rule="auto-sharding-long" />  
  6.     </schema>  
  7.     <!--dataHost可以配置不同主機(jī)上的數(shù)據(jù)庫(kù),這里為了演示就配置了一個(gè)主機(jī)上的不同數(shù)據(jù)庫(kù)-->  
  8.     <dataNode name="dn1" dataHost="localhost1" database="db1" />  
  9.     <dataNode name="dn2" dataHost="localhost1" database="db2" />  
  10.     <dataNode name="dn3" dataHost="localhost1" database="db3" />  
  11.     <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0"  
  12.               writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">  
  13.         <!--心跳語(yǔ)句-->  
  14.         <heartbeat>select user()</heartbeat>  
  15.         <!--這里我本地mycat配了一個(gè)遠(yuǎn)程mysql-->  
  16.         <writeHost host="hostM1" url="遠(yuǎn)程mysql的ip地址:3306" user="root"  
  17.                    password="2014">  
  18.         </writeHost>  
  19.     </dataHost>  
  20. </mycat:schema> 

rule.xml是分片規(guī)則的配置文件 

  1. <mycat:rule xmlns:mycat="http://io.mycat/">  
  2.     <tableRule name="auto-sharding-long">  
  3.         <rule>  
  4.             <!--根據(jù)哪個(gè)列進(jìn)行分片-->  
  5.             <columns>id</columns>  
  6.             <!--分片規(guī)則,連續(xù)分片-->  
  7.             <algorithm>rang-long</algorithm>  
  8.         </rule>  
  9.     </tableRule>  
  10.     <function name="rang-long"  
  11.        <!--分片規(guī)則的實(shí)現(xiàn)類-->  
  12.         class="io.mycat.route.function.AutoPartitionByLong">  
  13.         <!--分片規(guī)則配置文件-->  
  14.         <property name="mapFile">autopartition-long.txt</property>  
  15.     </function>  
  16. </mycat:rule> 

autopartition-long.txt詳細(xì)的分片策略 

  1. # range start-end ,data node index  
  2. K=1000,M=10000 
  3. 00-500M=0  
  4. 500M-1000M=1  
  5. 1000M-1500M=2 

這個(gè)配置的意思是,id在0到500w放在***個(gè)分片,以此類推

小編這里用Navicat(數(shù)據(jù)庫(kù)連接工具)連接到本地的mycat

主機(jī):localhost

端口:8066

用戶名:root(server.xml中配置好的用戶名密碼)

密碼:123456

看到有一個(gè)TestDB庫(kù),在這個(gè)庫(kù)里面執(zhí)行建表語(yǔ)句 

  1. CREATE TABLE `tb_test` (  
  2.   `id` int(11) NOT NULL,  
  3.   `name` varchar(255) DEFAULT NULL,  
  4.   PRIMARY KEY (`id`)  
  5. ENGINE=InnoDB DEFAULT CHARSET=utf8mb4

然后到對(duì)應(yīng)的物理數(shù)據(jù)庫(kù)db1,db2,db3上看,3個(gè)庫(kù)都有了這個(gè)表。

在邏輯數(shù)據(jù)庫(kù)中插入如下三條數(shù)據(jù) 

  1. insert into tb_test (id, name) values (1, "1");  
  2. insert into tb_test (id, name) values (5000001, "5000001");  
  3. insert into tb_test (id, name) values (10000001, "10000001"); 

可以看到id為1的數(shù)據(jù)插入到物理數(shù)據(jù)庫(kù)中的db1,id為5000001的數(shù)據(jù)插入到db2,id為10000001的數(shù)據(jù)插入到db3

在邏輯數(shù)據(jù)庫(kù)中執(zhí)行如下語(yǔ)句又能拿到這3條記錄 

  1. select id, name from tb_test 

執(zhí)行如下語(yǔ)句,可以看到mycat從三個(gè)數(shù)據(jù)庫(kù)中取了記錄,LIMIT 100是因?yàn)閟chema.xml中配置了sqlMaxLimit=“100” 

  1. explain select id, name from tb_test 

有了mycat以后,我們的數(shù)據(jù)庫(kù)地址配置成mycat即可,它幫我們做了很多,其他各種分片規(guī)則,讀寫分離等的配置就不再演示,理解整個(gè)框架的大概運(yùn)行流程就行

***再分享一個(gè)知識(shí)點(diǎn),mycat1.5 開(kāi)始會(huì)支持本地 xml 啟動(dòng),以及從 zookeeper 加載配置轉(zhuǎn)為本地 xml 的兩種方式,即原來(lái)分享的zookeeper可以用作配置中心 

責(zé)任編輯:龐桂玉 來(lái)源: 數(shù)據(jù)庫(kù)開(kāi)發(fā)
相關(guān)推薦

2022-12-05 07:51:24

數(shù)據(jù)庫(kù)分庫(kù)分表讀寫分離

2018-02-24 19:37:33

Java8數(shù)據(jù)庫(kù)中間件

2021-05-08 18:50:57

分庫(kù)分表中間件

2020-01-03 16:30:14

數(shù)據(jù)庫(kù)讀寫分離分庫(kù)

2019-01-16 14:00:54

數(shù)據(jù)庫(kù)分庫(kù)分表

2020-04-10 17:00:33

Mycat分庫(kù)分表SpringBoot

2023-03-10 18:20:07

客戶端開(kāi)源中間件

2019-05-13 15:00:14

MySQLMyCat數(shù)據(jù)庫(kù)

2017-12-01 05:04:32

數(shù)據(jù)庫(kù)中間件Atlas

2017-11-27 05:36:16

數(shù)據(jù)庫(kù)中間件TDDL

2017-11-27 05:06:42

數(shù)據(jù)庫(kù)中間件cobar

2020-11-06 15:30:23

分庫(kù)分表Sharding-JD數(shù)據(jù)庫(kù)

2017-07-18 17:07:40

數(shù)據(jù)庫(kù) MyCATJoin

2022-04-08 09:23:50

數(shù)據(jù)管理區(qū)塊鏈大數(shù)據(jù)

2024-12-04 13:02:34

數(shù)據(jù)庫(kù)分庫(kù)分表

2011-08-10 13:03:58

CJDBC數(shù)據(jù)庫(kù)集群

2022-06-15 07:32:24

數(shù)據(jù)庫(kù)分庫(kù)分表

2017-05-23 18:55:05

mysql-proxy數(shù)據(jù)庫(kù)架構(gòu)

2024-08-02 15:47:28

數(shù)據(jù)庫(kù)分庫(kù)分表

2017-12-11 13:30:49

Go語(yǔ)言數(shù)據(jù)庫(kù)中間件
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)