- 金融級IT架構(gòu)與運維:云原生、分布式與安全
- 魏新宇等
- 5389字
- 2022-01-14 14:23:08
4.4 容器云上的數(shù)據(jù)庫定制化方案
在本節(jié)中,我們將介紹MySQL在容器云上的定制化。下面先簡單了解一下分布式數(shù)據(jù)庫的發(fā)展。
4.4.1 分布式數(shù)據(jù)庫的發(fā)展
數(shù)據(jù)庫大致經(jīng)歷了三個發(fā)展階段:RDBMS(2008年以前)→NoSQL(2008—2013年)→NewSQL(2013年以后)。
2008年的數(shù)據(jù)庫的數(shù)量級都是GB級別。RDBMS解決了很多復(fù)雜的問題,如join操作、主外鍵等。隨著互聯(lián)網(wǎng)高速發(fā)展,數(shù)據(jù)量增長速度加快,RDBMS無法線性擴(kuò)展,NoSQL應(yīng)運而生。
NoSQL的全稱是Not Only SQL。它的優(yōu)勢包括海量擴(kuò)展能力、讀寫高性能,并且可以與關(guān)系型數(shù)據(jù)庫相輔相成。
NoSQL有以下幾類產(chǎn)品。
- 鍵值(KV)存儲型數(shù)據(jù)庫:Memcached、Redis。
- 列存儲型數(shù)據(jù)庫:Cassadra、HBase。
- 圖形數(shù)據(jù)庫(Graph):Neo4J、InfoGrid、Infinite Graph。
- 文檔型數(shù)據(jù)庫:MongoDB、CouchDB。
MongoDB被大量應(yīng)用在容器上,其典型應(yīng)用場景如下。
- 基于位置的移動搜索應(yīng)用(基于自身地理空間索引)。
- 日志分析平臺(MongoDB自帶高性能的聚合框架)。
- 可以存儲簡歷或投遞關(guān)系等相對復(fù)雜的數(shù)據(jù)結(jié)果,如簡歷庫。
- 存儲用戶數(shù)據(jù)、帖子信息。
NewSQL同時滿足NoSQL以及在線交易事務(wù),是分布式數(shù)據(jù)庫的發(fā)展方向。簡單而言:NewSQL=RDBMS(ACID)+SQL+NoSQL(擴(kuò)展性)。
NewSQL的主要目的是替換傳統(tǒng)數(shù)據(jù)庫的分庫分表,解決如MySQL+MongoDB的大數(shù)據(jù)性能瓶頸、業(yè)務(wù)層邏輯復(fù)雜度的增加(多維度映射)、運維成本高(MySQL 5.5不支持Online DDL操作)、故障切換時間長(30s至1min)、MHA/MMM二次開發(fā)等問題。
NewSQL目前有以下幾種。
- Google的Spanner/F1,不開源。
- TiDB。
- CockroachDB:百度在用。
- OceanBase。
- 華為的GaussDB。
- 騰訊的TDSQL。
在以上幾種NewSQL數(shù)據(jù)庫中,TiDB被廣泛使用,尤其是在容器云上。TiDB已經(jīng)針對OpenShift發(fā)布了TiDB Operator。需要注意的是,TiDB無法直接參與到分布式事務(wù)中,它只是在寫數(shù)據(jù)的時候可以強一致地寫到多個節(jié)點中,即它是按照處理本地事務(wù)的方式實現(xiàn)分布式寫數(shù)據(jù)。TiDB不支持MySQL的存儲過程、觸發(fā)器等。TiDB高度兼容MySQL協(xié)議,支持基于Raft算法的多副本復(fù)制。
4.4.2 MySQL的復(fù)制與高可用
MySQL是一個輕量級數(shù)據(jù)庫,在容器云上部署時,有的客戶會選擇購買第三方服務(wù)商的MySQL容器化服務(wù)和產(chǎn)品,有的客戶會自行構(gòu)建基于容器云的MySQL集群。
要實現(xiàn)MySQL上容器云,需要關(guān)注MySQL兩方面的技術(shù)。
- 復(fù)制技術(shù):主從復(fù)制、半同步復(fù)制、組復(fù)制。
- 高可用技術(shù):MHA、MGR、MySQL InnoDB Cluster。
需要指出的是,MySQL的高可用技術(shù)依賴于MySQL的復(fù)制技術(shù)。下面介紹常用的MySQL的復(fù)制技術(shù)以及高可用技術(shù)。
MySQL有多種復(fù)制技術(shù),廣為使用的復(fù)制技術(shù)主要有以下三種。
- 主從復(fù)制:在這種模式中,主從實例的復(fù)制是異步復(fù)制,主實例可讀寫,從實例可讀。從庫通過I/O線程連接主庫,獲取主庫二進(jìn)制日志寫到本地中繼日志,并更新master-info文件(存放主庫相關(guān)信息),再利用SQL線程執(zhí)行中繼日志。
- 半同步復(fù)制是在第一種主從復(fù)制的基礎(chǔ)上,利用插件完成半同步復(fù)制。對于傳統(tǒng)的主從復(fù)制,不管從庫是否正確獲取到二進(jìn)制日志,主庫都會不斷更新。而對于半同步復(fù)制,只有當(dāng)確認(rèn)了從庫把二進(jìn)制日志寫入中繼日志才會允許提交更新,如果從庫遲遲不返回ACK確認(rèn)信息,則主庫會自動將半同步復(fù)制狀態(tài)取消,進(jìn)入最基本的主從復(fù)制模式。
- 組復(fù)制(MySQL Group Replication,MGR)。MGR是MySQL官方在5.7.17版本引進(jìn)的一個數(shù)據(jù)庫高可用與高擴(kuò)展的解決方案,并于2016年12月正式推出。MGR 在原生復(fù)制技術(shù)之上引入分布式強一致性協(xié)議——Paxos,以插件的方式提供。MySQL官方還基于MGR推出了MySQL InnoDB Cluster,為MySQL提供完整的高可用性解決方案。
常見的幾種MySQL高可用技術(shù)介紹如下。
- MHA(Master High Availability),目前在MySQL高可用方面是一個相對成熟的解決方案,也是一套優(yōu)秀的MySQL高可用性環(huán)境下故障切換和主從提升的高可用軟件。MHA依賴于MySQL的主從復(fù)制技術(shù)。
- 基于MGR實現(xiàn)的高可用。但這種方案的缺點是外部獲得狀態(tài)變更時需要讀取數(shù)據(jù)庫,且外部需要使用LVS、VIP配置。
- MySQL InnoDB Cluster。這是目前MySQL最完整的高可用解決方案,它依賴于MGR復(fù)制技術(shù)。需要注意的是,當(dāng)前直接在OpenShift上實現(xiàn)MySQL InnoDB Cluster的難度還是比較大的。
接下來,我們介紹如何在OpenShift部署純開源、原生的MySQL,以及MySQL容器鏡像的部署方式,以期對想了解在容器云上部署原生MySQL的讀者有一些幫助。
4.4.3 OpenShift提供的MySQL容器鏡像
紅帽O(jiān)penShift提供了MySQL的容器鏡像,最新的版本是MySQL 8.0(截至2021年9月)。如圖4-78所示,第一個鏡像是基于RHEL7實現(xiàn),第二個鏡像是基于RHEL8實現(xiàn)。

