小阿軒yx-案例:MySQL主從復制與讀寫分離

小阿軒yx-案例:MySQL主從復制與讀寫分離

案例分析

概述

實際生產環境中

  • 如果對數據庫讀和寫都在同一個數據庫服務器中操作,無論在安全性、高可用性還是高并發等各個方面都完全不能滿足實際需求
  • 一般都是通過主從復制(Master-Slave)同步數據
  • 再通過讀寫分離來提升數據庫并發負載能力進行部署與實施

案例前置知識點

MySQL 主從復制原理
  • MySQL 主從復制和 MySQL 讀寫分離兩者有緊密聯系
  • 首先部署主從復制,才能在此基礎上進行數據的讀寫分離
MySQL 支持的復制類型

基于語句復制

  • 在主服務器上執行的 SQL 語句,在從服務器上執行同樣的語句

MySQL 默認采用基于語句的復制,效率比較高

基于行的復制

  • 把改變的內容復制過去,而不是把命令在從服務器上執行一遍

混合類型的復制

  • 默認采用基于語句的復制,一旦發現基于語句無法精準復制時,就會采用基于行的復制
復制的工作過程

  • 每個事物更新數據完成之前,Master 將這些改變記錄進二進制日志。寫入二進制日志完成后,Master 通知存儲引擎提交事務
  • Slave 將 Master 的 Binary log 復制到其中繼日志(Relay log)
  • SQL slave thread(SQL 從線程)處理該過程的最后一步

復制過程有一個很重要的限制,即復制在Slave上時串行化的,也就是說Master上的并行更新操作不能在 Slave 上并行操作

MySQL 讀寫分離原理
  • 簡單說,讀寫分離就是只在主服務器上寫,只在從服務器上讀。
  • 讓主數據庫處理事務性查詢,而數據庫處理 select 查詢。
  • 數據庫復制被用來把主數據庫上事務性查詢導致的變更同步到集群中的從數據庫。

目前較為常見的 MySQL 讀寫分離分為兩種
基于程序代碼內部實現

在代碼中根據 select、insert 進行路由分類,這類方法也是目前生產環境應用最廣泛的

優點

  • 性能較好
  • 在程序代碼中實現
  • 不需要增加額外的設備作為硬件開支

缺點

  • 需要開發人員來實現
  • 運維人員無從下手
基于中間代理層實現
  • 一般位于客戶端和服務器之間,代理服務器接到后端請求后通過判斷轉發到后端數據庫

兩個代表性程序

MySQL-Proxy

  • 為 MySQL 開源項目
  • 通過自帶的 lua 腳本進行 SQL 判斷

(注:MySQL 官方不建議將 MySQL-Proxy用到生產環境)

Amoeba

  • 由陳思儒用java語言進行開發
  • 作者曾就職于阿里巴巴擔任首席工程師(現已離職)
  • 阿里巴巴將其用于生產環境

缺點

  • 不支持事務
  • 不支持存儲過程

案例

搭建 MySQL 主從復制

需求

通過 Amoeba 實現 MySQL 數據庫請求的讀寫分離

關閉所有服務器的 ffirewalld

[root@localhost ~]# setenforce 0
[root@localhost ~]# systemctl stop firewalld
建立時間同步環境

主節點搭建時間同步服務器

安裝NTP

[root@localhost ~]# yum -y install ntp

從服務器選擇時間與主機同步

配置 NTP

[root@localhost ~]# vim /etc/ntp.conf
//添加如下兩行
server 127.127.1.0
fudge 127.127.1.0 stratum 8

重啟服務

[root@localhost ~]# systemctl restart mysqld
[root@localhost ~]# systemctl enable ntpd

登錄 MySQL 程序,給從服務器授權?

[root@localhost ~]# mysql -uroot -ppwd123
mysql> grant replication slave on *.* to 'myslave'@'192.168.10.%' identified by '123456' ;
mysql> flush privileges;
mysql> show master status;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| master-bin.000001 |      337 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.01 sec)

配置從服務器

[root@localhost ~]# vim /etc/my.cnf在[mysqld]模塊中修改或添加:
##修改,值不能和其他mysql服務器重復
server-id = 22
##添加(可不指定)
relay-log=relay-log-bin
##添加(可不指定)
relay-log-index=slave-relay-bin.index

