mysql怎么制作分布式 mysql數(shù)據(jù)庫是分布式的嗎

MySQL大型分布式集群具體怎么做

1、主要解決針對大型網(wǎng)站架構(gòu)中持久化部分中,大量數(shù)據(jù)存儲以及高并發(fā)訪問所帶來是數(shù)據(jù)讀寫問題。分布式是將一個業(yè)務(wù)拆分為多個子業(yè)務(wù),部署在不同的服務(wù)器上。集群是同一個業(yè)務(wù),部署在多個服務(wù)器上。

喀喇沁網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián)公司,喀喇沁網(wǎng)站設(shè)計制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為喀喇沁成百上千提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\成都外貿(mào)網(wǎng)站建設(shè)公司要多少錢,請找那個售后服務(wù)好的喀喇沁做網(wǎng)站的公司定做!

2、著重對數(shù)據(jù)切分做了細(xì)致豐富的講解,從數(shù)據(jù)切分的原理出發(fā),一步一步深入理解數(shù)據(jù)的切分,通過深入理解各種切分策略來設(shè)計和優(yōu)化我們的系統(tǒng)。這部分中我們還用到了數(shù)據(jù)庫中間件和客戶端組件來進(jìn)行數(shù)據(jù)的切分,讓廣大網(wǎng)友能夠?qū)?shù)據(jù)的切分從理論到實(shí)戰(zhàn)都會有一個質(zhì)的飛躍。

通過分布式+集群的方式來提高io的吞吐量,以及數(shù)據(jù)庫的主從復(fù)制,主主復(fù)制,負(fù)載均衡,高可用,分庫分表以及數(shù)據(jù)庫中間件的使用。

教程樣例項(xiàng)目中用到的技術(shù)及相應(yīng)的環(huán)境:

MySQL5.7 CentOS6.9 Vmware Spring3.x以上 JDK8 Maven XShell Xftp

用 MySQL 實(shí)現(xiàn)分布式鎖,你聽過嗎?

以前參加過一個庫存系統(tǒng),由于其業(yè)務(wù)復(fù)雜性,搞了很多個應(yīng)用來支撐。這樣的話一份庫存數(shù)據(jù)就有可能同時有多個應(yīng)用來修改庫存數(shù)據(jù)。

比如說,有定時任務(wù)域xx.cron,和SystemA域和SystemB域這幾個JAVA應(yīng)用,可能同時修改同一份庫存數(shù)據(jù)。如果不做協(xié)調(diào)的話,就會有臟數(shù)據(jù)出現(xiàn)。

對于跨JAVA進(jìn)程的線程協(xié)調(diào),可以借助外部環(huán)境,例如DB或者Redis。下文介紹一下如何使用DB來實(shí)現(xiàn)分布式鎖。

本文設(shè)計的分布式鎖的交互方式如下:

在使用synchronized關(guān)鍵字的時候,必須指定一個鎖對象。

進(jìn)程內(nèi)的線程可以基于obj來實(shí)現(xiàn)同步。obj在這里可以理解為一個鎖對象。如果線程要進(jìn)入synchronized代碼塊里,必須先持有obj對象上的鎖。這種鎖是JAVA里面的內(nèi)置鎖,創(chuàng)建的過程是線程安全的。那么借助DB,如何保證創(chuàng)建鎖的過程是線程安全的呢?

可以利用DB中的UNIQUE KEY特性,一旦出現(xiàn)了重復(fù)的key,由于UNIQUE KEY的唯一性,會拋出異常的。在JAVA里面,是 SQLIntegrityConstraintViolationException 異常。

transaction_id是事務(wù)Id,比如說,可以用

來組裝一個transaction_id,表示某倉庫某銷售模式下的某個條碼資源。不同條碼,當(dāng)然就有不同的transaction_id。如果有兩個應(yīng)用,拿著相同的transaction_id來創(chuàng)建鎖資源的時候,只能有一個應(yīng)用創(chuàng)建成功。