圖4-78 紅帽O(jiān)penShift提供的MySQL容器鏡像
我們查看第一個rhel8/mysql-80鏡像的配置文件的部分內(nèi)容,如下所示:
FROM ubi8/s2i-core:rhel8.2 ENV MYSQL_VERSION=8.0 \ APP_DATA=/opt/app-root/src \ HOME=/var/lib/mysql RUN yum -y module enable mysql:$MYSQL_VERSION && \ INSTALL_PKGS="policycoreutils rsync tar gettext hostname bind-utils groff-base mysql-server" && \ yum install -y --setopt=tsflags=nodocs $INSTALL_PKGS && \ rpm -V $INSTALL_PKGS && \ yum -y clean all --enablerepo='*' && \ mkdir -p /var/lib/mysql/data && chown -R mysql.0 /var/lib/mysql && \ test "$(id mysql)" = "uid=27(mysql) gid=27(mysql) groups=27(mysql)" COPY 8.0/root-common / COPY 8.0/s2i-common/bin/ $STI_SCRIPTS_PATH COPY 8.0/root /
從上面內(nèi)容我們可以看出,該鏡像是基于紅帽RHEL8.2的UBI實現(xiàn),并且具備S2I的能力。
接著查看容器鏡像的Package List,如圖4-79所示,可以看到MySQL的版本是8.0.17。

