国产 无码 综合区,色欲AV无码国产永久播放,无码天堂亚洲国产AV,国产日韩欧美女同一区二区

分布式數(shù)據(jù)庫架構(gòu)

這篇具有很好參考價值的文章主要介紹了分布式數(shù)據(jù)庫架構(gòu)。希望對大家有所幫助。如果存在錯誤或未考慮完全的地方,請大家不吝賜教,您也可以點(diǎn)擊"舉報違法"按鈕提交疑問。

分布式數(shù)據(jù)庫架構(gòu)

1、MySQL常見架構(gòu)設(shè)計(jì)

對于mysql架構(gòu),一定會使用到讀寫分離,在此基礎(chǔ)上有五種常見架構(gòu)設(shè)計(jì):一主一從或多從、主主復(fù)制、級聯(lián)復(fù)制、主主與級聯(lián)復(fù)制結(jié)合。

1.1、主從復(fù)制

這種架構(gòu)設(shè)計(jì)是使用的最多的。在讀寫分離的基礎(chǔ)上,會存在一臺master作為寫機(jī),一個或多個slave作為讀機(jī)。因?yàn)樵趯?shí)際的情況下,讀的請求量一般是遠(yuǎn)遠(yuǎn)大于寫請求的。
分布式數(shù)據(jù)庫架構(gòu)
采用這種架構(gòu)之后,當(dāng)應(yīng)用寫入輸入時,會把數(shù)據(jù)寫入到master節(jié)點(diǎn),然后由master節(jié)點(diǎn)將寫入數(shù)據(jù)復(fù)制到slave節(jié)點(diǎn)上。

缺點(diǎn):

  • master單機(jī)故障
  • 對master進(jìn)行維護(hù)時,無法接收寫請求
  • master復(fù)制延遲,查詢數(shù)據(jù)延遲
  • slave提升為master后,可能會發(fā)生數(shù)據(jù)丟失(數(shù)據(jù)不一致)
1.1.1、 主從復(fù)制搭建

1、首先需要在兩臺機(jī)器上安裝mysql鏡像以及創(chuàng)建mysql容器

docker pull mysql:5.7

docker run --name mysql3307 -p 3307:3306 --privileged=true -ti -e MYSQL_ROOT_PASSWORD=123456 -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -v /home/mysql/docker-data/3307/conf:/etc/mysql/conf.d -v /home/mysql/docker-data/3307/data/:/var/lib/mysql -v /home/mysql/docker-data/3307/logs/:/var/log/mysql -d mysql:5.7

2、需要在兩臺機(jī)器上的/home/mysql/docker-data/3307/conf目錄下,需要創(chuàng)建mysql的配置文件my.cnf。

my.cnf配置文件內(nèi)容如下:

# For advice on how to change settings please see
# http://dev.mysql.com/doc/refman/5.7/en/server-configuration-defaults.html

[mysqld]
#
# Remove leading # and set to the amount of RAM for the most important data
# cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%.
# innodb_buffer_pool_size = 128M
#
# Remove leading # to turn on a very important data integrity option: logging
# changes to the binary log between backups.
# log_bin
#
# Remove leading # to set options mainly useful for reporting servers.
# The server defaults are faster for transactions and fast SELECTs.
# Adjust sizes as needed, experiment to find the optimal values.
# join_buffer_size = 128M
# sort_buffer_size = 2M
# read_rnd_buffer_size = 2M
#datadir=/home/mysql/docker-data/3307/data
#socket=/home/mysql/docker-data/3307/mysql.sock

character_set_server=utf8
init_connect='SET NAMES utf8'

# Disabling symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

#log-error=/home/mysql/docker-data/3307/logs/mysqld.log
#pid-file=/home/mysql/docker-data/3307/mysqld.pid
lower_case_table_names=1
#指定主機(jī)號,不允許出現(xiàn)重復(fù)
server-id=423307
#開啟binlog
log-bin=mysql-bin
auto_increment_increment=2
auto_increment_offset=1

#rpl_semi_sync_master_enabled=1
#rpl_semi_sync_master_timeout=10000

3、在master的docker容器中添加mysql權(quán)限,開啟備份機(jī)復(fù)制,并且設(shè)置備份用戶信息。

#添加權(quán)限
GRANT REPLICATION SLAVE,FILE,REPLICATION CLIENT ON *.* TO 'repluser'@'%' IDENTIFIED BY '123456';

#刷新權(quán)限
FLUSH PRIVILEGES;

分布式數(shù)據(jù)庫架構(gòu)
4、設(shè)置并刷新權(quán)限后,重啟mysql服務(wù)器,可以查看master上的binlog信息。

show master status;

分布式數(shù)據(jù)庫架構(gòu)
注意:至此上述步驟兩臺機(jī)器上都需要執(zhí)行,參數(shù)上的設(shè)置按實(shí)際情況來定。

5、接著在slave中進(jìn)入到mysql容器,設(shè)置master信息,用于標(biāo)注當(dāng)前slave的master是誰。

change master to master_host='localhost',master_port=3307,master_user='repluser',master_password='123456',master_log_file='mysql-bin.000002',master_log_pos=154;

參數(shù)解析

change master to master_host='master的ip',
master_port=master的端口號,
master_user='repluser',master_password='123456',
master_log_file='master中的binlob文件',
master_log_pos=master中的position位置信息;

分布式數(shù)據(jù)庫架構(gòu)
6、設(shè)置完成后,還要開啟slave中的IOSQL線程,這兩個線程主要用于slave中進(jìn)行數(shù)據(jù)備份,可以先查看slave中這兩個線程的狀態(tài)。

show slave status\G

分布式數(shù)據(jù)庫架構(gòu)
開啟slave中的IOSQL線程

start slave;

分布式數(shù)據(jù)庫架構(gòu)
至此mysql主從復(fù)制搭建完成。

7、 相關(guān)狀態(tài)信息的查看

查看slave中的binlog是否已經(jīng)開啟

show global variables like "%log%";

分布式數(shù)據(jù)庫架構(gòu)
接著還可以查看master、slave中的進(jìn)程信息

在master mysql中輸入:

show processlist;

分布式數(shù)據(jù)庫架構(gòu)
從上圖中可以看出:master已經(jīng)把所有的binlog發(fā)送給slave,并且等待更多的更新操作。

在slave mysql中輸入:

show processlist;

分布式數(shù)據(jù)庫架構(gòu)
從上圖可以看出:在slave它已經(jīng)連接到了master,正在等待master發(fā)送事件,并且slave已經(jīng)讀取了所有的relay log信息,并且正在等待更多的更新操作。

8、測試驗(yàn)證

連接主庫,并在主庫中創(chuàng)建數(shù)據(jù)庫,創(chuàng)建數(shù)據(jù)庫表以及添加行記錄。此時會發(fā)現(xiàn)從庫中也會創(chuàng)建相應(yīng)的數(shù)據(jù)庫和數(shù)據(jù)庫表和行記錄。

1.1.2、 MySQL復(fù)制原理

在mysql中,其有兩種復(fù)制機(jī)制,分別是:異步復(fù)制、半同步復(fù)制。默認(rèn)采用異步復(fù)制。(上述主從復(fù)制操作為異步復(fù)制)

異步復(fù)制執(zhí)行流程

分布式數(shù)據(jù)庫架構(gòu)

  • 1、應(yīng)用事務(wù)提交到master
  • 2、master接收到應(yīng)用事務(wù)提交請求后,會更新內(nèi)部的binlog日志,接著讓mysql引擎執(zhí)行事務(wù)操作,并返回給客戶端執(zhí)行結(jié)果信息。同時在master中會存在一個事件監(jiān)聽,其會一直監(jiān)聽master中binlog日志文件的改變,一旦發(fā)現(xiàn)日志文件發(fā)生改變,則會觸發(fā)dump線程。
  • 3、dump線程被觸發(fā)后,會通知slave中的IO線程現(xiàn)在有事務(wù)操作需要進(jìn)行同步。
  • 4、slave中IO線程接收到通知后,會從slave中relay-log.info文件中獲取slave中的binlog日志文件和pos位置信息。接著會把這部分信息發(fā)送給master的dump線程。
  • 5、master的dump線程接收到這些信息后,會根據(jù)slave發(fā)送的binlog日志文件和pos位置,將最新的binlog日志和pos位置后面的內(nèi)容同步給slave的IO線程。
  • 6、slave的IO線程接收到這些信息后,會將這部分內(nèi)容同步到slave的relay-bin文件中。
  • 7、當(dāng)relay-bin文件發(fā)生改變后,會觸發(fā)slave線程執(zhí)行sql操作。(異步操作)
  • 8、當(dāng)slave向relay-bin寫入完成后,還會向master返回一個ACK消息,通知slave已經(jīng)執(zhí)行成功。

