DB讀寫分離描述
數據庫的讀寫分離其實就是爲了加減小數據庫的壓力;數據庫的寫入操做由主數據庫來進行,讀取操做由從數據庫來進行操做。html
實現數據庫讀寫分離技術是有不少方法的,在這裏我就用一個比較簡單的mysql-proxy這個中間件來實現數據庫的讀寫分離;python
使用mysql-proxy實現mysql的讀寫分離,mysql-proxy其實是做爲後端mysql主從服務器的代理,它直接接受客戶端的請求,對SQL語句進行分析,判斷出是讀操做仍是寫操做,而後分發至對應的mysql服務器上。mysql
數據庫讀寫分離比較實用的還有Amoeba等相關程序。linux
基本環境
此環境須要三臺主機(能夠是虛擬主機)
Linux 操做系統 版本: CentOS8.0
軟件版本:
數據庫: mariadb
lua: lua.X86_64
mysql-proxy: mysql-proxy-0.8.5git
這裏由於須要用三臺主機,電腦配置有點上愁,因此我這裏就使用容器(docker)代替三臺虛擬主機了sql
root@uduntu:~# docker ps -a CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 8aea2ebdf1a5 centos "/sbin/init" 12 minutes ago Up 11 minutes mysql-proxy 9a24bbeec012 centos "/sbin/init" 13 minutes ago Up 12 minutes DB2 5495e5cf36c3 centos "/sbin/init" 37 minutes ago Up 37 minutes DB1 root@uduntu:~#
這三個容器,IP地址分別是:docker
①DB1: 172.18.0.2數據庫
②DB2: 172.18.0.3ubuntu
③mysql-proxy: 172.18.0.4後端
好了基礎環境已經介紹完成了,接下來開始真正的部署操做吧!
數據庫部署
MariaDB描述:
MariaDB數據庫管理系統是MySQL的一個分支,主要由開源社區在維護,採用GPL受權許可 MariaDB的目的是徹底兼容MySQL,包括API和命令行,使之能輕鬆成爲MySQL的代替品。
MariaDB基於事務的Maria存儲引擎,替換了MySQL的MyISAM存儲引擎,它使用了Percona的 XtraDB,InnoDB的變體,分支的開發者但願提供訪問即將到來的MySQL 5.4 InnoDB性能。
這個版本還包括了 PrimeBase XT (PBXT) 和 FederatedX存儲引擎。
安裝
[root@DB1 /]# apt -y install mariadb-server Setting up mariadb-client-10.3 (1:10.3.17-1) ... Setting up libdbd-mysql-perl:amd64 (4.050-2build1) ... Setting up libhtml-parser-perl (3.72-3build2) ... Setting up mariadb-server-10.3 (1:10.3.17-1) ... Created symlink /etc/systemd/system/mysql.service → /lib/systemd/system/mariadb.service. Created symlink /etc/systemd/system/mysqld.service → /lib/systemd/system/mariadb.service. Created symlink /etc/systemd/system/multi-user.target.wants/mariadb.service → /lib/systemd/system/mariadb.service. Setting up libhttp-message-perl (6.18-1) ... Setting up libcgi-pm-perl (4.44-1) ... Setting up libhtml-template-perl (2.97-1) ... Setting up mariadb-server (1:10.3.17-1) ... Setting up libcgi-fast-perl (1:2.15-1) ... Processing triggers for systemd (242-7ubuntu3) ... Processing triggers for man-db (2.8.7-3) ... Processing triggers for libc-bin (2.30-0ubuntu2) ... jia@uduntu:~$ \\出現上面代碼表示安裝成功
啓動
[root@DB1 /]# systemctl start mariadb ==== AUTHENTICATING FOR org.freedesktop.systemd1.manage-units === Authentication is required to start 'mariadb.service'. Authenticating as: jia Password: \\此處輸入密碼 ==== AUTHENTICATION COMPLETE === [root@DB1 /]#
查看是否啓動成功:
[root@DB1 /]# mysql_secure_installation \\下面是初始化過程 NOTE: RUNNING ALL PARTS OF THIS SCRIPT IS RECOMMENDED FOR ALL MariaDB SERVERS IN PRODUCTION USE! PLEASE READ EACH STEP CAREFULLY! In order to log into MariaDB to secure it, we'll need the current password for the root user. If you've just installed MariaDB, and you haven't set the root password yet, the password will be blank, so you should just press enter here. Enter current password for root (enter for none): OK, successfully used password, moving on... Setting the root password ensures that nobody can log into the MariaDB root user without the proper authorisation. Set root password? [Y/n] y New password: Re-enter new password: Password updated successfully! Reloading privilege tables.. ... Success! By default, a MariaDB installation has an anonymous user, allowing anyone to log into MariaDB without having to have a user account created for them. This is intended only for testing, and to make the installation go a bit smoother. You should remove them before moving into a production environment. Remove anonymous users? [Y/n] y ... Success! Normally, root should only be allowed to connect from 'localhost'. This ensures that someone cannot guess at the root password from the network. Disallow root login remotely? [Y/n] y ... Success! By default, MariaDB comes with a database named 'test' that anyone can access. This is also intended only for testing, and should be removed before moving into a production environment. Remove test database and access to it? [Y/n] y - Dropping test database... ... Success! - Removing privileges on test database... ... Success! Reloading the privilege tables will ensure that all changes made so far will take effect immediately. Reload privilege tables now? [Y/n] y ... Success! Cleaning up... All done! If you've completed all of the above steps, your MariaDB installation should now be secure. Thanks for using MariaDB! [root@DB1 /]#
初始化完成後,可直接使用自帶的mysql客戶端進行鏈接
[root@DB1 /]# mysql -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 56 Server version: 10.3.17-MariaDB-1 Ubuntu 19.10 Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | ifnormation_schema | | mysql | | performance_schema | +--------------------+ rows in set (0.000 sec) MariaDB [(none)]>
DB2數據庫同DB1數據庫同樣,一樣方法安裝mariadb數據庫就能夠哦!我這裏就省略不寫了
MySQL-Proxy部署
MySQL-Proxy軟件須要部署到單獨的mysql-proxy服務器上的。
安裝依賴軟件
MySQL-Proxy中含有一個讀寫分離的lua文件,這也是咱們使用mysql-proxy實現讀寫分離必用的文件,它須要lua解析器進行解析。
所以咱們須要安裝一個lua解析器。
[root@mysql-proxy /]# yum -y install lua* mdadm-4.1-4.el8.x86_64 mozjs52-52.9.0-1.el8.x86_64 mtools-4.0.18-14.el8.x86_64 nfs-utils-1:2.3.3-14.el8_0.2.x86_64 numactl-libs-2.0.12-2.el8.x86_64 numad-0.5-26.20150602git.el8.x86_64 parted-3.2-36.el8.x86_64 pciutils-3.5.6-4.el8.x86_64 pciutils-libs-3.5.6-4.el8.x86_64 policycoreutils-2.8-16.1.el8.x86_64 polkit-0.115-6.el8.x86_64 polkit-libs-0.115-6.el8.x86_64 polkit-pkla-compat-0.1-12.el8.x86_64 psmisc-23.1-3.el8.x86_64 python3-dateutil-1:2.6.1-6.el8.noarch python3-dnf-plugins-core-4.0.2.2-3.el8.noarch quota-1:4.04-10.el8.x86_64 quota-nls-1:4.04-10.el8.noarch rdma-core-22-2.el8.x86_64 rpcbind-1.2.5-3.el8.x86_64 syslinux-6.04-1.el8.x86_64 syslinux-extlinux-6.04-1.el8.x86_64 syslinux-extlinux-nonlinux-6.04-1.el8.noarch syslinux-nonlinux-6.04-1.el8.noarch systemd-container-239-13.el8.x86_64 userspace-rcu-0.10.1-2.el8.x86_64 xml-common-0.6.3-50.el8.noarch Complete! [root@mysql-proxy /]# \\出現以上輸出表示安裝成功
安裝Mysql-Proxy
在安裝完成lua以後,咱們就能夠安裝今天的主角軟件了
[root@mysql-proxy opt]# ls mysql-proxy-0.8.5-linux-rhel5-x86-64bit.tar.gz [root@mysql-proxy opt]# //上面軟件就是咱們的主角軟件
安裝軟件包
#安裝軟件包 #將安裝包解壓 [root@mysql-proxy opt]# tar zxf mysql-proxy-0.8.5-linux-rhel5-x86-64bit.tar.gz #解壓後的目錄 [root@mysql-proxy mysql-proxy-0.8.5-linux-rhel5-x86-64bit]# ls bin include lib libexec licenses share # 更更名稱,方便以後對其進行操做 [root@mysql-proxy opt]# mv mysql-proxy-0.8.5-linux-rhel5-x86-64bit mysql-proxy #將mysql-proxy中lua配置文件cp到軟件根目錄 [root@mysql-proxy mysql-proxy]# cp share/doc/mysql-proxy/rw-splitting.lua . #再次查看目錄結構 [root@mysql-proxy mysql-proxy]# ls bin include lib libexec licenses rw-splitting.lua share #修改lua配置文件,只須要修改下面代碼就能夠 if not proxy.global.config.rwsplit then proxy.global.config.rwsplit = { min_idle_connections = 4, //此處值改成1 max_idle_connections = 8, //此處值改成1 is_debug = false } #修改完成後保存退出,啓動mysql-proxy [root@mysql-proxy mysql-proxy]# cd bin/ //切換目錄 [root@mysql-proxy bin]# ./mysql-proxy --proxy-read-only-backend-addresses=172.18.0.3:3306 --proxy-backend-addresses=172.18.0.2:3306 --proxy-lua-script=/opt/mysql-proxy/rw-splitting.lua & [1] 5680 [root@mysql-proxy bin]# 2019-11-20 09:26:54: (critical) plugin proxy 0.8.5 started [root@mysql-proxy bin]# #啓動成功
注意:
–proxy-read-only-backend-addresses //指定執行讀取操做的數據庫IP地址以及端口
–proxy-backend-addresses //指定執行寫入操做的數據庫IP地址以及端口
–proxy-lua-script //指定mysql-proxy軟件中lua配置文件路徑
#查看是否啓動成功 [root@mysql-proxy bin]# ps aux | grep mysql-proxy root 5680 0.0 0.5 38428 3696 pts/1 S 09:26 0:00 /opt/mysql-proxy/libexec/mysql-proxy --proxy-read-only-backend-addresses=172.18.0.3:3306 --proxy-backend-addresses=172.18.0.2:3306 --proxy-lua-script=/opt/mysql-proxy/rw-splitting.lua #出現第一行表示啓動成功
接下來須要爲mysql-proxy程序建立能夠讀取和寫入數據庫的用戶
[root@DB2 /]# [root@DB2 /]# mysql -u root -p //登錄數據庫 Enter password: //輸入數據庫密碼 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 16 Server version: 10.3.11-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> grant all on *.* to 'proxy'@'%' identified by 'redhat'; //建立用戶並設置權限 Query OK, 0 rows affected (0.105 sec) MariaDB [(none)]> flush privileges; //更新權限列表 Query OK, 0 rows affected (0.090 sec) MariaDB [(none)]>
注意:用戶須要在兩個數據庫上建立,名稱密碼要一致;
繼續看 :測試
好了到這裏,數據庫的部署,以及使用代理對數據庫的讀寫進行限制已經作好了其實也並無複雜,接下來讓咱們測試一下。
#找一個客戶端,宿主機也能夠,安裝一個數據庫客戶端或則數據庫的鏈接工具進行鏈接,我這裏就使用mysql客戶端進行測試了 root@uduntu:~# mysql -uproxy -predhat -h 172.18.0.4 -P4040 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 21 Server version: 10.3.11-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> #查看到登錄數據庫表示鏈接成功
注意:
①mysql -uproxy -predhat -h 172.18.0.4 -P4040
②其中-u指的是數據庫的用戶名;
③-p指的是密碼;
④-h指定mysql-proxy的服務器地址;
⑤-P表示mysql-proxy的端口
接下來咱們試着建立一個數據庫看下效果:
DB1數據庫默認所擁有的數據庫
[root@DB1 /]# mysql -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 22 Server version: 10.3.11-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show databases ; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ rows in set (0.197 sec) MariaDB [(none)]>
DB2數據庫默認所擁有的數據庫:
[root@DB2 /]# mysql -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 17 Server version: 10.3.11-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ rows in set (0.275 sec) MariaDB [(none)]>
使用代理mysql-proxy建立新數據庫:
root@uduntu:~# root@uduntu:~# mysql -uproxy -predhat -h 172.18.0.4 -P4040 Welcome to the MariaDB monitor. Commands end with ; or \g. Your MariaDB connection id is 21 Server version: 10.3.11-MariaDB MariaDB Server Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MariaDB [(none)]> create database test; //建立test數據庫 Query OK, 1 row affected (0.056 sec) MariaDB [(none)]>
查看DB1數據庫:發現多了test數據庫
MariaDB [(none)]> show databases ; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | +--------------------+ rows in set (0.001 sec) MariaDB [(none)]>
查看DB2數據庫:發現沒有新的數據庫;
MariaDB [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | +--------------------+ rows in set (0.000 sec) MariaDB [(none)]>
OK搞定,說明數據庫只是往DB1裏面寫數據庫並不往DB2中寫入數據
優化MySQL-Proxy
你會發如今啓動mysql-proxy時須要寫那麼多東西,須要指定兩個參數,每次啓動都要寫太麻煩了,爲了解決這個問題, 在這裏寫了一個啓動腳本,但願能夠幫到你們。
#!/bin/sh # chkconfig: - 98 44 # processname: mysql-proxy # description: mysql-proxy is a proxy daemon to mysql . /etc/rc.d/init.d/functions PROXY_PATH=/opt/mysql-proxy/bin prog="mysql-proxy" . /etc/sysconfig/network [ ${NETWORKING} = "no" ] && exit 0 PROXY_OPTIONS="--proxy-read-only-backend-addresses=172.18.0.3:3306 --proxy-backend-addresses=172.18.0.2:3306 --proxy-lua-script=/opt/mysql-proxy/rw-splitting.lua" PROXY_PID=/opt/mysql-proxy/run/mysql-proxy.pid if [ -f /etc/sysconfig/mysql-proxy ]; then . /etc/sysconfig/mysql-proxy fi PATH=$PATH:/usr/bin:/opt/bin:$PROXY_PATH RETVAL=0 case "$1" in start) echo -n $"Starting $prog: " $NICELEVEL $PROXY_PATH/mysql-proxy $PROXY_OPTIONS --daemon --pid-file=$PROXY_PID --user=root --log-level=debug --log-file=/opt/mysql-proxy/log/mysql-proxy.log RETVAL=$? echo if [ $RETVAL = 0 ]; then touch /var/lock/subsys/mysql-proxy] echo "ok" fi ;; stop) echo -n $"Stopping $prog: " killproc $prog RETVAL=$? echo if [ $RETVAL = 0 ]; then rm -f /var/lock/subsys/mysql-proxy rm -f $PROXY_PID fi ;; restart) $0 stop sleep 3 $0 start ;; condrestart) [ -e /var/lock/subsys/mysql-proxy ] && $0 restart ;; status) status mysql-proxy RETVAL=$? ;; *) echo "Usage: $0 {start|stop|restart|status|condrestart}" RETVAL=1 ;; esac exit $RETVAL
將mysql-proxy服務管理腳本放在了/opt/mysql-proxy/init.d/文件夾裏
給執行權限,創建相應目錄
[root@mysql-proxy ~]chmod +x /opt/mysql-proxy/init.d/mysql-proxy [root@mysql-proxy ~]mkdir /opt/mysql-proxy/run [root@mysql-proxy ~]mkdir /opt/mysql-proxy/log [root@mysql-proxy ~]cd /opt/mysql-proxy/init.d/ 啓動mysql-proxy [root@mysql-proxy init.d ~]./mysql-proxy start 中止mysql-proxy [root@mysql-proxy init.d ~]./mysql-proxy stop 重啓mysql-proxy [root@mysql-proxy init.d~]./mysql-proxy restart
這樣啓動中止mysql-proxy就很簡單了,在這裏提醒你們一下,單獨的數據庫讀寫分離是沒有任何做用的,只有結合數據主從複製來進行纔有意義。