--relay-log=name????中繼日志的文件的名字
?--relay-log-index=name??????MySQL slave 在啟動時需要檢查relay log index 文件中的relay log信息,此處定義該索引文件的名字

重啟服務

[root@localhost ~]# systemctl restart mysqld

登錄MySQL,配置同步

[root@localhost ~]# mysql -uroot -ppwd123
mysql> change master to master_host='192.168.10.101',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=337;
Query OK,0 rows affected,2 warnings (0.05 sec)

啟動同步

mysql> start slave;

注:如果后面加了分號,顯示的最后一行會提示ERROR: No query specified,當然,這沒有任何影響

查看 Slave 狀態,確保以下兩個值為 YES

##注意后面不要加分號
mysql> show slave status\G
*********1.row*********
//省略部分內容
...
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
//省略部分內容
...
1 row in set (0.00 sec)

驗證主從復制

在主從服務器上分別查詢數據庫

[root@localhost ~]# mysql -uroot -ppwd123
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)

在主服務器上創建數據庫

mysql> create database test;
Query OK, 1 row affected (0.00 sec)mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db_test            |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)

在從服務器上再次查詢數據庫,顯示數據庫相同,則主從復制成功

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| db_test            |
| mysql              |
| performance_schema |
| test               |
+--------------------+
5 rows in set (0.00 sec)
擴展

主主復制

  • 將一個 slave1服務器作為另一臺 slave2的master

在slave1 上修改my.cnf

## 在[mysqld]模塊添加
server-id=11
log-bin=master-bin
log-slave-updates=true

重啟mysql

[root@localhost ~]# systemctl restart mysqld

在slave1上執行以下命令創建一個授權用戶,用于在slave2上鏈接slave1

mysql> grant replication slave on *.* to 'myslave'@'192.168.10.%' identified by '123456' ;
mysql> flush privileges;
mysql> show master status;

搭建 Mysql 讀寫分離

Amoeba(變形蟲)
  • 開源框架項目
  • 于 2008 年發布一款 Amoeba for MySQL 軟件。
  • 這個軟件致力于 MySQL的分布式數據庫前端代理層
  • 主要為應用層訪問 MySQL 的時候充當SQL路由功能

優勢

  • 具有負載均衡
  • 高可用性
  • SQL過濾
  • 讀寫分離
  • 可路由到相關的目標數據庫
  • 可并發請求多臺數據庫

通過 Amoeba 能夠完成多數據源以下功能

  • 高可用
  • 負載均衡
  • 數據切片

目前 Amoeba 已在很多企業的生產線上使用

在主機amoeba上安裝java環境

[root@localhost ~]# chmod +x jdk-6u14-linux-x64.bin
## 根據提示按 Enter 鍵完成即可
[root@localhost ~]# ./jdk-6u14-linux-x64.bin
[root@localhost ~]# mv jdk1.6.0_14/ /usr/local/jdk1.6
## 增加一下配置
[root@localhost ~]# vim /etc/profile
## 添加到最末尾
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin:$PATH:$JAVA_HOME/bin
export AMOEBA_HOME=/usr/local/amoeba/
export PATH=$PATH:$AMOEBA_HOME/bin
[root@localhost local]# source /etc/profile## 查詢版本,確定java安裝成功
[root@localhost local]# java -version
java version "1.6.0 14"
Java(TM) SE Runtime Environment (build 1.6.0 14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)

(Java 環境已配置成功)

安裝并配置 amoeba

[root@localhost local]# mkdir /usr/local/amoeba
[root@localhost ~]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@localhost ~]# chmod -R 755 /usr/local/amoeba/
[root@localhost ~]# /usr/local/amoeba/bin/amoeba
## 有此提示表示成功
amoeba start|stop

配置 amoeba 讀寫分離,兩個 Slave 讀負載均衡

Master、Slave1、Slave2三個mysql服務器中開放權限給amoeba訪問(只在master中即可,會復制到slave中)

mysql> grant all on *.* to test@'192.168.10.%' identified by '123.com';

在amoeba上配置amoeba.xml文件

[root@localhost ~]# cd /usr/local/amoeba/conf
[root@localhost conf]# vim amoeba.xml## 修改帶有注釋的行部分,此處設置的是mysql客戶端連接amoeba時用的賬號和密碼
<property name="authenticator"><bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">##30行<property name="user">amoeba</property>##32行<property name="password">123456</property></property>.......略......<queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter"><property name="LRUMapSize">1500</property>##115行<property name="defaultPool">master</property>##118行<property name="writePool">master</property>##119行此處的注釋去掉<property name="readPool">slaves</property><property name="needParse">true</property></queryRouter>