在寫操作頻繁的業(yè)務(wù)系統(tǒng)中,通常會進(jìn)行分庫,以降低單數(shù)據(jù)庫寫入的壓力,并提高寫操作的吞吐量。如果使用了分庫,那么業(yè)務(wù)數(shù)據(jù)自然也都分配到各個數(shù)據(jù)庫上了。

在這種水平切分的多數(shù)據(jù)庫上使用DB分布式鎖,可以自定義一個DataSouce列表。并暴露一個 getConnection(String transactionId) 方法,按照transactionId找到對應(yīng)的Connection。

實(shí)現(xiàn)代碼如下:

首先編寫一個initDataSourceList方法,并利用Spring的PostConstruct注解初始化一個DataSource 列表。相關(guān)的DB配置從db.properties讀取。

DataSource使用阿里的DruidDataSource。

接著最重要的一個實(shí)現(xiàn)getConnection(String transactionId)方法。實(shí)現(xiàn)原理很簡單,獲取transactionId的hashcode,并對DataSource的長度取模即可。

連接池列表設(shè)計好后,就可以實(shí)現(xiàn)往distributed_lock表插入數(shù)據(jù)了。

接下來利用DB的 select for update 特性來鎖住線程。當(dāng)多個線程根據(jù)相同的transactionId并發(fā)同時操作 select for update 的時候,只有一個線程能成功,其他線程都block住,直到 select for update 成功的線程使用commit操作后,block住的所有線程的其中一個線程才能開始干活。

我們在上面的DistributedLock類中創(chuàng)建一個lock方法。

當(dāng)線程執(zhí)行完任務(wù)后,必須手動的執(zhí)行解鎖操作,之前被鎖住的線程才能繼續(xù)干活。在我們上面的實(shí)現(xiàn)中,其實(shí)就是獲取到當(dāng)時 select for update 成功的線程對應(yīng)的Connection,并實(shí)行commit操作即可。

那么如何獲取到呢?我們可以利用ThreadLocal。首先在DistributedLock類中定義

每次調(diào)用lock方法的時候,把Connection放置到ThreadLocal里面。我們修改lock方法。

這樣子,當(dāng)獲取到Connection后,將其設(shè)置到ThreadLocal中,如果lock方法出現(xiàn)異常,則將其從ThreadLocal中移除掉。

有了這幾步后,我們可以來實(shí)現(xiàn)解鎖操作了。我們在DistributedLock添加一個unlock方法。

畢竟是利用DB來實(shí)現(xiàn)分布式鎖,對DB還是造成一定的壓力。當(dāng)時考慮使用DB做分布式的一個重要原因是,我們的應(yīng)用是后端應(yīng)用,平時流量不大的,反而關(guān)鍵的是要保證庫存數(shù)據(jù)的正確性。對于像前端庫存系統(tǒng),比如添加購物車占用庫存等操作,最好別使用DB來實(shí)現(xiàn)分布式鎖了。

如果想鎖住多份數(shù)據(jù)該怎么實(shí)現(xiàn)?比如說,某個庫存操作,既要修改物理庫存,又要修改虛擬庫存,想鎖住物理庫存的同時,又鎖住虛擬庫存。其實(shí)也不是很難,參考lock方法,寫一個multiLock方法,提供多個transactionId的入?yún)?,for循環(huán)處理就可以了。這個后續(xù)有時間再補(bǔ)上。

mysql如何實(shí)現(xiàn)分布式數(shù)據(jù)庫

應(yīng)該是通過ndb的cluster來實(shí)現(xiàn)啊,你只需在網(wǎng)上找mysql cluster的資料就可以知道了。在mysql官方網(wǎng)站上可以下載到,如《mysql cluster維護(hù)手冊.docx》等

MySQL Mycat 分布式架構(gòu)

參考:

圖中是兩組分片,紅色我們稱為shard1,藍(lán)色我們稱為shard2

51 52是服務(wù)器

兩個3307互為主從(雙主),3309是本地3307的從庫

說明:沒有明確說明是只在某一個節(jié)點(diǎn)上做的,就是兩個節(jié)點(diǎn)都做

兩臺虛擬機(jī) db01 db02