總結(jié):對于這一系列操作,可以發(fā)現(xiàn)master和slave在進(jìn)行同步時是以異步的方式完成的,master寫入完binlog后,會馬上通過引擎進(jìn)行事務(wù)提交并向客戶端返回響應(yīng),對于與slave同步的操作,則是異步完成的。

雖然這種方式的RT很快,但是很容易出現(xiàn)數(shù)據(jù)不一致的情況。

半同步復(fù)制執(zhí)行流程

分布式數(shù)據(jù)庫架構(gòu)

  • 半同步復(fù)制與異步復(fù)制的工作流程大體相似,但不同的是,當(dāng)master中的binlog日志寫入完成后,其不會馬上通過引擎進(jìn)行事務(wù)提交,而會處于等待,等到slave同步完成向master返回ACK通知后,才會喚醒等待,繼續(xù)向下執(zhí)行。
  • 等待的時長,默認(rèn)為10秒,但該時間可以配置。
  • 半同步復(fù)制盡量的避免的主從數(shù)據(jù)不一致的情況,但是會造成吞吐量的降低。

對于這個問題,mysql也進(jìn)行了解決,假設(shè)使用半同步復(fù)制進(jìn)行備份時,slave節(jié)點(diǎn)掛掉了,那么當(dāng)master等待10秒后,仍然會進(jìn)行引擎提交,同時會將半同步復(fù)制切換為異步復(fù)制。等到slave節(jié)點(diǎn)重啟后,又會自動的從異步復(fù)制切換到半同步復(fù)制。

主從異步復(fù)制日志效果

Mysql在進(jìn)行復(fù)制操作時,默認(rèn)是基于異步復(fù)制完成的。那為了更好的體會異步復(fù)制的效果,可以通過mysql日志來查看具體的復(fù)制過程效果。

啟動主從兩臺Mysql服務(wù)器。

查看master的Mysql日志信息

docker logs -f mysql3307 | grep binlog_dump

分布式數(shù)據(jù)庫架構(gòu)
?根據(jù)當(dāng)前查看的日志信息,在master中已經(jīng)開啟了dump線程連接到了id為273307的slave節(jié)點(diǎn),并且該id就是在slave的mysql配置文件中設(shè)置的id。

同時pos內(nèi)容包括當(dāng)前的binlog日志和pos位置。

查看slave的mysql日志信息
分布式數(shù)據(jù)庫架構(gòu)
根據(jù)slave中的日志信息,可以看到,當(dāng)前slave中已經(jīng)開啟了relay-log日志,其對應(yīng)文件信息就是xxxxx-relay-bin。其內(nèi)部保存的就是slave中的相關(guān)binlog信息和pos位置信息。

同時在slave中也已經(jīng)開啟了SQL Thread,并且根據(jù)信息可以,它會從xxxx-relay-bin.000001文件的4位置開始復(fù)制。

同時在slave中也開啟了IO Thread,其已經(jīng)連接到master,并且會從master的binlog日志的154的位置開啟復(fù)制。

查看master當(dāng)前的binlog日志信息

#確定當(dāng)前master正在使用的binlog日志文件
cat mysql-bin.index

#查看當(dāng)前binlog日志文件內(nèi)容
tail -f mysql-bin.000002

分布式數(shù)據(jù)庫架構(gòu)
查看slave當(dāng)前的日志信息

cat relay-log.info

cat master.info

分布式數(shù)據(jù)庫架構(gòu)
分布式數(shù)據(jù)庫架構(gòu)

cat xxxxxxxxxx-relay-bin.index

分布式數(shù)據(jù)庫架構(gòu)
分布式數(shù)據(jù)庫架構(gòu)
監(jiān)控slave日志信息

tail -f 8122977f8b0a-relay-bin.000002

分布式數(shù)據(jù)庫架構(gòu)
master中新增數(shù)據(jù),觸發(fā)主從同步

  • 查看master修改前后的binlog日志
cat mysql-bin.000002 

分布式數(shù)據(jù)庫架構(gòu)

  • 查看slave復(fù)制前后的relay-bin日志
 tail -f 41dc8a520939-relay-bin.000002

分布式數(shù)據(jù)庫架構(gòu)

1.1.3、 主從半同步復(fù)制搭建

1、配置
進(jìn)入mysql容器,加載lib,主從節(jié)點(diǎn)都要配置,因?yàn)橹鲝墓?jié)點(diǎn)間會存在切換。

install plugin rpl_semi_sync_master soname 'semisync_master.so';

install plugin rpl_semi_sync_slave soname 'semisync_slave.so';

分布式數(shù)據(jù)庫架構(gòu)
查看插件信息

show plugins;

分布式數(shù)據(jù)庫架構(gòu)
2、啟用半同步(務(wù)必先啟用從庫,再啟用主庫

#先啟用從庫,再啟用主庫

#從庫:
set global rpl_semi_sync_slave_enabled= {0|1};  # 1:啟用,0:禁止

#主庫:
set global rpl_semi_sync_master_enabled= {0|1}; # 1:啟用,0:禁止

set global rpl_semi_sync_master_timeout=10000;  # 單位為ms

分布式數(shù)據(jù)庫架構(gòu)
分布式數(shù)據(jù)庫架構(gòu)
3、重啟從庫IO Thread

stop slave io_thread;
start slave io_thread;

4、截止到此已經(jīng)完成半同步開啟配置,可以查看主庫狀態(tài)信息和參數(shù)信息

#查詢狀態(tài)信息
show global status like "%sync%";

#查詢參數(shù)信息
show global variables like '%sync%';

show global status like “%sync%”;
分布式數(shù)據(jù)庫架構(gòu)
show global variables like ‘%sync%’;
分布式數(shù)據(jù)庫架構(gòu)
根據(jù)上述的配置,當(dāng)前主從兩臺服務(wù)器的復(fù)制方式已經(jīng)改為半同步復(fù)制。接下來就可以來查看具體的效果。

  • 正常的向master中添加數(shù)據(jù),slave可以進(jìn)行正常數(shù)據(jù)更新。

master打印日志信息如下: 開啟半同步復(fù)制,關(guān)閉異步復(fù)制
分布式數(shù)據(jù)庫架構(gòu)

  • 關(guān)閉slave的IO Thread或者停止salve服務(wù)

再次向master中添加數(shù)據(jù)。此時可以發(fā)現(xiàn),當(dāng)進(jìn)行數(shù)據(jù)提交時,會出現(xiàn)等待,過了十秒后,會對數(shù)據(jù)進(jìn)行保存。同時slave中不會同步的進(jìn)行數(shù)據(jù)更新。
分布式數(shù)據(jù)庫架構(gòu)
分布式數(shù)據(jù)庫架構(gòu)
如上圖所示,超過時間后,半同步復(fù)制會轉(zhuǎn)化為異步復(fù)制。此時復(fù)制機(jī)制就會由半同步復(fù)制轉(zhuǎn)換為異步復(fù)制,當(dāng)再次向master中添加數(shù)據(jù),不會再次出現(xiàn)等待。

  • slave中重新開啟IO Thread。

異步復(fù)制會再次轉(zhuǎn)換為半同步復(fù)制,其次,在slave IO Tthread關(guān)閉這段時間內(nèi)的數(shù)據(jù),會同步到slave中,不會出現(xiàn)數(shù)據(jù)丟失。

1.2、主主復(fù)制

對于主從復(fù)制來說,其內(nèi)部會存在一臺master以及一臺或多臺slave。但有一個非常明顯的問題,master是單點(diǎn)存在。一旦master宕機(jī),則無法進(jìn)行數(shù)據(jù)的寫入。為了解決這個問題,可以使用主主復(fù)制架構(gòu)。

在主主復(fù)制架構(gòu)中,會存在兩臺master,沒有slave。并且會對這兩臺master進(jìn)行讀寫分離,兩臺master會進(jìn)行相互的復(fù)制。

主主復(fù)制架構(gòu)圖
分布式數(shù)據(jù)庫架構(gòu)
在此架構(gòu)中,兩臺master會進(jìn)行雙向復(fù)制,為什么這么做呢? 因?yàn)榧僭O(shè)現(xiàn)在負(fù)責(zé)寫的master宕機(jī)了,那么寫的工作則會交給之前負(fù)責(zé)讀的服務(wù)器來完成,相當(dāng)于它即負(fù)責(zé)寫又負(fù)責(zé)讀。等到原先負(fù)責(zé)寫的master恢復(fù)了,其在繼續(xù)負(fù)責(zé)寫工作。 反之亦然。因此才需要兩者間進(jìn)行雙向復(fù)制。