圖4-79 rhel8/mysql-80的Package List
在介紹了OpenShift提供的MySQL容器鏡像后,接下來我們介紹在OpenShift上部署MySQL的4種方式:
- 以命令行方式部署MySQL;
- 以模板方式部署MySQL;
- 使用S2I方式定制化部署MySQL;
- 使用模板部署MySQL主從復(fù)制。
4.4.4 以命令行和模板方式部署MySQL
部署MySQL最簡單的方式是使用podman命令行直接部署(這里我們使用基于RHEL7的mysql8鏡像進(jìn)行驗證):
#podman run -d --nam mysql_database -e MYSQL_USER=user -e MYSQL_PASSWORD=pass -e MYSQL_DATABASE=db -p 3306:3306 rhscl/mysql-80-rhel7
查看運行的MySQL的容器鏡像,結(jié)果如圖4-80所示。

圖4-80 使用命令行直接部署MySQL
但是,在實際生產(chǎn)中直接使用podman命令行運行MySQL容器鏡像顯然是不合適的。此時,我們可以通過模板方式在OpenShift上部署MySQL。在OpenShift中查看MySQL模板,如圖4-81所示。

圖4-81 使用模板方式部署MySQL
該模板的yaml文件的地址為https://github.com/openshift/origin/blob/master/examples/db-templates/mysql-persistent-template.json,感興趣的讀者可以自行查閱更多內(nèi)容。
使用模板傳遞參數(shù),如圖4-82所示。

圖4-82 通過模板傳遞參數(shù)
通過模板創(chuàng)建成功后,可以查看Pod的相關(guān)信息:
# oc get pods |grep -i mysql1 mysql1-1-4mkc4 1/1 Running 0 37m
登錄MySQL Pod查看數(shù)據(jù)庫:
#oc rsh mysql1-1-4mkc4 sh-4.2$ mysql -u root
結(jié)果如圖4-83所示。

圖4-83 查看數(shù)據(jù)庫
通過模板方式部署MySQL很方便,可以傳遞參數(shù),但這種方式無法實現(xiàn)定制化部署。接下來,我們介紹如何使用S2I方式在OpenShift中定制化部署MySQL。
4.4.5 使用S2I方式定制化部署MySQL
接下來,我們展示如何使用S2I構(gòu)建鏡像的方式實現(xiàn)定制化部署MySQL。該鏡像就是本文開頭展示的mysql8.0容器鏡像。在部署時,我們指定源碼地址為https://github.com/sclorg/mysql-container.git。
首先導(dǎo)入紅帽MySQL容器鏡像的ImageStream,以便后續(xù)使用。
#oc import-image rhscl/mysql-80-rhel7 --from=registry.access.redhat.com/rhscl/ mysql-80-rhel7 --confirm –all -n openshift
ImageStream導(dǎo)入成功,如圖4-84所示。