編輯 Server.xml 文件

[root@localhost conf]# vim dbServers.xml
修改(注意去掉注釋),slave2的復制一個slave1<!-- mysql user -->##26行<property name="user">test</property>##29行,去掉注釋符<property name="password">123.com</property></factoryConfig>......略......##45行<dbServer name="master"  parent="abstractServer"><factoryConfig><!-- mysql ip -->##48行<property name="ipAddress">192.168.1.101</property>            </factoryConfig></dbServer>##52行<dbServer name="slave1"  parent="abstractServer"><factoryConfig><!-- mysql ip -->##55行<property name="ipAddress">192.168.1.102</property></factoryConfig></dbServer><dbServer name="slave2"  parent="abstractServer"><factoryConfig><!-- mysql ip --><property name="ipAddress">192.168.1.103</property></factoryConfig></dbServer>##59行<dbServer name="slaves" virtual="true"><poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"><!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--><property name="loadbalance">1</property><!-- Separated by commas,such as: server1,server2,server1 -->##65行<property name="poolNames">slave1,slave2</property>          </poolConfig></dbServer>

啟動 amoeba 軟件

[root@localhost ~]# cd /usr/local/amoeba/
[root@localhost amoeba]# bin/amoeba start&

注:當在前臺運行某個作業時,終端被該作業占據;而在后臺運行作業時,它不會占據終端。可以使用&命令把作業放到后臺執行

如果能看到 8066 和 3306端口,證明 amoeba 是正常開啟

[root@localhost amoeba]# netstat -anpt | grep java
tcp6 0    0 127.0.0.1:51388    ...*    LISTEN    31083/java
tcp6 0    0 :::8066          ...*    LISTEN    31083/java
tcp6 0    0 192.168.8.100:58748    192.168.8.139:3306 ESTABLISHED 31083/java
tcp6 0    0 192.168.8.100:37810    192.168.8.134:3306 ESTABLISHED 31083/java
tcp6 0    0 192.168.8.100:56066    192.168.8.136:3306 ESTABLISHED 31083/iava

測試

在 client 主機上

[root@localhost ~]# yum -y install mysql

通過代理訪問 MySQL?

[root@localhost ~]# mysql -u amoeba -p 123456 -h 192.168.10.104 -P 8066
## 密碼:123456
Enter password:
MySQL [(none)]>

若在連接“192.168.1.110”時報如下錯誤

MySQL [(none)]>show databases;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
1437053119Connection id:
Current database:*** NONE ***
ERROR 2013 (HY000): Lost connection to MySQL server during query
MySQL [(none)]>

同時,在 Amoeba 的服務器上面有如下報錯日志

amoeba Could not create a validated object, cause: ValidateObject failed

是因為 dbServers.xm 中的用戶,需要在主從機上分配權限。

同時注意該文件中

<!-- mysql schema --><property name="schema">test</property>

test數據庫肯定是要存在的。

在 Master、Slave1 和 Slave2 上面創建 test 數據庫,就可以解決此問題。?

在 master 服務器上創建表

mysql> stop slave;
MySQL [test]> use auth
MySQL [auth]> create table users (id int(10),name char(20));
Query Ok, 0 rows affected (0.16 sec)

分別在兩臺服務器上執行操作

mysql> stop slave;

在主服務器上

mysql> insert into users values ('2','zhangsan');
Query OK,1 rows affected (0.06 sec)

從服務器同步了表,手動插入其它內容