此時缺點(diǎn)也非常明顯,雖然master不存在單點(diǎn)了,但是對于讀來說,如果并發(fā)量大的話,它肯定扛不住。對于主主復(fù)制架構(gòu)來說,應(yīng)用較少。

1.2.1、主主復(fù)制搭建

主主復(fù)制的搭建和主從非常類似,只不過主主復(fù)制會進(jìn)行互指。

1、參照主從完成搭建。(按照上述主從復(fù)制結(jié)構(gòu)搭建)

2、原slave端也要開啟權(quán)限

#添加權(quán)限
GRANT REPLICATION SLAVE,FILE,REPLICATION CLIENT ON *.* TO 'repluser'@'%' IDENTIFIED BY '123456';

#刷新權(quán)限
FLUSH PRIVILEGES;

#重啟mysql服務(wù)并查看binlog信息
show master status

3、在master這一端也要配置slave的相關(guān)配置

change master to master_host='localhost',master_port=3308,master_user='repluser',master_password='123456',master_log_file='mysql-bin.000002',master_log_pos=154;

start slave;

4、查看master和slave的進(jìn)程列表:show processlist??梢园l(fā)現(xiàn)他們現(xiàn)在互為主備。

master
分布式數(shù)據(jù)庫架構(gòu)
slave分布式數(shù)據(jù)庫架構(gòu)

5、測試
當(dāng)在兩臺服務(wù)器中添加數(shù)據(jù),都可以完成雙向同步。

1.3、級聯(lián)復(fù)制架構(gòu)

當(dāng)讀壓力現(xiàn)在增大并且還想減小主從復(fù)制的性能消耗,可以采用級聯(lián)復(fù)制架構(gòu)。
分布式數(shù)據(jù)庫架構(gòu)
寫請求的入口仍為一個,但當(dāng)master向slave進(jìn)行復(fù)制時,對于slave可以分為多層, master只要向其中兩臺slave復(fù)制即可,然后再由slave將其數(shù)據(jù)復(fù)制到后面更多的slave中。

通過這種方式可以減輕master向slave復(fù)制的IO壓力。

但是這種架構(gòu)也存在一個弊端:slave的延遲會加大。

1.4、雙主與級聯(lián)復(fù)制結(jié)合架構(gòu)

對于master在前面幾種架構(gòu)設(shè)計(jì)中,都存在單點(diǎn)問題, 對于master單點(diǎn)問題的解決,可以采用當(dāng)前的架構(gòu)。通過這種架構(gòu)不僅可以解決master單點(diǎn)的問題,也可以解決slave延遲的問題。
分布式數(shù)據(jù)庫架構(gòu)

2、Mysql高可用實(shí)踐

以主主架構(gòu)為例,現(xiàn)在不管寫或者讀,只要其中一個宕機(jī),則會把它本身工作交給另外一臺服務(wù)器完成。此時就需要對IP進(jìn)行一個自動的指向。而且這種服務(wù)器IP切換,對于上層應(yīng)用來說,應(yīng)該是完全隱藏的,其無需知道當(dāng)前是由誰來完成具體工作,其只需要來連接一個IP就可以。

對于這種需求,就需要通過keepAlived來完成IP的自動切換。
分布式數(shù)據(jù)庫架構(gòu)
對于keepalived會在多臺mysql服務(wù)器進(jìn)行安裝, 同時keepalived間也分為master和slave, 同時master會虛擬化一個VIP供應(yīng)用進(jìn)行連接。 如果一旦master掛掉后,會由slave節(jié)點(diǎn)繼續(xù)工作,同時slave節(jié)點(diǎn)也會虛擬出相同VIP,供應(yīng)用進(jìn)行連接。

2.1、keepAlived高可用配置

1、安裝keepalived

1. 下載keepalied安裝包 http://www.keepalived.org/download.html
2. yum -y install openssl-devel gcc gcc-c++
3. mkdir /etc/keepalived
4. 上傳安裝包并解壓  tar -zxvf keepalived-2.0.18.tar.gz
5. mv keepalived-2.0.18 /usr/local/keepalived
6. cd /usr/local/keepalived
7. ./configure && make && make install
8.創(chuàng)建啟動文件
cp  -a /usr/local/etc/keepalived   /etc/init.d/
cp  -a /usr/local/etc/sysconfig/keepalived    /etc/sysconfig/
cp  -a /usr/local/sbin/keepalived    /usr/sbin/

2、編寫執(zhí)行shell腳本

進(jìn)入/etc/keepalived。創(chuàng)建chk.sh,同時賦予執(zhí)行權(quán)限:chmod +x chk.sh

#! /bin/bash
mysql -h 127.0.0.1 -u root -p123456 -P 3312 -e "show status;" >/dev/null 2>&1
if [ $? == 0 ]
then
    echo " $host mysql login successfully "
    exit 0
else
    echo "  mysql login faild"
    killall keepalived
    exit 2
fi

3、編寫keepAlived配置文件

cd /etc/keepalived

vi keepalived.conf

! Configuration File for keepalived
#簡單的頭部,這里主要可以做郵件通知報警等的設(shè)置,此處就暫不配置了;
global_defs {
    #notificationd LVS_DEVEL
    router_id MYSQL_4   #唯一標(biāo)識不允許出現(xiàn)重復(fù)
    script_user root
    enable_script_security
}
#預(yù)先定義一個腳本,方便后面調(diào)用,也可以定義多個,方便選擇;
vrrp_script chk_haproxy {
    script "/etc/keepalived/chk.sh"
    interval 2  #腳本循環(huán)運(yùn)行間隔
}
#VRRP虛擬路由冗余協(xié)議配置
vrrp_instance VI_1 {   #VI_1 是自定義的名稱;
    state BACKUP    #MASTER表示是一臺主設(shè)備,BACKUP表示為備用設(shè)備【我們這里因?yàn)樵O(shè)置為開啟不搶占,所以都設(shè)置為備用】
    nopreempt      #開啟不搶占
    interface ens33   #指定VIP需要綁定的物理網(wǎng)卡
    virtual_router_id 11   #VRID虛擬路由標(biāo)識,也叫做分組名稱,該組內(nèi)的設(shè)備需要相同
    priority 130   #定義這臺設(shè)備的優(yōu)先級 1-254;開啟了不搶占,所以此處優(yōu)先級必須高于另一臺

    advert_int 1   #生存檢測時的組播信息發(fā)送間隔,組內(nèi)一致
    authentication {    #設(shè)置驗(yàn)證信息,組內(nèi)一致
        auth_type PASS   #有PASS 和 AH 兩種,常用 PASS
        auth_pass 111111    #密碼
    }
    virtual_ipaddress {
        192.168.200.200    #指定VIP地址,組內(nèi)一致,可以設(shè)置多個IP
    }
    track_script {    #使用在這個域中使用預(yù)先定義的腳本,上面定義的
        chk_haproxy
    }
}

4、啟動keepAlived

systemctl start keepalived

5、查看keepAlived執(zhí)行狀態(tài)

ps -ef|grep keepalived

分布式數(shù)據(jù)庫架構(gòu)
6、可以通過tail -f /var/log/messages

7、查看ip信息,此時可以發(fā)現(xiàn)出現(xiàn)了配置的虛擬ip

ip a

8、測試
通過navicat使用虛擬IP連接mysql,當(dāng)前連接IP為VIP??梢赃B接成功。

3、數(shù)據(jù)切分核心思想

3.1、為什么要進(jìn)行數(shù)據(jù)切分?

當(dāng)前微服務(wù)架構(gòu)非常流行,很多都會采用微服務(wù)架構(gòu)對其系統(tǒng)進(jìn)行拆分。 而雖然產(chǎn)生了多個微服務(wù),但因?yàn)槠溆脩袅亢蛿?shù)據(jù)量的問題,很有可能仍然使用的是同一個數(shù)據(jù)庫。
分布式數(shù)據(jù)庫架構(gòu)
但是隨著用戶量和數(shù)據(jù)量增加,就會出現(xiàn)很多影響數(shù)據(jù)庫性能的因素,如:數(shù)據(jù)存儲量、IO瓶頸、訪問量瓶頸等。此時就需要將數(shù)據(jù)進(jìn)行拆分,從一個庫拆分成多個庫。

3.2、數(shù)據(jù)拆分方式

垂直拆分