每臺創(chuàng)建四個mysql實(shí)例:3307 3308 3309 3310

mysql軟件我們之前已完成二進(jìn)制安裝,直接初始化即可

我們server-id規(guī)劃為:db01上是7/8/9/10,db02上是17/18/19/20

"箭頭指向誰是主庫"

10.0.0.51:3307 ----- 10.0.0.52:3307

10.0.0.51:3309 ------ 10.0.0.51:3307

10.0.0.52:3309 ------ 10.0.0.52:3307

兩個分片,每個分片四個mysql節(jié)點(diǎn)

shard1:

Master:10.0.0.51:3307

slave1:10.0.0.51:3309

Standby Master:10.0.0.52:3307

slave2:10.0.0.52:3309

shard2:

Master:10.0.0.52:3308

slave1:10.0.0.52:3310

Standby Master:10.0.0.51:3308

slave2:10.0.0.51:3310

shard1

10.0.0.51:3307 ----- 10.0.0.52:3307

db02

db01

db02

10.0.0.51:3309 ------ 10.0.0.51:3307

db01

10.0.0.52:3309 ------ 10.0.0.52:3307

db02

shard2

10.0.0.52:3308 ----- 10.0.0.51:3308

db01

db02

db01

10.0.0.52:3310 ----- 10.0.0.52:3308

db02

10.0.0.51:3310 ----- 10.0.0.51:3308

db01

這個復(fù)制用戶在誰上建都行

注:如果中間出現(xiàn)錯誤,在每個節(jié)點(diǎn)進(jìn)行執(zhí)行以下命令

常見方案:

360 Atlas-Sharding 360

Alibaba cobar 阿里

Mycat 開源

TDDL 淘寶

Heisenberg 百度

Oceanus 58同城

Vitess 谷歌

OneProxy

DRDS 阿里云

我們裝的是openjdk,不是官方的那個

Mycat-server-xxxxx.linux.tar.gz

配置環(huán)境變量

我們mycat的命令也是在bin目錄下

啟動

8066就是對外提供服務(wù)的端口,9066是管理端口

連接mycat:

默認(rèn)123456

db01:

我們一般先把原schema.xml備份,然后自己新寫一個:

xml和html看起來差不多,xml是從下往上調(diào)用的

前三行我們不用看,直接從第四行schema開始看起:

定義了schema,然后以/schema結(jié)尾

為什么要用邏輯庫?

業(yè)務(wù)透明化

此配置文件就是實(shí)現(xiàn)讀寫分離的配置

重啟mycat

讀寫分離測試

總結(jié):

以上案例實(shí)現(xiàn)了1主1從的讀寫分離功能,寫操作落到主庫,讀操作落到從庫.如果主庫宕機(jī),從庫不能在繼續(xù)提供服務(wù)了。

我們推薦這種架構(gòu)

一寫三讀,

不設(shè)置雙寫的原因是:性能沒提升多少,反而引起主鍵沖突的情況

配置文件:

之后重啟:mycat restart

真正的 writehost:負(fù)責(zé)寫操作的writehost

standby writeHost :和readhost一樣,只提供讀服務(wù)

我們此處寫了兩個writehost,默認(rèn)使用第一個

當(dāng)寫節(jié)點(diǎn)宕機(jī)后,后面跟的readhost也不提供服務(wù),這時候standby的writehost就提供寫服務(wù),

后面跟的readhost提供讀服務(wù)

測試:

讀寫分離測試

對db01 3307節(jié)點(diǎn)進(jìn)行關(guān)閉和啟動,測試讀寫操作

結(jié)果應(yīng)為另一臺(52)的3307(17)是寫,3309(19)是讀

一旦7號節(jié)點(diǎn)恢復(fù),此時因?yàn)?落后了,寫節(jié)點(diǎn)仍是17

balance屬性

負(fù)載均衡類型,目前的取值有3種:

writeType屬性

負(fù)載均衡類型,目前的取值有2種:

switchType屬性

-1 表示不自動切換

1 默認(rèn)值,自動切換

