王 艷
(河南經貿職業學院計算機工程學院 河南 鄭州 450046)
隨著互聯網的高速發展,互聯網上的業務隨之增多,從而也會產生大量的數據。 面對高并發的場景,往往都是讀數據操作遠多于寫數據操作,如果所有的讀寫操作都在同一臺數據庫主機上,勢必會造成該主機負荷過重,同時也對數據安全造成極大威脅。 將數據存放在多臺數據庫主機上,部署數據庫主從架構[1]。 在從數據庫上進行查詢操作,降低主數據庫的訪問壓力,如果主數據庫出現問題,可以快速切換到從數據庫中提供服務,在很大程度上增強了數據庫的安全性[1]。
本文將基于開源的應用容器引擎(docker container,Docker)用來部署關系型數據庫管理系統(my structured query language,MySQL)的主從架構,相較于基于傳統虛擬化架構的數據庫主從同步來說,該部署模式具有快速交付和部署、更簡單的運行維護、更便捷的升級和擴容、更高效的資源利用等一系列優點[2]。
MySQL 是目前國內最流行的關系型數據庫之一,在各企事業單位應用廣泛,針對MySQL 數據主從同步的需求也日益復雜,自3.25 版本開始,MySQL 開始提供復制的功能,通過設置主機服務器和從機認證服務器來實現數據庫主從同步。
根據主機和從機的數量不同,主從服務架構可以分為一主一從、一主多從、雙主機、聯級復制、多主一從的模式。在一主一從服務模式下,從機不僅作為備機使用,還要提供讀數據的數據源,當數據發生增刪改操作時,在主機上執行,并自動同步到從機,如果僅讀數據,則會到從機上執行,從而降低主機的壓力;一主多從的服務模式是對一主一從服務模式的擴展,在實際應用中,單一的從節點在支撐業務查詢數據時存在很大的性能瓶頸,因此,將從機進行水平擴展,實現一主多從,提高查詢效率;雙主機模式即設置兩臺主機,兩臺主機互為對方的從機,共同分擔讀寫壓力;聯級復制與一主多從的服務模式類似,不同的是,聯級復制會設置從機的級別,低級別的從機的數據來源于高級別的從機,從而降低由于從機量增加,對主機造成的性能影響;多主一從的服務模式多應用在寫操作遠遠多于讀操作的業務中,通過設置多臺主機來分擔主機的壓力,同時通過一個特定從機來完成讀操作和數據備份的功能。
本文將采用一主一從的服務模式進行實驗,在該服務模式下,設置主數據庫啟用二進制日志,并設置服務器編號。 當主數據庫發生數據更改時,更新數據的同時還會將該事件寫入主數據庫二進制日志里,從數據庫上的特定輸入/輸出(input/output,I/O)進程會監聽主數據庫上的二進制日志,一旦發生更新,會自動同步到自己的中繼日志中。 此時,從數據庫特定的結構化查詢語言(structured query language,SQL)進程監聽自己的中繼日志,一旦發生改變,自動根據中繼日志中的數據更改操作更新自身數據庫數據。 從而實現將主數據庫的數據庫定義語言(data definition language, DDL) 和數據庫操縱語言( data manipulation language,DML)操作傳輸到從數據庫所在的服務器上,達到主從一致的狀態[3]。
Docker 是基于開源編程語言實現的云開源項目。 它的主要目標是“Build,Ship and Run Any App, Anywhere”,也就是通過對應用組件的封裝、分發、部署、運行等生命周期的管理,使用戶APP 運行環境能夠做到一次封裝,隨處運行[4]。
傳統虛擬機資源占用多、冗余步驟多、啟動慢。 針對以上缺點,Linux 容器虛擬化技術應運而生。 從架構上來說,容器技術并不是模擬一個完整的操作系統,而是對進程進行隔離。 借助容器技術,將軟件運行過程中所需的所有依賴環境進行打包,系統因此而變得高效輕量,并保證部署在任何環境中的軟件都能始終如一地運行[5]。
相較于傳統的虛擬化技術,Docker 容器虛擬化技術具有更快速的應用交付和部署、更便捷的升級和擴縮容、更簡單的系統運維和更高效的計算資源利用4 大優勢[4]。
(1)更快速的應用交付和部署:傳統模式下,應用程序開發完成后,需要提供一系列安裝程序、環境依賴包和配置說明文檔,并且運維人員需要根據配置文檔進行復雜的配置才能正常運行軟件。 如果使用Docker 容器虛擬化技術,只需要交付少量容器鏡像文件,運維人員在測試或部署時,僅加載鏡像并運行即可,和應用程序相關的一系列配置已經提前在鏡像里內置,可以提高應用程序部署測試的效率。
(2)更便捷的升級和擴縮容:隨著微服務架構和Docker的應用和發展,大量的應用會基于微服務的方式進行開發,類似于搭積木,每個Docker 容器將變成一塊“積木”,因此,應用的升級將變得非常容易。 當業務需要升級時,只需要通過鏡像運行新的容器即可進行業務升級或者擴容,使應用系統的更新升級從原先的天級變成分秒級。
(3)更簡單的系統運維:應用軟件使用容器虛擬化技術部署后,可保持開發、測試環境與生產環境的高度一致,容器會將與應用程序有關的依賴庫打包封裝,不會因為依賴環境版本等問題給應用帶來影響。 當程序發生異常時,可以通過測試環境的相同容器進行快速定位和修復。
(4)更高效的計算資源利用:相較于傳統的虛擬化技術來說,Docker 是內核級虛擬化,不需要額外的Hypervisor支持,在一臺物理機上可以運行多個相互隔離的容器實例,能夠提升物理服務器CPU 和內存的利用率。
安裝一臺Host 主機,本文中的主機選用了CentOS 7(64-bit)操作系統,Docker 運行在CentOS 7 上,要求系統為64 位、系統內核版本為3.10 以上,并且配置好該主機的網絡,確保主機可以聯通互聯網。
3.1.1 Docker 安裝
使用阿里云鏡像網站上的Docker 社區版提供的前端軟件包管理器源文件安裝Docker,安裝完成后啟動Docker,并查看Docker 版本,本實驗采用的Docker 版本為24.0.4,安裝完成后,設置開機自啟動,并查驗Docker 的運行狀態為激活(Active)狀態,執行以下命令。
# yum install -y docker-ce
# systemctl start docker
# systemctl enable docker
# systemctl status docker
# docker info
3.1.2 Docker 鏡像加速器配置
使用Docker 需要下載鏡像,鏡像默認在Docker 官方的公共倉庫里下載,由于國內訪問Docker Hub 的速度很不穩定,甚至會出現連接不上的情況,所以需要配置鏡像加速器,本文選取阿里云鏡像加速器。
在阿里云開發網站(https:/ /developer.aliyun.com)進行賬號注冊并登錄,找到容器鏡像服務選項下面的鏡像加速器,根據網站提示,通過修改配置文件/etc/docker/daemon.json 來使用加速器,設置完畢后重啟Docker 使其生效。
Docker 采用數據卷技術來解決數據持久化和數據共享的問題,將宿主機的目錄或者文件與容器中的目錄或者文件進行綁定,一方修改,另一方會立即同步,并且一個數據卷可以被多個容器同時掛載,一個容器也可以被掛載多個數據卷。
本實驗采用mysql:5.7 版本的數據庫,當MySQL 服務啟動時會以/etc/mysql/my. cnf 為配置文件,該文件會導入/etc/mysql/conf. d 目錄中所有以cnf 為結尾的文件。這些文件會拓展或覆蓋/etc/mysql/my. cnf 文件中的配置。 因此需要創建自己需要的配置文件并掛載至MySQL容器中的/etc/mysql/conf.d 目錄。
(1)拉取并運行MySQL:5.7 鏡像,進入容器查看配置目錄/etc/mysql/conf.d ,該目錄下存在3 個配置文件,分別是docker.cnf,mysql.cnf 和mysqldump.cnf,執行以下命令。
[root@ localhost ~]# docker run -itd -e MYSQL_ROOT_PASSWORD=123456--name test mysql:5.7
[root@localhost ~]# docker exec -it 9f43c06b57 bash
root@9f43c06b57c0:/# cd /etc/mysql/conf.d/
(2)將配置目錄/etc/mysql/conf.d 下的3 個配置文件拷貝至宿主機自定義目錄/my/custom01/中,并自定義配置文件/my/custom/config-file. cnf,通過添加log_bin =mysql-bin 設置開啟binlog 日志,并定義sever_id =20,從而實現主從同步功能,執行以下命令。
[root@localhost custom01]#docker cp 9f43c06b57c0:/etc/mysql/conf.d/?.cnf /my/custom01/
[root@localhost custom01]# vim config-file.cnf
(3)自定義/my/custom02/作為從服務器,同樣拷貝配置目錄/etc/mysql/conf.d 下的所有內容,并自定義配置文件/my/custom/config-file. cnf, 與主服務器不同的是,config-file.cnf 中設置server_id=30,其余步驟皆一致。
(4)重新運行MySQL:5.7 鏡像,設置端口映射、目錄映射,將主數據庫容器命名為mysql01,端口映射為3305,從數據庫命名為mysql02,端口映射為3307,執行以下命令。
[root@localhost ~]# docker run -itd --name mysql01-v /my/custom01:/etc/mysql/conf. d -e MYSQL_ROOT_PASSWORD="123456" -p 3305 ∶3306 mysql:5.7
[root@localhost ~]# docker run -itd --name mysql02-v /my/custom02:/etc/mysql/conf. d -e MYSQL_ROOT_PASSWORD="123456" -p 3307 ∶3306 mysql:5.7
(5)通過docker inspect 容器id 命令查看mysql01 和mysql02 兩個容器的id 和ip 地址分別為f52147f7230a,172.17.0.4 和d8df6c775697,172.17.0.6。 進入主數據庫mysql01 容器中,查看配置目錄/etc/mysql/conf. d 下的文件是否正確,查看無誤后,登錄數據庫,創建用戶,設置從數據庫的復制權限,執行以下命令。
root@f52147f7230a:~# cd /etc/mysql/conf.d/
root@f52147f7230a:/etc/mysql/conf.d# ls
config-file.cnf docker.cnf mysql.cnf mysqldump.cnf
root@f52147f7230a:~# mysql -uroot -p123456
mysql>grant all privileges on ?.? to root@'%'
identified by '123456';
mysql>grant replication slave on ?.? to 'user'@'172.17.0.6' identified by '123456';
(6)進入從數據庫mysql02 容器中,查看配置目錄/etc/mysql/conf.d 下的文件是否正確,查看無誤后,登錄數據庫,創建用戶,設置主數據庫,執行以下命令,使用show slave status\G 命令,查看Slave_IO_Running 和Slave_SQL_Running 都為Yes,說明兩個同步線程都正常運行。
root@d8df6c775697:~# mysql -uroot -p123456
mysql>grant all privileges on ?. ? to root@'%' identified by "123456";
mysql>change master to master_host ='172.17.0.4',master_user='user', master_password='123456';
mysql> start slave;
mysql>show slave status\G
在mysql01 容器中創建數據庫test,在該數據庫中創建表company,插入一條記錄,在mysql02 容器中查看數據同步情況。
在主數據庫所在的主機中進行如下操作:
mysql>show databases;
mysql> use test;
mysql> create table company (id int not null primary key, name varchar(50), addr varchar(255));
mysql> insert into company values (1, "xiaohong", "HenanZhengZhou");
mysql> select ?from company;
再從數據庫所在的主機中查看數據是否自動進行了同步,結果如圖1 所示。

圖1 從數據庫數據同步驗證
綜上所述,利用Docker 容器來部署MySQL 數據庫主從同步比在傳統的虛擬機中部署速度更快,且能夠將部署好的容器打包成新的鏡像。 當現有的容器不足以支撐業務處理時,可通過鏡像運行新的容器進行快速擴容,極大地提高了運維管理效率,能更高效地利用計算機中的資源。
由于實驗環境有限,本實驗部署在一臺主機上,在實際生產環境中,需要設置兩臺主機,并設置在同一局域網內,確保可以網絡互聯,分別啟動運行mysql:5.7 鏡像,設置主從數據庫,主數據庫負責寫數據的業務,從數據庫負責查詢操作,能夠真正實現將數據放在不同的兩臺服務器上,實現數據的互為備份,并能夠更好地面對高并發業務,極大地提高工作效率。