垂直拆分是按照業(yè)務(wù)將表進(jìn)行分類并分布到不同的數(shù)據(jù)節(jié)點(diǎn)上。在初始進(jìn)行數(shù)據(jù)拆分時,使用垂直拆分是非常直觀的一種方式。
分布式數(shù)據(jù)庫架構(gòu)
垂直拆分的優(yōu)點(diǎn):

  • 拆分規(guī)則明確,按照不同的功能模塊或服務(wù)分配不同的數(shù)據(jù)庫。
  • 數(shù)據(jù)維護(hù)與定位簡單。

垂直拆分的缺點(diǎn):

  • 對于讀寫極其頻繁且數(shù)據(jù)量超大的表,仍然存在存儲與性能瓶頸。簡單的索引此時已經(jīng)無法解決問題。
  • 會出現(xiàn)跨庫join。
  • 需要對代碼進(jìn)行重構(gòu),修改原有的事務(wù)操作。
  • 某個表數(shù)據(jù)量達(dá)到一定程度后擴(kuò)展起來較為困難。
水平拆分

?為了解決垂直拆分出現(xiàn)的問題,可以使用水平拆分繼續(xù)橫向擴(kuò)展,首先,可以如果當(dāng)前數(shù)據(jù)庫的容量沒有問題的話,可以對讀寫極其頻繁且數(shù)據(jù)量超大的表進(jìn)行分表操作。由一張表拆分出多張表。

在一個庫中,拆分出多張表,每張表存儲不同的數(shù)據(jù),這樣對于其操作效率會有明顯的提升。而且因?yàn)樘幱谕粋€庫中,也不會出現(xiàn)分布式事務(wù)的問題。
分布式數(shù)據(jù)庫架構(gòu)

而拆分出多張表后,如果當(dāng)前數(shù)據(jù)庫的容量已經(jīng)不夠了,但是還要繼續(xù)拆分的話,就可以進(jìn)行分庫操作,產(chǎn)生多個數(shù)據(jù)庫,然后在擴(kuò)展出的數(shù)據(jù)庫中繼續(xù)擴(kuò)展表。
分布式數(shù)據(jù)庫架構(gòu)

水平拆分的優(yōu)點(diǎn):

  • 盡量的避免了跨庫join操作。
  • 不會存在超大型表的性能瓶頸問題。
  • 事務(wù)處理相對簡單。
  • 只要拆分規(guī)則定義好,很難出現(xiàn)擴(kuò)展性的限制。

水平拆分的缺點(diǎn):

  • 拆分規(guī)則不好明確,規(guī)則一定會和業(yè)務(wù)掛鉤,如根據(jù)id、根據(jù)時間等。
  • 不好明確數(shù)據(jù)位置,難以進(jìn)行維護(hù)。
  • 多數(shù)據(jù)源管理難度加大,代碼復(fù)雜度增加。
  • 也會存在分布式事務(wù)問題
  • 數(shù)據(jù)庫維護(hù)成本增加
數(shù)據(jù)切分帶來的問題
  • 按照用戶ID求模,將數(shù)據(jù)分散到不同的數(shù)據(jù)庫,具有相同數(shù)據(jù)用戶的數(shù)據(jù)都被分散到一個庫中。
  • 按照日期,將不同月甚至日的數(shù)據(jù)分散到不同的庫中。
  • 按照某個特定的字段求模,或者根據(jù)特定范圍段分散到不同的庫中。

數(shù)據(jù)切分帶來的核心問題

  • 產(chǎn)生引入分布式事務(wù)的問題。
  • 跨節(jié)點(diǎn) Join 的問題。
  • 跨節(jié)點(diǎn)合并排序分頁問題。

3.3、Mycat中間件使用

當(dāng)對數(shù)據(jù)拆分后會產(chǎn)生諸多的問題,對于這些問題的解決,可以借助于數(shù)據(jù)庫中間件來進(jìn)行解決,現(xiàn)在時下比較流行的是使用Mycat。

Mycat是一款數(shù)據(jù)庫中間件,對于應(yīng)用程序來說是完全透明化的,不管底層的數(shù)據(jù)如何拆分,應(yīng)用只需要連接Mycat即可完成對數(shù)據(jù)的操作。同時它還支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流數(shù)據(jù)庫。但是Mycat不會進(jìn)行數(shù)據(jù)存儲,它只是用于數(shù)據(jù)的路由。

其底層是基于攔截思想實(shí)現(xiàn),其會攔截用戶發(fā)送過來的SQL語句,首先對SQL語句做了一些特定的分析:如分片分析、路由分析、讀寫分離分析、緩存分析等,然后將此SQL發(fā)往后端的真實(shí)數(shù)據(jù)庫,并將返回的結(jié)果做適當(dāng)?shù)奶幚?,最終再返回給用戶。
分布式數(shù)據(jù)庫架構(gòu)

Mycat特性
  • 支持SQL92標(biāo)準(zhǔn)
  • 遵守Mysql原生協(xié)議,跨語言,跨平臺,跨數(shù)據(jù)庫的通用中間件代理。
  • 基于心跳的自動故障切換,支持讀寫分離,支持MySQL主從,以及galera cluster集群。
  • 支持Galera for MySQL集群,Percona Cluster或者M(jìn)ariaDB cluster
  • 基于Nio實(shí)現(xiàn),有效管理線程,高并發(fā)問題。
  • 支持?jǐn)?shù)據(jù)的多片自動路由與聚合,支持sum,count,max等常用的聚合函數(shù)。
  • 支持單庫內(nèi)部任意join,支持跨庫2表join。
  • 支持通過全局表,ER關(guān)系的分片策略,實(shí)現(xiàn)了高效的多表join查詢。
  • 支持多租戶方案。
  • 支持分布式事務(wù)(弱xa)。
  • 支持全局序列號,解決分布式下的主鍵生成問題。
  • 分片規(guī)則豐富,插件化開發(fā),易于擴(kuò)展。
  • 強(qiáng)大的web,命令行監(jiān)控。
  • 支持前端作為mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 。
  • 支持密碼加密
  • 支持服務(wù)降級
  • 支持IP白名單
  • 支持SQL黑名單、sql注入攻擊攔截
  • 支持分表(1.6)
  • 集群基于ZooKeeper管理,在線升級,擴(kuò)容,智能優(yōu)化,大數(shù)據(jù)處理(2.0開發(fā)版)。
Mycat源碼的本地部署運(yùn)行

**源碼下載:**https://codeload.github.com/MyCATApache/Mycat-Server/zip/Mycat-server-1675-release

默認(rèn)端口:8066

配置啟動參數(shù):

-DMYCAT_HOME=D:\workspace\Mycat-Server-Mycat-server-1675-release\src\main
#設(shè)置堆外內(nèi)存大小
-XX:MaxDirectMemorySize=512M 

注意:為什么要設(shè)置堆外內(nèi)存:當(dāng)使用mycat對非分片查詢時,會把所有的數(shù)據(jù)查詢出來,然后把這部分?jǐn)?shù)據(jù)放在堆外內(nèi)存中

在Mycat有核心三個配置文件,分別為:sever.xml、schema.xml、rule.xml

  • server.xml:是Mycat服務(wù)器參數(shù)調(diào)整和用戶授權(quán)的配置文件。
  • schema.xml:是邏輯庫定義和表以及分片定義的配置文件
  • rule.xml:是分片規(guī)則的配置文件,分片規(guī)則的具體一些參數(shù)信息單獨(dú)存放為文件,也在這個目錄下,配置文件修改需要重啟MyCAT。
MyCat核心概念