2 基于MySQL主從同步的狀態(tài)決定是否切換 ,心跳語句為 show slave status

datahost其他配置

dataHost name="localhost1" maxCon="1000" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="1"

maxCon="1000":最大的并發(fā)連接數(shù)

minCon="10" :mycat在啟動之后,會在后端節(jié)點(diǎn)上自動開啟的連接線程,長連接,好處是連接速度快,弊端是占內(nèi)存

tempReadHostAvailable="1"

這個一主一從時(1個writehost,1個readhost時),可以開啟這個參數(shù),如果2個writehost,2個readhost時

heartbeatselect user()/heartbeat 監(jiān)測心跳

其他參數(shù)sqlMaxLimit自動分頁,必須在啟用分表的情況下才生效

創(chuàng)建測試庫和表:

我們重啟mycat后連接到8066

發(fā)現(xiàn)跟一個庫一樣,實(shí)際上已經(jīng)分到不同的物理硬件上了

分片:對一個"bigtable",比如說t3表

熱點(diǎn)數(shù)據(jù)表 核心表

(1)行數(shù)非常多,800w下坡

(2)訪問非常頻繁

分片的目的:

(1)將大數(shù)據(jù)量進(jìn)行分布存儲

(2)提供均衡的訪問路由

分片策略:

范圍 range 800w 1-400w 400w01-800w 不適用于業(yè)務(wù)訪問不均勻的情況

取模 mod (取余數(shù)) 和節(jié)點(diǎn)的數(shù)量進(jìn)行取模

枚舉 按枚舉的種類分,如移動項(xiàng)目按省份分

哈希 hash

時間 流水

優(yōu)化關(guān)聯(lián)查詢(否則join的表在不同分片上,效率會比單庫還要低)

全局表

ER分片

案例:移動統(tǒng)一:先拆出邊緣業(yè)務(wù),再按地域分片,但對應(yīng)用來說是統(tǒng)一的

vim rule.xml

tableRule name="auto-sharding-long"

rule

columnsid/columns

algorithmrang-long/algorithm

/rule

function name="rang-long"

class="io.mycat.route.function.AutoPartitionByLong"

property name="mapFile"autopartition-long.txt/property

/function

===================================

vim autopartition-long.txt

0-10=0

11-20=1

創(chuàng)建測試表:

mysql -S /data/3307/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"

mysql -S /data/3308/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"

測試:

重啟mycat

mycat restart

mysql -uroot -p123456 -h 127.0.0.1 -P 8066

insert into t3(id,name) values(1,'a');

insert into t3(id,name) values(2,'b');

insert into t3(id,name) values(3,'c');

insert into t3(id,name) values(4,'d');

insert into t3(id,name) values(11,'aa');

insert into t3(id,name) values(12,'bb');

insert into t3(id,name) values(13,'cc');

insert into t3(id,name) values(14,'dd');

取余分片方式:分片鍵(一個列)與節(jié)點(diǎn)數(shù)量進(jìn)行取余,得到余數(shù),將數(shù)據(jù)寫入對應(yīng)節(jié)點(diǎn)

vim schema.xml

table name="t4" dataNode="sh1,sh2" rule="mod-long" /

vim rule.xml

property name="count"2/property

準(zhǔn)備測試環(huán)境

創(chuàng)建測試表:

mysql -S /data/3307/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"

mysql -S /data/3308/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"

重啟mycat

mycat restart

測試:

mysql -uroot -p123456 -h10.0.0.52 -P8066

use TESTDB

insert into t4(id,name) values(1,'a');

insert into t4(id,name) values(2,'b');

insert into t4(id,name) values(3,'c');

insert into t4(id,name) values(4,'d');

分別登錄后端節(jié)點(diǎn)查詢數(shù)據(jù)

mysql -S /data/3307/mysql.sock

use taobao

select * from t4;

mysql -S /data/3308/mysql.sock

use taobao

select * from t4;

t5 表

id name telnum

1 bj 1212

2 sh 22222

3 bj 3333

4 sh 44444

5 bj 5555

sharding-by-intfile

