mysql 主從復制和讀寫分離

centos 7 安裝mysql ,并配置主從復制 讀寫分離

安裝mysql

1.準備兩臺虛擬機

  • ip地址 : 192.168.0.101 , 102.168.0.102
  • 系統版本 : centos 7
  • mysql : 8.0.12
  • nycat : 1.6.5

下載安裝mysql

使用yum庫進行安裝, 在https://dev.mysql.com/downloads/repo/yum/ 選擇安裝的版本

  1. 使用 wget https://repo.mysql.com//mysql80-community-release-el7-1.noarch.rpm 進行下載

  2. 下載完成后,使用 yum localinstall platform-and-version-specific-package-name.rpm , 并將 platform-and-version-specific-package-name 替換為下載的RPM包

  3. yum repolist enabled | grep "mysql.-community." 使用此命令查看yum存儲庫是否成功添加。

  4. yum install mysql-community-server 使用此命令安裝mysql,之后是漫長的等待時間。

  5. 安裝完成之后,就是啟動mysql 了,命令如下:systemctl start mysqld.service ,systemctl status mysqld.service 使用此命令查看運行狀態,出現如下,表示mysql啟動成功

mysqld.service - MySQL Server
   Loaded: loaded (/usr/lib/systemd/system/mysqld.service; enabled; vendor preset: disabled)
   Active: **active (running)** since 六 2018-09-15 22:05:45 CST; 20s ago
     Docs: man:mysqld(8)
           http://dev.mysql.com/doc/refman/enusingsystemd.html
  Process: 1335 ExecStartPre=/usr/bin/mysqld_pre_systemd (code=exited, status=0/SUCCESS)
 Main PID: 1403 (mysqld)
   Status: "SERVER_OPERATING"
   CGroup: /system.slice/mysqld.service
           └─1403 /usr/sbin/mysqld

  1. 使用此命令 獲取登陸的默認密碼: grep "password" /var/log/mysqld.log

  2. 我們使用 mysql -u root -p 登陸

  3. ALTER USER 'root'@'localhost' IDENTIFIED BY 'MyNewPass4!'; 設置新密碼

  4. 開啟遠程訪問:

    • use mysql
    • update user set host = '%' where user = 'root';
    • FLUSH PRIVILEGES;

至此, 我們已經成功安裝了mysql, 并可以遠程訪問了

但是有一部還沒有做,一般是不提供root用戶的信息直接進行訪問,需要提供一個單獨的用戶進行遠程復制,可使用如下命令,進行用戶的創建,并授權,這里我給了slave用戶全部的權限, 可以只給部分的權限.

mysql> create user 'slave'@'%' IDENTIFIED by '123456';
mysql> grant all PRIVILEGES on *.* to 'slave'@'%';
mysql> flush privileges

主從復制配置

實現主從復制的主要思路是,A主mysql開啟二進制日志,B從mysql讀取日志,并同步執行。一般都是主從同步,主主同步不推薦使用。

主從復制的方式:

  • 基于日志
  • 基于GTID(全局事務標識符)

主要說采用日志實現主從復制的方式。

主從復制的原理:

  • Master將數據改變的記錄到二進制(binary log)中, 也就是配置文件log-bin指定的文件名
  • slave 通過 i/o 線程讀取master中binary log events 內容,并寫入到slave的中繼日志中
  • slave 重做中繼日志事件,把中繼日志的事件信息一條一條的在本地執行一次,完成數據庫的本地存儲,從而實現數據的復制操作。

配置Master主機文件,修改 /etc/my.cnf:

  • server-id=1 #值唯一
  • log-bin=master-bin #開啟二進制日志文件
    修改完配置后, 使用systemctl restart mysqld.service 重啟服務

配置slave主機文件,修改 /etc/my.cnf:

  • server-id=2
  • binlog_format=mixed #主從復制模式

修改完配置后, 使用systemctl restart mysqld.service 重啟服務

登陸mysql的命令行,輸入:
mysql>
change master to
master_user='root',
master_password='123456',
master_host='192.168.0.101',
master_port=3306,
master_log_file='xxxx',
master_log_pos=xxx;

對上面的參數進行解釋:

  • master_host: master主機ip
  • master_user : master用戶
  • master_password:master密碼
  • master_port:master端口號
  • master_log_file : #指定slave從哪個文件讀取數據,可以在master服務器上,使用命令show master status 查看
  • master_log_pos : 從那個position 號開始讀取

查看主從同步的狀態命令

mysql> show slave status\G;

上面的配置完成后,開啟主從同步模式,命令如下:
mysql>start slave ;