在學(xué)習(xí)Mycat首先需要先對其內(nèi)部一些核心概念有足夠的了解。

  • 邏輯庫:Mycat中的虛擬數(shù)據(jù)庫。對應(yīng)實(shí)際數(shù)據(jù)庫的概念。在沒有使用mycat時,應(yīng)用需要確定當(dāng)前連接的數(shù)據(jù)庫等信息,那么當(dāng)使用mycat后,也需要先虛擬一個數(shù)據(jù)庫,用于應(yīng)用的連接。
  • 邏輯表:mycat中的虛擬數(shù)據(jù)表。對應(yīng)時間數(shù)據(jù)庫中數(shù)據(jù)表的概念。
  • 非分片表:沒有進(jìn)行數(shù)據(jù)切分的表。
  • 分片表:已經(jīng)被數(shù)據(jù)拆分的表,每個分片表中都有原有數(shù)據(jù)表的一部分?jǐn)?shù)據(jù)。多張分片表可以構(gòu)成一個完整數(shù)據(jù)表。
  • ER表:子表的記錄與所關(guān)聯(lián)的父表記錄存放在同一個數(shù)據(jù)分片上,即子表依賴于父表,通過表分組(Table Group)保證數(shù)據(jù)Join不會跨庫操作。表分組(Table Group)是解決跨分片數(shù)據(jù)join的一種很好的思路,也是數(shù)據(jù)切分規(guī)劃的重要一條規(guī)則
  • 全局表:可以理解為是一張數(shù)據(jù)冗余表,如狀態(tài)表,每一個數(shù)據(jù)分片節(jié)點(diǎn)又保存了一份狀態(tài)表數(shù)據(jù)。數(shù)據(jù)冗余是解決跨分片數(shù)據(jù)join的一種很好的思路,也是數(shù)據(jù)切分規(guī)劃的另外一條重要規(guī)則。
  • 分片節(jié)點(diǎn)(dataNode):數(shù)據(jù)切分后,每一個數(shù)據(jù)分片表所在的數(shù)據(jù)庫就是分片節(jié)點(diǎn)。
  • 節(jié)點(diǎn)主機(jī)(dataHost):數(shù)據(jù)切分后,每個分片節(jié)點(diǎn)(dataNode)不一定都會獨(dú)占一臺機(jī)器,同一機(jī)器上面可以有多個分片數(shù)據(jù)庫,這樣一個或多個分片節(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)。
  • 分片規(guī)則(rule):按照某種業(yè)務(wù)規(guī)則把數(shù)據(jù)分到某個分片的規(guī)則就是分片規(guī)則。
  • 全局序列號(sequence):也可以理解為分布式id。數(shù)據(jù)切分后,原有的關(guān)系數(shù)據(jù)庫中的主鍵約束在分布式條件下將無法使用,因此需要引入外部機(jī)制保證數(shù)據(jù)唯一性標(biāo)識,這種保證全局性的數(shù)據(jù)唯一標(biāo)識的機(jī)制就是全局序列號(sequence),如UUID、雪花算法等。

4、Mycat企業(yè)級應(yīng)用實(shí)踐

4.1、環(huán)境參數(shù)配置

在server.xml 文件中的system標(biāo)簽下配置所有的參數(shù),全部為環(huán)境參數(shù),可以根據(jù)當(dāng)前需要進(jìn)行開啟和配置,如:設(shè)置mycat連接端口號

<property name="serverPort">8066</property>

分布式數(shù)據(jù)庫架構(gòu)

4.2、數(shù)據(jù)非分片

4.2.1、配置初始化信息

應(yīng)用連接mycat的話,也需要設(shè)置用戶名、密碼、被連接數(shù)據(jù)庫信息,要配置這些信息的話,可以修改server.xml,在其內(nèi)部添加內(nèi)容如下:

<!--配置自定義用戶信息-->
<!--連接用戶名-->
<user name="mycat">
    <!--連接密碼-->
    <property name="password">mycat</property>
    <!--創(chuàng)建虛擬數(shù)據(jù)庫-->
    <property name="schemas">userdb</property>
    <!--指定該庫是否只讀-->
    <!--<property name="readOnly">true</property>-->
</user>
4.2.2、配置虛擬數(shù)據(jù)庫&表
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

	<!--配置虛擬數(shù)據(jù)庫-->
	<!--name:虛擬邏輯數(shù)據(jù)庫名稱,對應(yīng)server.xml中的schemas屬性值-->
	<!--dataNode:邏輯庫中邏輯表的默認(rèn)數(shù)據(jù)節(jié)點(diǎn)-->
	<!--sqlMaxLimit:類似于SQL上添加limit,如schema為非分片庫,則該屬性無效-->
	<schema name="userdb" checkSQLschema="true" dataNode="localdn" sqlMaxLimit="500">
		<!--配置虛擬邏輯表-->
		<!--name:邏輯表名稱,必須唯一-->
		<!--dataNode:邏輯表所處的數(shù)據(jù)節(jié)點(diǎn),值必須與dataNode標(biāo)簽中的name屬性對應(yīng)。如果值過多可以用$連接,如:dn$1-99,dn$200-400-->
		<!--primaryKey:邏輯表對應(yīng)的真實(shí)表的主鍵id的字段名-->
		<table name="tb_user" dataNode="localdn" primaryKey="user_id"/>
	</schema>

	<!--配置dataNode信息-->
	<!--name:當(dāng)前datanode名稱-->
	<!--dataHost:分片節(jié)點(diǎn)所處的節(jié)點(diǎn)主機(jī),該值必須與dataHost標(biāo)簽中的name屬性對應(yīng)-->
	<!--database:當(dāng)前數(shù)據(jù)節(jié)點(diǎn)所對應(yīng)的實(shí)際物理數(shù)據(jù)庫-->
	<dataNode name="localdn" dataHost="localdh" database="user"/>

	<!--配置節(jié)點(diǎn)主機(jī)-->
	<!--balance:用于進(jìn)行讀操作指向,有三個值可選
		0:所有讀操作都發(fā)送到當(dāng)前可用的writeHost上
		1:所有讀操作都隨機(jī)的發(fā)送到readHost上
		2:所有讀操作都隨機(jī)發(fā)送在writeHost與readHost上
	-->
	<!--maxCon:指定每個讀寫實(shí)例連接池的最大連接。也就是說,標(biāo)簽內(nèi)嵌套的writeHost、readHost標(biāo)簽都會使用這個屬性的值來實(shí)例化出連接池的最大連接數(shù)-->
	<!--minCon:指定每個讀寫實(shí)例連接池的最小連接,初始化連接池的大小-->
	<!--name:當(dāng)前節(jié)點(diǎn)主機(jī)名稱,不允許出現(xiàn)重復(fù)-->
	<!--dbType:當(dāng)時使用的數(shù)據(jù)庫類型-->
	<!--dbDriver:當(dāng)前使用的數(shù)據(jù)庫驅(qū)動-->
	<!--writeType:用于寫操作指向,有三個值可選
		0:所有寫操作都發(fā)送到可用的writeHost上
		1:所有寫操作都隨機(jī)發(fā)送到readHost上
		2:所有寫操作都隨機(jī)發(fā)送在writeHost與readHost上
	-->
	<!--readHost是從屬于writeHost的,即意味著它從那個writeHost獲取同步數(shù)據(jù)。
		因此,當(dāng)它所屬的writeHost宕機(jī)了,則它也不會再參與到讀寫分離中來,即“不工作了”。這是因?yàn)榇藭r,它的數(shù)據(jù)已經(jīng)“不可靠”了。
		基于這個考慮,目前mycat 1.3和1.4版本中,若想支持MySQL一主一從的標(biāo)準(zhǔn)配置,并且在主節(jié)點(diǎn)宕機(jī)的情況下,從節(jié)點(diǎn)還能讀取數(shù)據(jù)。
		則需要在Mycat里配置為兩個writeHost并設(shè)置banlance=1。”-->
	<!--switchType:設(shè)置節(jié)點(diǎn)切換操作,有三個值可選
		-1:不自動切換
		1:自動切換,默認(rèn)值
		2:基于mysql主從同步的狀態(tài)決定是否切換
	-->
	<!--slaveThreshold:主從同步狀態(tài)決定是否切換,延遲超過該值就不切換-->
	<dataHost balance="0" maxCon="100" minCon="10" name="localdh" dbType="mysql" dbDriver="jdbc" writeType="0" switchType="1" slaveThreshold="1000">
		<!--查詢心跳-->
		<heartbeat>select user()</heartbeat>
		<!--配置寫節(jié)點(diǎn)實(shí)際物理數(shù)據(jù)庫信息-->
		<writeHost url="jdbc:mysql://localhost:3306" host="host1" password="root" user="root"></writeHost>
	</dataHost>
</mycat:schema>
4.2.3 測試

通過navicat創(chuàng)建本地?cái)?shù)據(jù)庫連接并創(chuàng)建對應(yīng)數(shù)據(jù)庫,同時創(chuàng)建mycat連接。 在mycat連接中操作表,添加數(shù)據(jù),可以發(fā)現(xiàn),本地?cái)?shù)據(jù)庫中同步的也新增了對應(yīng)的數(shù)據(jù)。

4.3、根據(jù)ID取模數(shù)據(jù)分片

當(dāng)一個數(shù)據(jù)表中的數(shù)據(jù)量非常大時,就需要考慮對表內(nèi)數(shù)據(jù)進(jìn)行分片,拆分的規(guī)則有很多種,比較簡單的一種就是,通過對id進(jìn)行取模,完成數(shù)據(jù)分片。

1)修改schema.xml