slave1:
mysql> use auth;
mysql>insert into users values ('2','zhangsan');slave2:
mysql> use auth;
mysql> insert into users values ('3','zhangsan);

在客戶機上查詢3次

mysql> use auth;
mysql> select * from users;

對比三次的輸出,驗證讀操作,發現沒有在master寫入的數據,而slave上寫的能查到

在客戶機上

mysql> use auth;
mysql>insert into users values ('4','zhangsan');
##發現在client上查詢不到自己寫的數據
mysql> select * from users;

在主服務器上

##能查到在client上寫入的數據,說明寫操作在master上
mysql> select * from users;

在從服務器上

##發現沒有數據,說明寫入的操作是在master上
mysql> select * from users;

由此驗證,已經實現了 MySQL讀寫分離

目前所有的寫操作都全部在 Master 主服務器上,用來避免數據的不同步;所有的讀操作都分攤給了 Slave 從服務器,用來分擔數據庫壓力。

小阿軒yx-案例:MySQL主從復制與讀寫分離

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/37753.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/37753.shtml
英文地址,請注明出處:http://en.pswp.cn/web/37753.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

MSPG3507——藍牙接收數據顯示在OLED,滴答定時器延時500MS

#include "ti_msp_dl_config.h" #include "OLED.h" #include "stdio.h"volatile unsigned int delay_times 0;//搭配滴答定時器實現的精確ms延時 void delay_ms(unsigned int ms) {delay_times ms;while( delay_times ! 0 ); } int a0; …

4.自動生成class和device

第三章里面&#xff0c;我們使用mknod創建設備節點&#xff0c;常規操作是在驅動init的時候就創建好&#xff0c;使用class_create和device_create創建。 #include "asm/uaccess.h" #include "linux/scatterlist.h" #include "linux/types.h" #…

【公平鎖 和 非公平鎖】

公平鎖 和 非公平鎖 公平鎖:類似食堂打飯&#xff0c;按照申請鎖的順序來獲取鎖類似廁所蹲坑先來后到 公平鎖就是很公平 在并發環境下每個線程在獲取鎖的同時會先查看此鎖維護的等待隊列&#xff0c;如果為空&#xff0c;或者當前線程是等待就占有鎖&#xff0c;否則就加入到…

20人團隊如何免費使用 Atlassian 云產品?

企業賺錢越來越難&#xff0c;尤其是初創團隊或小型團隊更傾向于使用免費工具支持業務。團隊規模影響協作復雜度&#xff0c;Atlassian 考慮到小團隊的需求&#xff0c;提供了多種選擇。比如&#xff0c;Jira 和 Confluence 的云版本有免費版&#xff0c;包含基本的項目管理功能…

ISP IC/FPGA設計-第一部分-SC130GS攝像頭分析(0)

1.介紹 SC130GS是一款國產的Global shutter CMOS圖像傳感器&#xff0c;最高支持1280Hx1024V240fps的傳輸速率&#xff1b;SC130GS有黑白和彩色款&#xff0c;作為ISP開發選擇彩色的&#xff0c;有效像素窗口為1288Hx1032V&#xff0c;支持復雜的片上操作&#xff0c;選擇他理…

Toshiba東芝TB6612FNG電機驅動IC:釋放性能與多功能性

在嵌入式系統和機器人技術領域&#xff0c;電機控制是一個關鍵方面&#xff0c;對項目的性能和可靠性有著顯著影響。東芝的TB6612FNG電機驅動IC作為一個穩健且多功能的解決方案&#xff0c;在驅動雙直流電機方面脫穎而出&#xff0c;提供了高性能、可靠性和易用性。本文將深入探…

23種設計模式之裝飾者模式

深入理解裝飾者模式 一、裝飾者模式簡介1.1 定義1.2 模式類型1.3 主要作用1.4 優點1.5 缺點 二、模式動機三、模式結構四、 裝飾者模式的實現4.1 組件接口4.2 具體組件4.3 裝飾者抽象類4.4 具體裝飾者4.5 使用裝飾者模式4.6 輸出結果&#xff1a; 五、 應用場景5.1 圖形用戶界面…

排序(堆排序、快速排序、歸并排序)-->深度剖析(二)

前言 前面介紹了冒泡排序、選擇排序、插入排序、希爾排序&#xff0c;作為排序中經常用到了算法&#xff0c;還有堆排序、快速排序、歸并排序 堆排序&#xff08;HeaSort&#xff09; 堆排序的概念 堆排序是一種有效的排序算法&#xff0c;它利用了完全二叉樹的特性。在C語言…

復分析——第9章——橢圓函數導論(E.M. Stein R. Shakarchi)

第 9 章 橢圓函數導論 (An Introduction to Elliptic Functions) The form that Jacobi had given to the theory of elliptic functions was far from perfection; its flaws are obvious. At the base we find three fundamental functions sn, cn and dn. These functio…

商湯上海AI實驗室聯合發布:自動駕駛全棧式高精度標定工具箱(含車、IMU、相機、激光雷達等的標定)

前言 在自動駕駛技術飛速發展的今天&#xff0c;傳感器的精確標定對于確保系統性能至關重要。SensorsCalibration&#xff0c;一個專為自動駕駛車輛設計的標定工具箱&#xff0c;提供了一套全面的解決方案&#xff0c;用于校準包括IMU、激光雷達、攝像頭和雷達在內的多種傳感器…

基于Java平價平價汽車租賃系統設計和實現(源碼+LW+部署講解)

&#x1f497;博主介紹&#xff1a;?全網粉絲10W,CSDN作者、博客專家、全棧領域優質創作者&#xff0c;博客之星、平臺優質作者、專注于Java、小程序技術領域和畢業項目實戰?&#x1f497; &#x1f31f;文末獲取源碼數據庫&#x1f31f; 感興趣的可以先收藏起來&#xff0c;…

【python】使用conda管理python項目:conda管理不同項目環境,pip下載最新的包

文章目錄 一. python包管理概述1. miniforge、Miniconda與Anaconda2. conda與pip的區別是什么&#xff1f;3. pip與conda配合使用 二. 使用conda管理不同py環境1. 創建一個環境2. 解決沖突 三. 命令合集1. conda1.1. 常用1.2. 環境管理1.3. 分享環境1.4. 包管理 2. 依賴沒有在c…

《RepViT Revisiting Mobile CNN From ViT Perspective》

期刊&#xff1a;CVPR 年份&#xff1a;2024 代碼&#xff1a;http://https: //github.com/THU-MIG/RepViT 摘要 最近&#xff0c;與輕量級卷積神經網絡(CNN)相比&#xff0c;輕量級視覺Transformer(ViTs)在資源受限的移動設備上表現出了更高的性能和更低的延遲。研究人員已…

無法訪問指向的web服務器(或虛擬主機)的目錄,請檢查網絡設置

微信公眾平臺,進行業務域名、JS接口安全域名、網頁授權域名配置時&#xff0c;遇到的問題中有&#xff1a;無法訪問指向的web服務器&#xff08;或虛擬主機&#xff09;的目錄&#xff0c;請檢查網絡設置&#xff0c;這里簡單記錄一下處理過程。 關于這個問題首先保證下載…

SHELL腳本學習(十四)gawk進階

一、使用變量 gawk支持兩種變量 內建變量自定義變量 1.1 內建變量 1.1.1 字段和記錄分隔符變量 數據字段變量允許使用美元符號 $ 和 位置來引用對應的字段。 $1 對應第一個數據字段&#xff0c;$2對應第二個數據字段&#xff0c;以此類推。 數據字段用字段分隔符劃定。默…

【基于R語言群體遺傳學】-1-哈代溫伯格基因型比例

前言 群體遺傳學是研究生物群體中基因的分布、基因頻率和基因型頻率的維持和變化的學科。它不僅探討遺傳病的發病頻率和遺傳方式&#xff0c;還研究基因頻率和變化的規律&#xff0c;為預防、監測和治療遺傳病提供重要信息。R語言作為一種強大的統計分析工具&#xff0c;在群體…

mybatis實現多表查詢

mybatis高級查詢【掌握】 1、準備工作 【1】包結構 創建java項目&#xff0c;導入jar包和log4j日志配置文件以及連接數據庫的配置文件&#xff1b; 【2】導入SQL腳本 運行資料中的sql腳本&#xff1a;mybatis.sql 【3】創建實體來包&#xff0c;導入資料中的pojo 【4】User…

TypeScript Project References npm 包構建小實踐

npm 包輸出 es/cjs 產物 在開發一個 npm 包時&#xff0c;通常需要同時輸出 ES 模塊和 CommonJS 模塊的產物供不同的構建進行使用。在只使用tsc進行產物編譯的情況下&#xff0c;我們通常可以通過配置兩個獨立的 tsconfig.json 配置文件&#xff0c;并在一個 npm script 中 執…

kubesphere自定義流水線基礎鏡像

背景 需求&#xff1a;在流水線基礎pod中使用python和jinja2模塊來動態渲染部署文件 由于ks提供的基礎鏡像無法滿足以上需求&#xff0c;在ks提供的maven鏡像的基礎上實現 實施 制作鏡像&并推送到private image repo FROM kubesphere/builder-maven:v3.2.0 RUN sed -i…