圖4-84 ImageStream導(dǎo)入成功
查看openshift項目中的MySQL ImageStream:
# oc get is -n openshift NAME MAGE REPOSITORY TAGS UPDATED mysql-80-rhel7 8.0,8.0-13,8.0-14,8.0-15,8.0-18,8.0-20 + 16 more... About a minute ago
接下來,利用Imagestream,使用S2I方式定制化部署MySQL容器鏡像:
oc new-app mysql-80-rhel7:8.0-15~https://github.com/sclorg/mysql-container.git \ --name my-mysql-rhel7 \ --context-dir=examples/extend-image \ --env MYSQL_OPERATIONS_USER=opuser \ --env MYSQL_OPERATIONS_PASSWORD=oppass \ --env MYSQL_DATABASE=opdb \ --env MYSQL_USER=user \ --env MYSQL_PASSWORD=pass
查看上面的輸入?yún)?shù)--context-dir,將examples/extend-image目錄對應(yīng)的內(nèi)容注入。接下來,我們分析這個目錄中包含的腳本。
查看GitHub上源碼examples/extend-image中包含的四個子目錄,如圖4-85所示。

圖4-85 查看examples/extend-image子目錄
接下來,我們分析四個子目錄的內(nèi)容。
1)mysql-cfg目錄下包含myconfig.cnf腳本文件,該腳本的內(nèi)容如下:
[mysqld] stored_program_cache = 524288
啟動MySQL容器時,myconfig.cnf將作為mysqld守護(hù)程序的配置注入。
2)mysql-pre-init目錄中包含兩個Shell腳本,80-add-arbitrary-users.sh和90-init-db.sh,二者是在啟動mysqld守護(hù)程序之前執(zhí)行的。腳本中使用了如下變量。
- $ {mysql_flags}變量,在腳本連接到本地運行的守護(hù)程序時使用。
- $ MYSQL_RUNNING_AS_MASTER變量,在使用run-mysqld-master命令運行容器時定義。
- $ MYSQL_RUNNING_AS_SLAVE變量,在使用run-mysqld-slave命令運行容器時定義。
80-add-arbitrary-users.sh的內(nèi)容如下,該腳本用于創(chuàng)建MySQL用戶:
create_arbitrary_users() { # Do not care what option is compulsory here, just create what is specified log_info "Creating user specified by MYSQL_OPERATIONS_USER (${MYSQL_OPERATIONS_USER}) ..." mysql $mysql_flags <<EOSQL CREATE USER '${MYSQL_OPERATIONS_USER}'@'%' IDENTIFIED BY '${MYSQL_OPERATIONS_PASSWORD}'; EOSQL log_info "Granting privileges to user ${MYSQL_OPERATIONS_USER} for ${MYSQL_DATABASE} ..." mysql $mysql_flags <<EOSQL GRANT ALL ON \`${MYSQL_DATABASE}\`.* TO '${MYSQL_OPERATIONS_USER}'@'%' ; FLUSH PRIVILEGES ; EOSQL } if ! [ -v MYSQL_RUNNING_AS_SLAVE ]; then create_arbitrary_users fi
90-init-db.sh的內(nèi)容如下所示,該腳本調(diào)用mysql-data/init.sql腳本創(chuàng)建數(shù)據(jù)庫。
init_arbitrary_database() { local thisdir local init_data_file thisdir=$(dirname ${BASH_SOURCE[0]}) init_data_file=$(readlink -f ${thisdir}/../mysql-data/init.sql) log_info "Initializing the arbitrary database from file ${init_data_file}..." mysql $mysql_flags ${MYSQL_DATABASE} < ${init_data_file} } if ! [ -v MYSQL_RUNNING_AS_SLAVE ] && $MYSQL_DATADIR_FIRST_INIT ; then init_arbitrary_database fi
3)mysql-data目錄中包含init.sql腳本文件,該腳本用于創(chuàng)建數(shù)據(jù)庫表的SQL語句。如下代碼所示,創(chuàng)建名為products的數(shù)據(jù)庫表,并注入數(shù)據(jù),該腳本被90-init-db.sh腳本調(diào)用。
CREATE TABLE products (id INTEGER, name VARCHAR(256), price FLOAT, variant INTEGER); CREATE TABLE products_variant (id INTEGER, name VARCHAR(256)); INSERT INTO products_variant (id, name) VALUES ('1', 'blue'), ('2', 'green');
4)mysql-pre-init目錄中包含80-check-arbitrary-users.sh腳本文件,該腳本用于判斷部署MySQL時是否指定參數(shù),如果不指定,則會提示報錯。
check_arbitrary_users() { if ! [[ -v MYSQL_OPERATIONS_USER && -v MYSQL_OPERATIONS_PASSWORD && -v MYSQL_ DATABASE ]]; then echo "You need to specify all these variables: MYSQL_OPERATIONS_USER, MYSQL_ OPERATIONS_PASSWORD, and MYSQL_DATABASE" return 1 fi } if ! [ -v MYSQL_RUNNING_AS_SLAVE ]; then check_arbitrary_users
我們查看部署結(jié)果,看到MySQL Pod部署成功:
# oc get pods NAME READY STATUS RESTARTS AGE my-mysql-rhel7-1-4v9dk 1/1 Running 0 9m24s my-mysql-rhel7-1-build 0/1 Completed 0 10m my-mysql-rhel7-1-deploy 0/1 Completed 0 9m28s
查看Pod部署的部分日志,我們看到在S2I源碼倉庫定義的腳本被執(zhí)行:
=> sourcing 20-validate-variables.sh ... => sourcing 25-validate-replication-variables.sh ... => sourcing 30-base-config.sh ... ---> 01:39:10 Processing basic MySQL configuration files ... => sourcing 60-replication-config.sh ... => sourcing 70-s2i-config.sh ... ---> 01:39:10 Processing additional arbitrary MySQL configuration provided by s2i ... => sourcing 40-paas.cnf ... => sourcing 50-my-tuning.cnf ... => sourcing myconfig.cnf ... => sourcing 80-check-arbitrary-users.sh ... ---> 01:39:10 Initializing database ... ---> 01:39:10 Running /opt/rh/rh-mysql80/root/usr/libexec/mysqld --initialize --datadir=/var/lib/mysql/data ---> 01:39:17 Starting MySQL server with disabled networking ... ---> 01:39:17 Waiting for MySQL to start ... 2020-05-15T01:39:17.779572Z 0 [Warning] [MY-011070] [Server] 'Disabling symbolic links using --skip-symbolic-links (or equivalent) is the default. Consider not using this option as it' is deprecated and will be removed in a future release. 2020-05-15T01:39:17.782325Z 0 [System] [MY-010116] [Server] /opt/rh/rh-mysql80/ root/usr/libexec/mysqld (mysqld 8.0.13) starting as process 86 => sourcing 40-datadir-action.sh ... ---> 01:39:40 Running datadir action: upgrade-warn ---> 01:39:40 MySQL server version check passed, both server and data directory are version 8.0. => sourcing 50-passwd-change.sh ... ---> 01:39:40 Setting passwords ... => sourcing 80-add-arbitrary-users.sh ... ---> 01:39:41 Creating user specified by MYSQL_OPERATIONS_USER (opuser) ... ---> 01:39:41 Granting privileges to user opuser for opdb ... => sourcing 90-init-db.sh ... ---> 01:39:41 Initializing the arbitrary database from file /opt/app-root/src/ mysql-data/init.sql... ---> 01:39:41 Shutting down MySQL ...
部署成功后,連接部署的數(shù)據(jù)庫,驗證S2I注入的數(shù)據(jù)庫腳本是否執(zhí)行成功:
mysql> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | opdb | | performance_schema | | sys | mysql> use opdb; Database changed
我們看到數(shù)據(jù)庫表products被自動創(chuàng)建:
mysql> show tables; +------------------+ | Tables_in_opdb | +------------------+ | products | | products_variant | +------------------+ 2 rows in set (0.02 sec) mysql> select * from products_variant; +------+-------+ | id | name | +------+-------+ | 1 | blue | | 2 | green | +------+-------+ 2 rows in set (0.00 sec)
從上述執(zhí)行結(jié)果可以看出,在部署MySQL時,S2I注入的腳本被執(zhí)行。
通過使用S2I方式,我們可以實現(xiàn)MySQL的定制化部署,甚至可以把MySQL的復(fù)制配置、數(shù)據(jù)庫數(shù)據(jù)導(dǎo)入的腳本放進(jìn)去。
4.4.6 使用模板部署MySQL主從復(fù)制
MySQL主從復(fù)制可以使用模板進(jìn)行部署。GitHub上有一主一從復(fù)制的模板(https://github.com/davidsajare/FSI-IT-construction/blob/main/Chapter4/mysql_replica.json),我們可以基于這個模板進(jìn)行定制化。需要注意的是,目前這個模板只能在一個OpenShift集群內(nèi)部署MySQL主從復(fù)制,而不能跨OpenShift集群部署主從復(fù)制。
在OpenShift中借鑒該模板部署MySQL主從復(fù)制,首先創(chuàng)建MySQL模板:
#oc apply -f mysql_replica.json -n openshift template.template.openshift.io/mysql-replication-example created # oc get template NAME DESCRIPTION PARAMETERS OBJECTS mysql-replication-example MySQL Replication Example 8 (3 generated) 6
在OpenShift UI界面,選擇創(chuàng)建好的模板,如圖4-86所示。

圖4-86 選擇創(chuàng)建好的模板
傳遞部署MySQL的參數(shù),如圖4-87所示。

圖4-87 使用MySQL模板傳遞參數(shù)
Pod部署成功的效果如下所示:
# oc get pods NAME READY STATUS RESTARTS AGE mysql-master-1-deploy 0/1 Completed 0 8m16s mysql-master-1-fdb9l 1/1 Running 5 8m13s mysql-slave-1-deploy 0/1 Completed 0 8m16s mysql-slave-1-zqjc5 1/1 Running 5 8m12s
分別查看Primary和Replica pod的日志,可以看出主從復(fù)制關(guān)系已經(jīng)建立。
Primary pod: # oc logs -f mysql-master-1-fdb9l 2020-05-15T06:01:28.281730Z 0 [Note] /opt/rh/rh-mysql57/root/usr/libexec/mysqld: ready for connections. Version: '5.7.24-log' socket: '/var/lib/mysql/mysql.sock' port: 3306 MySQL Community Server (GPL) 2020-05-15T06:01:35.879641Z 3 [Note] Start binlog_dump to master_thread_id(3) slave_server(3672989091), pos(, 4) Replica pod: # oc logs -f mysql-slave-1-zqjc5mysql-slave-1-zqjc5 2020-05-15T06:01:35.875170Z 2 [Note] Slave I/O thread for channel '': connected to master 'master@mysql-master:3306',replication started in log 'FIRST' at position 4
查看MySQL的Binlog狀態(tài),顯示正常,如圖4-88所示。

圖4-88 查看MySQL Binlog狀態(tài)
至此,我們完成了MySQL主從復(fù)制在OpenShift上的部署。如果想實現(xiàn)更為復(fù)雜的部署方式,可以基于本節(jié)的模板進(jìn)行修改。
4.4.7 MySQL主從復(fù)制的限制與不足
如前文所述,由于MySQL主從復(fù)制比較容易實現(xiàn),因此被廣泛應(yīng)用于企業(yè)中。但需要注意的是,主從復(fù)制是異步復(fù)制,存在丟數(shù)據(jù)的可能,而數(shù)據(jù)滯后取決于網(wǎng)絡(luò)速度。如果數(shù)據(jù)不一致,就需要手動修復(fù),前提是主庫的Binlog要備份或放置到持久化存儲里,以避免數(shù)據(jù)丟失。
MySQL主從復(fù)制可能出現(xiàn)以下幾種數(shù)據(jù)不一致的情況。
1)從庫出現(xiàn)問題:例如從庫所在容器云的集群出現(xiàn)硬件故障。
2)主庫出現(xiàn)問題:例如主庫所在容器云的集群出現(xiàn)硬件故障。
3)主從庫之間的復(fù)制出現(xiàn)問題:由于網(wǎng)絡(luò)延遲,造成主庫的Binlog沒有及時復(fù)制到從庫中。
針對第一種情況,直接重新創(chuàng)建從庫,與主庫建立新的主從關(guān)系即可。
針對第二種情況,首先中斷復(fù)制關(guān)系,將從庫提升為主庫接受業(yè)務(wù)請求,將Binlog復(fù)制到新的主庫,等到兩個庫數(shù)據(jù)一致時,再恢復(fù)主從關(guān)系。
針對第三種情況,首先查看主庫和從庫的狀態(tài),如果從庫的狀態(tài)是No,說明當(dāng)前從庫未同步,要是主從庫數(shù)據(jù)相差不大,開啟命令同步數(shù)據(jù)就可以了。如果數(shù)據(jù)相差較大,就需要手工復(fù)制Binglog,手工同步數(shù)據(jù)。
針對MySQL跨容器云的方案,比較好的做法是做讀寫分離,這樣不僅可以提升性能,還可以降低主從庫之間數(shù)據(jù)同步的壓力。即主庫做讀寫、從庫做只讀。為了提升性能,我們可以采用一主多從的方案。那么當(dāng)Master掛了以后,選擇哪個Slave提升為主庫?可以根據(jù)哪個從庫上同步的數(shù)據(jù)多,就將其提升為主庫,如圖4-89所示。