table標(biāo)簽新增屬性:subTables、rule

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

	<!--配置虛擬數(shù)據(jù)庫-->
	<!--name:虛擬邏輯數(shù)據(jù)庫名稱,對應(yīng)server.xml中的schemas屬性值-->
	<!--dataNode:邏輯庫中邏輯表的默認(rèn)數(shù)據(jù)節(jié)點(diǎn)-->
	<!--sqlMaxLimit:類似于SQL上添加limit,如schema為非分片庫,則該屬性無效-->
	<schema name="userdb" checkSQLschema="true" dataNode="localdn" sqlMaxLimit="500">
		<!--配置虛擬邏輯表-->
		<!--name:邏輯表名稱,必須唯一-->
		<!--dataNode:邏輯表所處的數(shù)據(jù)節(jié)點(diǎn),值必須與dataNode標(biāo)簽中的name屬性對應(yīng)。如果值過多可以用$連接,如:dn$1-99,dn$200-400-->
		<!--primaryKey:邏輯表對應(yīng)的真實(shí)表的主鍵id的字段名-->
		<!--subTables:分表的名稱??梢源嬖诙鄠€,tb_user1,tb_user2,tb_user3.如果分表較多,可以通過$連接:tb_user$1-3-->
		<!--rule:分片規(guī)則,對應(yīng)rule.xml中配置-->
		<table name="tb_user" dataNode="localdn" primaryKey="user_id" subTables="tb_user$1-3" rule="mod-long"/>
	</schema>

	<!--配置dataNode信息-->
	<!--name:當(dāng)前datanode名稱-->
	<!--dataHost:分片節(jié)點(diǎn)所處的節(jié)點(diǎn)主機(jī),該值必須與dataHost標(biāo)簽中的name屬性對應(yīng)-->
	<!--database:當(dāng)前數(shù)據(jù)節(jié)點(diǎn)所對應(yīng)的實(shí)際物理數(shù)據(jù)庫-->
	<dataNode name="localdn" dataHost="localdh" database="user"/>

	<!--配置節(jié)點(diǎn)主機(jī)-->
	<!--balance:用于進(jìn)行讀操作指向,有三個值可選
		0:所有讀操作都發(fā)送到當(dāng)前可用的writeHost上
		1:所有讀操作都隨機(jī)的發(fā)送到readHost上
		2:所有讀操作都隨機(jī)發(fā)送在writeHost與readHost上
	-->
	<!--maxCon:指定每個讀寫實(shí)例連接池的最大連接。也就是說,標(biāo)簽內(nèi)嵌套的writeHost、readHost標(biāo)簽都會使用這個屬性的值來實(shí)例化出連接池的最大連接數(shù)-->
	<!--minCon:指定每個讀寫實(shí)例連接池的最小連接,初始化連接池的大小-->
	<!--name:當(dāng)前節(jié)點(diǎn)主機(jī)名稱,不允許出現(xiàn)重復(fù)-->
	<!--dbType:當(dāng)時使用的數(shù)據(jù)庫類型-->
	<!--dbDriver:當(dāng)前使用的數(shù)據(jù)庫驅(qū)動-->
	<!--writeType:用于寫操作指向,有三個值可選
		0:所有寫操作都發(fā)送到可用的writeHost上
		1:所有寫操作都隨機(jī)發(fā)送到readHost上
		2:所有寫操作都隨機(jī)發(fā)送在writeHost與readHost上
	-->
	<!--readHost是從屬于writeHost的,即意味著它從那個writeHost獲取同步數(shù)據(jù)。
		因此,當(dāng)它所屬的writeHost宕機(jī)了,則它也不會再參與到讀寫分離中來,即“不工作了”。這是因?yàn)榇藭r,它的數(shù)據(jù)已經(jīng)“不可靠”了。
		基于這個考慮,目前mycat 1.3和1.4版本中,若想支持MySQL一主一從的標(biāo)準(zhǔn)配置,并且在主節(jié)點(diǎn)宕機(jī)的情況下,從節(jié)點(diǎn)還能讀取數(shù)據(jù)。
		則需要在Mycat里配置為兩個writeHost并設(shè)置banlance=1?!?->
	<!--switchType:設(shè)置節(jié)點(diǎn)切換操作,有三個值可選
		-1:不自動切換
		1:自動切換,默認(rèn)值
		2:基于mysql主從同步的狀態(tài)決定是否切換
	-->
	<!--slaveThreshold:主從同步狀態(tài)決定是否切換,延遲超過該值就不切換-->
	<dataHost balance="0" maxCon="100" minCon="10" name="localdh" dbType="mysql" dbDriver="jdbc" writeType="0" switchType="1" slaveThreshold="1000">
		<!--查詢心跳-->
		<heartbeat>select user()</heartbeat>
		<!--配置寫節(jié)點(diǎn)實(shí)際物理數(shù)據(jù)庫信息-->
		<writeHost url="jdbc:mysql://localhost:3306" host="host1" password="root" user="root"></writeHost>
	</dataHost>
</mycat:schema>

2)修改rule.xml

在schema.xml中已經(jīng)指定規(guī)則為mod-long。因此需要到該文件中修改對應(yīng)信息。

<tableRule name="mod-long">
    <rule>
        <!--當(dāng)用用于id取模的字段-->
        <columns>user_id</columns>
        <algorithm>mod-long</algorithm>
    </rule>
</tableRule>

<!--修改當(dāng)前的分片數(shù)量-->
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
		<!-- how many data nodes -->
		<!-- 根據(jù)datanode數(shù)量進(jìn)行取模分片,也就是要模幾。 -->
		<property name="count">3</property>
	</function>

3)測試

  • 向數(shù)據(jù)庫中插入一千條數(shù)據(jù),可以發(fā)現(xiàn),其會根據(jù)id取模,放入不同的三張表中。

  • 當(dāng)根據(jù)id查詢時,會通過對id的取模,確定當(dāng)前要查詢的分片。并且首先會先查詢mycat中的ehcache緩存,再來查詢數(shù)據(jù)分片。

  • 當(dāng)查詢所有數(shù)據(jù)時,會查詢所有數(shù)據(jù)分片。

4)缺陷

通過id取模分片這種方式實(shí)際中應(yīng)用較少。主要因?yàn)閮牲c(diǎn)問題:

根據(jù)id取模,1)散列不均勻,出現(xiàn)數(shù)據(jù)傾斜。2)動態(tài)擴(kuò)容時,存在rehash,出現(xiàn)數(shù)據(jù)丟失。

1)數(shù)據(jù)散列不均勻,容易出現(xiàn)數(shù)據(jù)傾斜。每張表中的數(shù)據(jù)量差距較大。

2)動態(tài)擴(kuò)容后,當(dāng)需要新增表時,需要對模數(shù)修改,有可能就會造成當(dāng)查詢某個分片時,在該分片中找不到對應(yīng)數(shù)據(jù)。

3)動態(tài)擴(kuò)容后,要進(jìn)行rehash操作。

4.4、全局序列號

當(dāng)進(jìn)行數(shù)據(jù)切分后,數(shù)據(jù)會存放在多張表中,如果仍然通過數(shù)據(jù)庫自增id的方式,就會出現(xiàn)ID重復(fù)的問題,造成數(shù)據(jù)錯亂。所以當(dāng)拆分完數(shù)據(jù)后,需要讓每一條數(shù)據(jù)都有自己的ID,并且在多表中不能出現(xiàn)重復(fù)。比較常見的會使用雪花算法來生成分布式id。

在Mycat中也提供了四種方式來進(jìn)行分布式id生成:基于文件、基于數(shù)據(jù)庫、基于時間戳和基于ZK。

4.4.1、基于本地文件方式生成

優(yōu)點(diǎn):本地加載,讀取速度較快。

缺點(diǎn):當(dāng)MyCAT重新發(fā)布后,配置文件中的sequence會恢復(fù)到初始值。

?生成的id沒有含義,如時間。

?MyCat如果存在多個,會出現(xiàn)id重復(fù)問題。

1)修改sequence_conf.properties

USER.HISIDS=  #使用過的歷史分段,可不配置
USER.MINID=1  #最小ID值
USER.MAXID=200000  #最大ID值
USER.CURID=1000  #當(dāng)前ID值

2)修改server.xml

<!--設(shè)置全局序號生成方式
   0:文件
   1:數(shù)據(jù)庫
   2:時間戳
   3:zookeeper
  -->
