小阿轩yx-案例:MySQL主从复制与读写分离

news2024/12/23 3:15:10

小阿轩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.coloradmin.cn/o/1883619.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【源码+文档+调试讲解】基于vue的线上点餐系统

摘要 随着信息技术在管理上越来越深入而广泛的应用&#xff0c;管理信息系统的实施在技术上已逐步成熟。本文介绍了线上点餐系统的开发全过程。通过分析线上点餐系统管理的不足&#xff0c;创建了一个计算机管理线上点餐系统的方案。文章介绍了线上点餐系统的系统分析部分&…

【PYTORCH,TENSORFLOW环境配置,安装,自用代码】

conda -V&#xff08;查看版本&#xff0c;这步不要也罢&#xff09; conda create -n test python3.7&#xff08;创建环境&#xff09; conda activate test&#xff08;激活&#xff09; conda env list&#xff08;查看自己的环境&#xff09; nvidia-smi&#xff08;查…

Ubuntu DNS服务配置 深度解析

测试方法 resolvectl status dig alidns.com 修改实践 直接用接口配置&#xff0c;没用 /etc/resolv.conf&#xff0c;有效 /etc/netplan/01-network-manager-all.yaml,无效 /etc/systemd/resolved.conf&#xff0c;见link&#xff0c;为全局配置 [Resolve] DNS1.1.1.1 Fa…

二维数组-----螺旋性矩阵输出

题目有点难&#xff0c;ok其实是很难。。。 观察样例输出&#xff0c;不难发现&#xff0c;螺旋数组中元素的递增轨迹为&#xff1a;右右右、下下下、左左左、上上上 简明为&#xff1a;右、下、左、上。可以设开始递增的元素1的位置为&#xff08;x&#xff0c;y)&#xff0c…

单片机语音识别控制蓝牙通信

基于单片机语音识别控制&蓝牙控制 1、Arduino单片机语音控制1.1 直连1.2 蓝牙无线连接1.3 部分核心程序1.4 实物演示 2、51单片机语音控制2.1 直连2.2 蓝牙无线连接2.3 部分核心程序2.4 实物演示 3、STM32单片机语音控制3.1 直连3.2 蓝牙无线连接3.3 部分核心程序3.4 实物演…

AI大模型日报#0701:Meta发布LLM Compiler、扒一扒Sora两带头人博士论文

导读&#xff1a;AI大模型日报&#xff0c;爬虫LLM自动生成&#xff0c;一文览尽每日AI大模型要点资讯&#xff01;目前采用“文心一言”&#xff08;ERNIE-4.0-8K-latest&#xff09;生成了今日要点以及每条资讯的摘要。欢迎阅读&#xff01;《AI大模型日报》今日要点&#xf…

黑马点评下订单-小程序下单没问题但是Postman发送请求失败了,返回401

经过多方探索&#xff0c;这个✓8错误就是由于黑马点评使用了拦截器&#xff0c;我们直接发送请求是会被拦截器拦截下来的&#xff0c;我给出的解决方案是通过配置Postman解决&#xff0c;方法很简单&#xff01; 解决方案 右边的value写上Redis里面登录所用token值就可以了…

无线物联网练习题

文章目录 选择填空简答大题 选择 不属于物联网感知技术的是(A) A:ZigBee B:红外传感器 C:FRID D:传感器 ZigBee是一种无线通信技术&#xff0c;虽然它常用于物联网中作为设备之间的通信手段&#xff0c;但它本身并不是一种感知技术 关于物联网于与互联网的区别的描述&#xff…

技术派全局异常处理

前言 全局的异常处理是Java后端不可或缺的一部分&#xff0c;可以提高代码的健壮性和可维护性。 在我们的开发中&#xff0c;总是难免会碰到一些未经处理的异常&#xff0c;假如没有做全局异常处理&#xff0c;那么我们返回给用户的信息应该是不友好的&#xff0c;很抽象的&am…

【机器学习】基于Transformer的迁移学习:理论与实践