vim schema.xml

table name="t5" dataNode="sh1,sh2" rule="sharding-by-intfile" /

vim rule.xml

tableRule name="sharding-by-intfile"

rule columnsname/columns

algorithmhash-int/algorithm

/rule

/tableRule

function name="hash-int" class="org.opencloudb.route.function.PartitionByFileMap"

property name="mapFile"partition-hash-int.txt/property

property name="type"1/property

property name="defaultNode"0/property

/function

partition-hash-int.txt 配置:

bj=0

sh=1

DEFAULT_NODE=1

columns 標(biāo)識將要分片的表字段,algorithm 分片函數(shù), 其中分片函數(shù)配置中,mapFile標(biāo)識配置文件名稱

準(zhǔn)備測試環(huán)境

mysql -S /data/3307/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"

mysql -S /data/3308/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"

重啟mycat

mycat restart

mysql -uroot -p123456 -h10.0.0.51 -P8066

use TESTDB

insert into t5(id,name) values(1,'bj');

insert into t5(id,name) values(2,'sh');

insert into t5(id,name) values(3,'bj');

insert into t5(id,name) values(4,'sh');

insert into t5(id,name) values(5,'tj');

a b c d

join

t

select t1.name ,t.x from t1

join t

select t2.name ,t.x from t2

join t

select t3.name ,t.x from t3

join t

使用場景:

如果你的業(yè)務(wù)中有些數(shù)據(jù)類似于數(shù)據(jù)字典,比如配置文件的配置,

常用業(yè)務(wù)的配置或者數(shù)據(jù)量不大很少變動的表,這些表往往不是特別大,

而且大部分的業(yè)務(wù)場景都會用到,那么這種表適合于Mycat全局表,無須對數(shù)據(jù)進(jìn)行切分,

要在所有的分片上保存一份數(shù)據(jù)即可,Mycat 在Join操作中,業(yè)務(wù)表與全局表進(jìn)行Join聚合會優(yōu)先選擇相同分片內(nèi)的全局表join,

避免跨庫Join,在進(jìn)行數(shù)據(jù)插入操作時,mycat將把數(shù)據(jù)分發(fā)到全局表對應(yīng)的所有分片執(zhí)行,在進(jìn)行數(shù)據(jù)讀取時候?qū)S機(jī)獲取一個節(jié)點(diǎn)讀取數(shù)據(jù)。

vim schema.xml

table name="t_area" primaryKey="id" type="global" dataNode="sh1,sh2" /

后端數(shù)據(jù)準(zhǔn)備

mysql -S /data/3307/mysql.sock

use taobao

create table t_area (id int not null primary key auto_increment,name varchar(20) not null);

mysql -S /data/3308/mysql.sock

use taobao

create table t_area (id int not null primary key auto_increment,name varchar(20) not null);

重啟mycat

mycat restart

測試:

mysql -uroot -p123456 -h10.0.0.52 -P8066

use TESTDB

insert into t_area(id,name) values(1,'a');

insert into t_area(id,name) values(2,'b');

insert into t_area(id,name) values(3,'c');

insert into t_area(id,name) values(4,'d');

A

join

B

為了防止跨分片join,可以使用E-R模式

A join B

on a.xx=b.yy

join C

on A.id=C.id

table name="A" dataNode="sh1,sh2" rule="mod-long"

childTable name="B" joinKey="yy" parentKey="xx" /

/table

mysql如何做成分布式?

MySQL做分布式需要通過ndb的Cluster來實(shí)現(xiàn)。MySQLCluster是MySQL適合于分布式計算環(huán)境的高實(shí)用、高冗余版本。 實(shí)現(xiàn)的步驟比較復(fù)雜,百度云案例:《MySQLCluster(MySQL集群)分布式》 下載地址:

名稱欄目:mysql怎么制作分布式 mysql數(shù)據(jù)庫是分布式的嗎
標(biāo)題路徑:http://muchs.cn/article6/hgeeog.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計公司做網(wǎng)站、App設(shè)計外貿(mào)建站、企業(yè)建站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司