<property name="sequnceHandlerType">0</property>
<!--進(jìn)入序列匹配流程, 必須帶有MYCATSEQ_或者 mycatseq_-->
<property name="sequnceHandlerPattern">(?:(\s*next\s+value\s+for\s*MYCATSEQ_(\w+))(,|\)|\s)*)+</property>
<property name="sequenceHanlderClass">io.mycat.route.sequence.handler.HttpIncrSequenceHandler</property>

3)測試

重啟mycat,并查詢是否修改成功

show @@sysparam

分布式數(shù)據(jù)庫架構(gòu)

通過navicat插入數(shù)據(jù)

insert into tb_user(user_id,user_name) values('next value for MYCATSEQ_USER','wangwu')

通過程序插入數(shù)據(jù)

@Insert("insert into tb_user(user_id,user_name) values('next value for MYCATSEQ_USER',#{userName})")
void addUser(User user);
4.4.2、基于數(shù)據(jù)庫生成

優(yōu)點(diǎn):能夠進(jìn)行id批量生成,在分布式下,可以避免id重復(fù)問題。

缺點(diǎn):ID沒有意義,對數(shù)據(jù)庫有壓力。

1)在實(shí)際數(shù)據(jù)庫執(zhí)行dbseq.sql中的sql語句,執(zhí)行完畢后,會創(chuàng)建一張表。
分布式數(shù)據(jù)庫架構(gòu)

2)修改sequence_db_conf.properties。

TB_USER=localdn

3)修改server.xml文件,修改全局序列號生成方式為數(shù)據(jù)庫方式

<property name="sequnceHandlerType">1</property>

4)修改schema.xml。在table中添加自增屬性

<table name="tb_user" dataNode="localdn" primaryKey="id" subTables="tb_user$1-3" rule="mod-long" autoIncrement="true"/>

5)測試

通過navicat新增記錄

insert into tb_user(user_id,user_name) values('next value for MYCATSEQ_TB_USER','wangwu')

分布式數(shù)據(jù)庫架構(gòu)

4.4.3、基于zookeeper生成

1)修改server.xml,更改生成模式

<property name="sequenceHandlerType">3</property>

2)修改myid.properties,配置zk連接信息

loadZk=true
zkURL=192.168.200.131:2181
clusterId=01
myid=mycat_fz_01
clusterNodes=mycat_fz_01
#server  booster  ;   booster install on db same server,will reset all minCon to 1
#type=server
#boosterDataHosts=localhost1

3)修改sequence_distributed_conf.properties

INSTANCEID=ZK #聲明使用zk生成
CLUSTERID=01

4)測試

啟動mycatServer后,通過zk客戶端查看節(jié)點(diǎn)信息。會發(fā)現(xiàn)新增了一個mycat節(jié)點(diǎn)

./zkCli.sh

ls /

分布式數(shù)據(jù)庫架構(gòu)
插入數(shù)據(jù)

insert into tb_user(user_id,user_name) values('n
ext value for MYCATSEQ_TB_USER12','heima')

next value for MYCATSEQ_ 后的內(nèi)容可以隨意指定。
分布式數(shù)據(jù)庫架構(gòu)

5)特性:

ID 結(jié)構(gòu):long 64 位,ID 最大可占 63 位

* |current time millis(微秒時間戳 38 位,可以使用 17 年)|clusterId(機(jī)房或者 ZKid,通過配置文件配置 5位)|instanceId(實(shí)例 ID,可以通過 ZK 或者配置文件獲取,5 位)|threadId(線程 ID,9 位)|increment(自增,6 位)

* 一共 63 位,可以承受單機(jī)房單機(jī)器單線程 1000*(2^6)=640000 的并發(fā)。

* 無悲觀鎖,無強(qiáng)競爭,吞吐量更高

7.4.4)基于時間戳生成

優(yōu)點(diǎn):不存在上面兩種方案因?yàn)閙ycat的重啟導(dǎo)致id重復(fù)的現(xiàn)象,ID= 64 位二進(jìn)制 (42(毫秒)+5(機(jī)器 ID)+5(業(yè)務(wù)編碼)+12(重復(fù)累加),每毫秒可以并發(fā) 12 位二進(jìn)制的累加。

缺點(diǎn):數(shù)據(jù)類型太長,建議采用bigint(最大取值18446744073709551615)

1)修改server.xml。更改生成方式

<property name="sequenceHandlerType">2</property>

2)修改sequence_time_conf.properties

#sequence depend on TIME
#WORKID與DATAACENTERID: 0-31 任意整數(shù)。多mycat節(jié)點(diǎn)下,每個節(jié)點(diǎn)的WORKID、DATAACENTERID不能重復(fù),組成唯一標(biāo)識,總共支持32*32=1024 種組合
WORKID=01
DATAACENTERID=01

3)測試

新增數(shù)據(jù)

insert into tb_user(user_id,user_name) values('next value for MYCATSEQ_TB_USER12','heima')

next value for MYCATSEQ_ 后的內(nèi)容可以隨意指定。
分布式數(shù)據(jù)庫架構(gòu)

5、MyCat分庫&讀寫分離

之前已經(jīng)基于id取模完成了分表操作,但是一個數(shù)據(jù)庫的容量畢竟是有限制的,如果數(shù)據(jù)量非常大,分表已經(jīng)滿足不了的話,就會進(jìn)行分庫操作。

?當(dāng)前分庫架構(gòu)如下:
分布式數(shù)據(jù)庫架構(gòu)

現(xiàn)在存在兩個主庫,并且各自都有從節(jié)點(diǎn)。 當(dāng)插入數(shù)據(jù)時,根據(jù)id取模放入不同的庫中。同時主從間在進(jìn)行寫時復(fù)制的同時,還要完成主從讀寫分離的配置。

1)修改schema.xml。配置多datenode與datahost。同時配置主從讀寫分離。

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">

    <schema name="userdb" checkSQLschema="true" dataNode="dn09" sqlMaxLimit="500">
        <table name="tb_user" dataNode="dn09,dn10" primaryKey="user_id" rule="mod-long"/>
    </schema>

    
    <dataNode name="dn09" dataHost="dh09" database="user"/>
    <dataNode name="dn10" dataHost="dh10" database="user"/>

    <dataHost name="dh09" balance="1" maxCon="100" minCon="10"  dbType="mysql" dbDriver="jdbc" writeType="0" switchType="1" slaveThreshold="1000">
        <!--查詢心跳-->
        <heartbeat>select user()</heartbeat>
        <!--配置寫節(jié)點(diǎn)實(shí)際物理數(shù)據(jù)庫信息-->
        <writeHost url="jdbc:mysql://192.168.200.142:3309" host="host1"  user="root" password="123456">
            <!--配置讀節(jié)點(diǎn)實(shí)際物理數(shù)據(jù)庫信息-->
            <readHost host="host2" url="jdbc:mysql://192.168.200.145:3309" user="root" password="123456" ></readHost>
        </writeHost>
    </dataHost>

    <dataHost name="dh10" balance="1" maxCon="100" minCon="10"  dbType="mysql" dbDriver="jdbc" writeType="0" switchType="1" slaveThreshold="1000">
        <!--查詢心跳-->
        <heartbeat>select user()</heartbeat>
        <!--配置寫節(jié)點(diǎn)實(shí)際物理數(shù)據(jù)庫信息-->
        <writeHost url="jdbc:mysql://192.168.200.142:3310" host="host1"  user="root" password="123456">
            <!--配置讀節(jié)點(diǎn)實(shí)際物理數(shù)據(jù)庫信息-->
            <readHost host="host2" url="jdbc:mysql://192.168.200.145:3310" user="root" password="123456" ></readHost>
        </writeHost>
    </dataHost>
</mycat:schema>

2)修改rule.xml。配置取模時的模數(shù)

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
    <!-- how many data nodes -->
    <!-- 根據(jù)datanode數(shù)量進(jìn)行取模分片,也就是要模幾。 -->
    <property name="count">2</property>
</function>

3)進(jìn)行批量數(shù)據(jù)添加,可以發(fā)現(xiàn)數(shù)據(jù)落在了不同的庫中。
分布式數(shù)據(jù)庫架構(gòu)
分布式數(shù)據(jù)庫架構(gòu)

4)讀寫分離驗(yàn)證

設(shè)置log4j2.xml的日志級別為DEBUG

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="DEBUG">
		........
        <asyncRoot level="DEBUG" includeLocation="true">
			........
        </asyncRoot>
    </Loggers>
</Configuration>

基于mysql服務(wù)進(jìn)行數(shù)據(jù)查看,觀察控制臺信息,可以看到對于read請求的數(shù)據(jù)源,分別使用的是配置文件的配置。

分布式數(shù)據(jù)庫架構(gòu)
分布式數(shù)據(jù)庫架構(gòu)文章來源地址http://www.zghlxwxcb.cn/news/detail-499699.html