圖4-89 MySQL的主從切換
4.4.8 CDC方案的選擇
在容器云中的MySQL主從復(fù)制通常不能跨容器云實現(xiàn)。所以在更為復(fù)雜的跨數(shù)據(jù)中心場景中,我們可以考慮使用CDC(Change Data Capture,變化數(shù)據(jù)捕獲)方案。即獲取MySQL的變化,然后將這些信息導(dǎo)入消息中間件中,從而使另外一個數(shù)據(jù)中心的業(yè)務(wù)消費端可以消費這些數(shù)據(jù)。
目前開源社區(qū)提供了以下幾種CDC方案,各方案對比如表4-6所示。
表4-6 開源社區(qū)幾種CDC的方案對比

綜合對比下,我們推薦使用Debezium方案。Debezium是一個由紅帽贊助的開源項目,它為CDC提供了一個低延遲的流式處理平臺。我們可以安裝并且配置Debezium去監(jiān)控數(shù)據(jù)庫,從而使應(yīng)用可以消費對數(shù)據(jù)庫的每一個行級別(row-level)的更改。在這種工作模式下,只有已提交的更改才是可見的,所以我們不用擔(dān)心事務(wù)(transaction)或者更改被回滾(roll back)。
Debezium為所有的數(shù)據(jù)庫更改事件提供了一個統(tǒng)一的模型,所以應(yīng)用不用擔(dān)心每一種數(shù)據(jù)庫管理系統(tǒng)的錯綜復(fù)雜性。另外,由于Debezium用持久化的、有副本備份的日志來記錄數(shù)據(jù)庫數(shù)據(jù)變化歷史,因此,應(yīng)用可以隨時停止再重啟,而不會錯過它停止運行時發(fā)生的事件,保證了所有事件都能被正確、完全地處理掉。
監(jiān)控數(shù)據(jù)庫,并在數(shù)據(jù)變化的時候獲得通知一直是很復(fù)雜的事情。雖然關(guān)系型數(shù)據(jù)庫的觸發(fā)器可以做到,但是它只對特定的數(shù)據(jù)庫有效,而且通常只能更新數(shù)據(jù)庫內(nèi)的狀態(tài)(無法和外部的進(jìn)程通信)。一些數(shù)據(jù)庫雖然提供了監(jiān)控數(shù)據(jù)變化的API或者框架,但是暫沒有形成一個統(tǒng)一的標(biāo)準(zhǔn),每種數(shù)據(jù)庫的實現(xiàn)方式都是不同的,我們需要掌握大量特定的知識和理解特定的代碼才能很好地運用。所以,確保以相同的順序查看和處理所有更改,同時最小化影響數(shù)據(jù)庫仍然非常具有挑戰(zhàn)性。
Debezium利用Kafka和Kafka Connector實現(xiàn)了自己的持久性、可靠性和容錯性。每一個部署在Kafka Connector的分布式、可擴(kuò)展、容錯性服務(wù)中的Connector負(fù)責(zé)監(jiān)控一個上游數(shù)據(jù)庫服務(wù)器,捕獲所有的數(shù)據(jù)庫更改,然后記錄到一個或者多個Kafka Topic(通常一個數(shù)據(jù)庫表對應(yīng)一個Kafka Topic)中。Kafka可以確保所有這些數(shù)據(jù)更改事件都能夠多副本并且總體上有序(Kafka只能保證一個Topic的單個分區(qū)內(nèi)有序),這樣,更多的客戶端就可以獨立消費同樣的數(shù)據(jù)更改事件,并將對上游數(shù)據(jù)庫系統(tǒng)造成的影響降到很低(如果N個應(yīng)用都直接去監(jiān)控數(shù)據(jù)庫更改,則對數(shù)據(jù)庫的壓力為N,而用Debezium匯報數(shù)據(jù)庫更改事件到Kafka,所有的應(yīng)用都去消費Kafka中的消息,可以將對數(shù)據(jù)庫的壓力降到1)。另外,客戶端可以隨時停止消費,然后重啟,從上次停止消費的地方繼續(xù)消費。每個客戶端可以自行決定它們是否需要exactly-once(嚴(yán)格一次)或者at-least-once(最少一次)消息交付語義保證,并且所有的數(shù)據(jù)庫或者表的更改事件是按照上游數(shù)據(jù)庫發(fā)生的順序被交付的。
如果不需要這種容錯級別、性能、可擴(kuò)展性、可靠性的應(yīng)用,也可以使用內(nèi)嵌的Debezium Connector引擎直接在應(yīng)用內(nèi)部運行Connector。雖然這種應(yīng)用仍需要消費數(shù)據(jù)庫更改事件,但我們更希望將Connector直接傳遞給它,而不是持久化到Kafka里。
Debezium支持的數(shù)據(jù)庫有MySQL、PostgreSQL、MongoDB、Microsoft SQL Server、Oracle、Apache Cassandra。
Debezium依賴于Kafaka。通過Debezium可以捕獲容器化MySQL的變化數(shù)據(jù),其架構(gòu)圖如圖4-90所示。