當使用 show slave status\G命令,主要看下面的兩個參數:

  • Slave_IO_Running:yes
  • Slave_SQL_Runing:yes
    兩個參數的值都是yes就表示主從復制的模式是正常的。

如果遇到同步出錯,可以重置主從復制設置:
mysql>reset slave ;
mysql> change ....

可使用如下命令,停止主從模式:
mysql>stop slave ;

總結:
上面所搭建的是單向的主從模式,也是使用的比較多的,而雙向主從其實就是master和slave都開啟日志功能,然后再master執行授權用戶,再在master上進行change master操作。

主從同步延時問題調優:
  • 網絡延遲
  • master負載過高
  • slave負載過高
    采用多臺slave來分攤讀請求 , 在單獨配置一臺slave做備份用。不進行其它任何的操作,已做到最大限度地實時請求。

讀寫分離

主要思路是使用mycat中間件,轉發sql指令到mysql節點,mycat不負責數據庫同步。 mycat原理中最重要的一個詞是“攔截” , 它攔截了用戶發送過來的SQL語句,首先對SQL語句做了一些特定的分析,如分片分析,路由分析,讀寫分離分析,緩存分析等,然后將此SQL發往后端的真實數據庫,并將返回的結果做適當的處理, 最終在返回給用戶。

應用場景
  • 單純的讀寫分離,此時的配置最為簡單,支持讀寫分離,主從切換
  • 分庫分表,對于超過1000萬的表進行分片,最大支持1000億的單表分片
  • 多租戶應用
  • 報表系統,處理大規模的報表統計
  • 替代hbase,分析大數據
  • 作為海量數據實時查詢的一種簡單有效方案

mycat 安裝:

  • 下載安裝,我就不在贅述了,很簡單,找到tar包,解壓就可以了。有一點需要注意的是,mycat運行需要jdk環境,并且版本要在1.7+。

配置:
需要配置三個文件,server.xml , rule.xml ,schema.xml

  • server.xml ,配置訪問用戶及權限
 //定義了兩個用戶,root和user為訪問mycat的用戶,并配置了密碼,TESTDB為mycat的虛擬庫,供上層使用,其中user用戶為只讀用戶
 <user name="root" defaultAccount="true">
   <property name="password">123456</property>
   <property name="schemas">TESTDB</property>
 </user>
 <user name="user">
   <property name="password">user</property>
   <property name="schemas">TESTDB</property>
   <property name="readOnly">true</property>
 </user>
  • schema.xml 是主要的配置文件,它主要分為三個部分,schema ,dataNode ,dataHost 。
<schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema>
    <dataNode name="dn1" dataHost="localhost1" database="school" />
    <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
        <heartbeat>select user()</heartbeat>
         <writeHost host="192.168.0.101" url="192.168.0.101:3306" user="root" password="123456">
            <readHost host="192.168.0.102" url="192.168.0.102:3306" user="root" password="123456" />
            </writeHost>
    </dataHost>
  • rule.xml : 這里沒有用到數據分片的規則,所以rule.xml可以不配

啟動 : 兩種方式

  • mycat start
  • ./startup_nowrap.sh
微信截圖_20180918101350.png

出現如下信息,代表鏈接成功了。

問題:

  1. Host '192.168.0.101' is blocked because of many connection errors

默認的max_connection_errors的值為10 ,這個值太低導致了數據庫阻塞了, 可以先使用命令 show global variables like '%max_connect_errors%'; 查看connect_errors的值,然后再使用命令 set global max_connect_errors=1000 來解決, 當然也可以修改配置文件,my.cnf 中添加如下, max_connections=1000 , max_connect_errors = 1000 , wait_time=30 , 還有一種簡單的方法,就是把基數清除掉 flush hosts , 但是不要忘了重啟mycat

  1. unknown charsetIndex : 255


    微信截圖_20180918095812.png

修改 conf/index_to_charset.properties ,在最后添加如下配置,255=utf8mb4 ,值為utf8mb4,是因為它是我mysql的默認字符集

  1. client does not support authentication protocol request by server, consider upgrading mysql client


    微信截圖_20180918095945.png

use mysql ; alter USER 'root'@'%' identified with mysql_native_password by 'Huoyan@123'; FLUSH PRIVILEGES; 使用此命令修改密碼 。 之所以出現這個問題,是因為新版本的mysql更改了密碼的驗證機制, 使用以上命令, 更改為舊密碼的驗證方式就可以了。 當然你也可以降低mysql的版本 。

至此, mysql的主從復制和讀寫分離我們已經搭建完成了 。至于驗證的步驟我就不在贅述了,感興趣的可以自己去研究一下, 有環境了就可以探索它的奧秘了。

?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容