到了這里,關(guān)于分布式數(shù)據(jù)庫架構(gòu)的文章就介紹完了。如果您還想了解更多內(nèi)容,請?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!

本文來自互聯(lián)網(wǎng)用戶投稿,該文觀點(diǎn)僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務(wù),不擁有所有權(quán),不承擔(dān)相關(guān)法律責(zé)任。如若轉(zhuǎn)載,請注明出處: 如若內(nèi)容造成侵權(quán)/違法違規(guī)/事實(shí)不符,請點(diǎn)擊違法舉報進(jìn)行投訴反饋,一經(jīng)查實(shí),立即刪除!

領(lǐng)支付寶紅包贊助服務(wù)器費(fèi)用

相關(guān)文章

  • 火山引擎云搜索服務(wù)升級云原生新架構(gòu);提供數(shù)十億級分布式向量數(shù)據(jù)庫能力

    火山引擎云搜索服務(wù)升級云原生新架構(gòu);提供數(shù)十億級分布式向量數(shù)據(jù)庫能力

    從互聯(lián)網(wǎng)發(fā)展伊始,搜索技術(shù)就綻放出了驚人的社會和經(jīng)濟(jì)價值。隨著信息社會快速發(fā)展,數(shù)據(jù)呈爆炸式增長,搜索技術(shù)通過數(shù)據(jù)收集與處理,滿足信息共享與快速檢索的需求。 云搜索服務(wù) ESCloud 是火山引擎提供的 完全托管在線分布式搜索服務(wù) ,兼容 Elasticsearch、Kibana 等軟

    2024年02月16日
    瀏覽(30)
  • 解釋什么是分布式數(shù)據(jù)庫,列舉幾種常見的分布式數(shù)據(jù)庫系統(tǒng)

    敏感信息和隱私保護(hù)是指在收集、存儲和使用個人數(shù)據(jù)時,需要采取一系列措施來保護(hù)這些數(shù)據(jù)的安全和機(jī)密性,防止數(shù)據(jù)被未經(jīng)授權(quán)的第三方訪問、使用或泄露。這些措施包括加密、訪問控制、數(shù)據(jù)脫敏、數(shù)據(jù)加密、隱私政策等。 在隱私保護(hù)的技術(shù)手段方面,常用的技術(shù)包

    2024年02月08日
    瀏覽(32)
  • 分析型數(shù)據(jù)庫:分布式分析型數(shù)據(jù)庫

    分析型數(shù)據(jù)庫:分布式分析型數(shù)據(jù)庫

    分析型數(shù)據(jù)庫的另外一個發(fā)展方向就是以分布式技術(shù)來代替MPP的并行計(jì)算,一方面分布式技術(shù)比MPP有更好的可擴(kuò)展性,對底層的異構(gòu)軟硬件支持度更好,可以解決MPP數(shù)據(jù)庫的幾個關(guān)鍵架構(gòu)問題。本文介紹分布式分析型數(shù)據(jù)庫。 — 背景介紹— 目前在分布式分析型數(shù)據(jù)庫領(lǐng)域,

    2023年04月14日
    瀏覽(52)
  • 分布式數(shù)據(jù)庫HBase

    分布式數(shù)據(jù)庫HBase

    HBase是一個高可靠、高性能、 面向列 、可伸縮的分布式數(shù)據(jù)庫,是谷歌BigTable的開源實(shí)現(xiàn),主要用來存儲非結(jié)構(gòu)化和把結(jié)構(gòu)化的松散數(shù)據(jù)。 HBase的目標(biāo)是處理非常龐大的表,可以通過水平擴(kuò)展的方式,利用 廉價計(jì)算機(jī)集群 處理由超過10億行數(shù)據(jù)和數(shù)百萬列元素組成的數(shù)據(jù)表。

    2024年02月09日
    瀏覽(25)
  • 【大數(shù)據(jù)】分布式數(shù)據(jù)庫HBase

    【大數(shù)據(jù)】分布式數(shù)據(jù)庫HBase

    目錄 1.概述 1.1.前言 1.2.數(shù)據(jù)模型 1.3.列式存儲的優(yōu)勢 2.實(shí)現(xiàn)原理 2.1.region 2.2.LSM樹 2.3.完整讀寫過程 2.4.master的作用 本文式作者大數(shù)據(jù)系列專欄中的一篇文章,按照專欄來閱讀,循序漸進(jìn)能更好的理解,專欄地址: https://blog.csdn.net/joker_zjn/category_12631789.html?spm=1001.2014.3001.5482 當(dāng)

    2024年04月27日
    瀏覽(29)
  • 分布式數(shù)據(jù)庫-事務(wù)一致性

    分布式數(shù)據(jù)庫-事務(wù)一致性

    version: v-2023060601 author: 路__ 分布式數(shù)據(jù)庫的“強(qiáng)一致性”應(yīng)該包含兩個方面: serializability(串行) and linearizability(線性一致) ,上述圖為“Highly Available Transactions: Virtues and Limitations”論文中對于一致性模型的介紹。圖中箭頭表示一致性模型之間的關(guān)系。對于異步網(wǎng)絡(luò)上的分

    2024年02月08日
    瀏覽(28)
  • 分布式數(shù)據(jù)庫NoSQL(二)——MongoDB 數(shù)據(jù)庫基本操作

    分布式數(shù)據(jù)庫NoSQL(二)——MongoDB 數(shù)據(jù)庫基本操作

    MongoDB 是一個基于分布式文件存儲的數(shù)據(jù)庫。由 C++ 語言編寫。旨在為 WEB 應(yīng)用提供可擴(kuò)展的高性能數(shù)據(jù)存儲解決方案。 MongoDB 是一個介于關(guān)系數(shù)據(jù)庫和非關(guān)系數(shù)據(jù)庫之間的產(chǎn)品,是非關(guān)系數(shù)據(jù)庫當(dāng)中功能最豐富,最像關(guān)系數(shù)據(jù)庫的。它支持的數(shù)據(jù)結(jié)構(gòu)非常松散,是類似 json 的

    2024年02月06日
    瀏覽(33)
  • 11.云原生分布式數(shù)據(jù)庫之TIDB

    11.云原生分布式數(shù)據(jù)庫之TIDB

    云原生專欄大綱 從后端視角、運(yùn)維視角和基礎(chǔ)架構(gòu)視角來看,使用 TiDB 作為數(shù)據(jù)庫系統(tǒng)可以獲得分布式架構(gòu)、高可用性、強(qiáng)一致性、事務(wù)支持、水平擴(kuò)展、高性能、簡化運(yùn)維、靈活的擴(kuò)展和配置、集成的監(jiān)控和告警等優(yōu)勢。這些優(yōu)勢使得 TiDB 成為處理大規(guī)模數(shù)據(jù)和高并發(fā)請求

    2024年02月01日
    瀏覽(26)
  • 分布式數(shù)據(jù)庫Apache Doris簡易體驗(yàn)

    ???????????? 哈嘍!大家好,我是【IT邦德】,江湖人稱jeames007,10余年DBA及大數(shù)據(jù)工作經(jīng)驗(yàn) 一位上進(jìn)心十足的【大數(shù)據(jù)領(lǐng)域博主】!?????? 中國DBA聯(lián)盟(ACDU)成員,目前服務(wù)于工業(yè)互聯(lián)網(wǎng) 擅長主流Oracle、MySQL、PG、高斯及Greenplum運(yùn)維開發(fā),備份恢復(fù),安裝遷移,性能優(yōu)

    2024年02月06日
    瀏覽(29)
  • 聊聊分布式 SQL 數(shù)據(jù)庫Doris(八)

    聊聊分布式 SQL 數(shù)據(jù)庫Doris(八)

    密集索引:文件中的每個搜索碼值都對應(yīng)一個索引值,就是葉子節(jié)點(diǎn)保存了整行. 稀疏索引:文件只為索引碼的某些值建立索引項(xiàng). 稀疏索引的創(chuàng)建過程包括將集合中的元素分段,并給每個分段中的最小元素創(chuàng)建索引。在搜索時,先定位到第一個大于搜索值的索引的前一個索引

    2024年02月05日
    瀏覽(30)

覺得文章有用就打賞一下文章作者

支付寶掃一掃打賞

博客贊助

微信掃一掃打賞

請作者喝杯咖啡吧~博客贊助

支付寶掃一掃領(lǐng)取紅包,優(yōu)惠每天領(lǐng)

二維碼1

領(lǐng)取紅包

二維碼2

領(lǐng)紅包