圖4-90 Debezium捕獲MySQL變化數(shù)據(jù)的架構(gòu)圖
目前Debezium支持的插件如圖4-91所示。

圖4-91 Debezium支持的插件
如果想了解更多Debezium的具體實現(xiàn)效果,請關(guān)注“大魏分享”公眾號中的文章《CDC(變化數(shù)據(jù)捕獲)在Kubernetes上的實現(xiàn)》。
- 中臺架構(gòu)與實現(xiàn):基于DDD和微服務(wù)
- IT服務(wù)供應(yīng)鏈協(xié)調(diào)
- 微服務(wù)治理:體系、架構(gòu)及實踐
- 數(shù)據(jù)科學(xué)家訪談錄
- 微信公眾平臺搭建與開發(fā)揭秘(第2版)
- SRv6網(wǎng)絡(luò)編程:開啟IP網(wǎng)絡(luò)新時代
- IT項目管理理論與方法
- Axure RP8 網(wǎng)站和APP原型制作 從入門到精通
- IT能力與企業(yè)信息化
- IT服務(wù)管理及CMMI-SVC實施
- IT與項目管理軟件應(yīng)用
- 日志管理與分析(第2版)
- 云計算解碼
- 軟件架構(gòu)師的12項修煉
- 用戶思維+:好產(chǎn)品讓用戶為自己尖叫