引言 在机器学习领域&#xff0c;迁移学习已成为提升模型训练效率和性能的重要策略&#xff0c;特别是在标注数据稀缺的场景下。Transformer模型自2017年由Google提出以来&#xff0c;在自然语言处理&#xff08;NLP&#xff09;领域取得了突破性进展&#xff0c;并逐渐扩展到…

科普文:一文搞懂jvm原理(三)执行引擎

概叙 科普文&#xff1a;一文搞懂jvm(一)jvm概叙-CSDN博客 科普文&#xff1a;一文搞懂jvm原理(二)类加载器-CSDN博客 前面我们介绍了jvm&#xff0c;jvm主要包括两个子系统和两个组件&#xff1a; Class loader(类装载器) 子系统&#xff0c;Execution engine(执行引擎) 子系…

【吊打面试官系列-MyBatis面试题】模糊查询 like 语句该怎么写?

大家好&#xff0c;我是锋哥。今天分享关于 【模糊查询 like 语句该怎么写?】面试题&#xff0c;希望对大家有帮助&#xff1b; 模糊查询 like 语句该怎么写? 第 1 种&#xff1a;在 Java 代码中添加 sql 通配符。 string wildcardname “%smi%”; list<name> names …

高考不是终点:如何利用教育资源实现人生跃迁?普鲁士教育的利弊,你了解吗?从科举到高考,中国教育的变迁!链接上层,获取核心资源的途径

高考已经结束&#xff0c;这两天分数将会陆续出来&#xff0c;无论结果好坏&#xff0c;我都希望你明白一些道理。这些道理在学校老师不会教你&#xff0c;但是非常重要。 一、中国的科举制度 科举制度是为王朝服务的。 科举制度是中国古代通过考试选拔官员的制度&#xff0c…

C++ initializer_list类型推导

目录 initializer_list C自动类型推断 auto typeid decltype initializer_list<T> C支持统一初始化{ }&#xff0c;出现了一个新的类型initializer_list<T>&#xff0c;一切类型都可以用列表初始化。提供了一种更加灵活、安全和明确的方式来初始化对象。 class…

Fragment+Viewpage2+FragmentStateAdapter实现滑动式标签布局

大家好&#xff0c;我是网创有方&#xff0c;今天记录下标签布局的实现方法&#xff0c;先看下效果图。 第一步&#xff1a;编写一个activity或者fragment。内含有一个viewpager2的适配器&#xff0c;适配器类型为FragmentStateAdapter。 ​ public class MediaCreateFragment…

pdf文件怎么删除其中一页?这些删除小技巧了解下

在我们日常的学习办公中&#xff0c;PDF文件因其跨平台、格式固定的特性&#xff0c;成为了我们工作和学习中不可或缺的一部分。然而&#xff0c;有时我们可能会遇到需要删除PDF文件中某一页的情况&#xff0c;这时该如何操作呢&#xff1f;下面教大家几种删除PDF页面小技巧&am…

钟义杰老师6月28号给中海油讲授《创新思维与创新管理+华为敏捷转型》圆满结束

钟老师的授课深受学员喜爱&#xff0c;课堂上老师讲了很多华为的案例&#xff0c;学员听的津津有味&#xff0c;对老师的授课一片好评

RedHat9 | podman容器-续集

一、管理容器存储和网络资源 使用容器来运行简单的进程&#xff0c;然后退出。可以配置容连续运行特定服务&#xff0c;如数据库服务。如果持续运行服务&#xff0c;需要向容器添加更多的资源&#xff0c;如持久存储或对其他网络的访问权限。 针对企业容器平台上的大型部署&a…

江协科技51单片机学习- p23 DS1302实时时钟

&#x1f680;write in front&#x1f680; &#x1f50e;大家好&#xff0c;我是黄桃罐头&#xff0c;希望你看完之后&#xff0c;能对你有所帮助&#xff0c;不足请指正&#xff01;共同学习交流 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd;​…