小阿轩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.mzph.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; …

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;…

《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;这里简单记录一下处理过程。 关于这个问题首先保证下载…

【基于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 中 执…

7.1作业

1.思维导图 2.在堆区申请两个长度为32的空间&#xff0c;实现两个字符串的比较【非库函数实现】 (1)定义函数&#xff0c;在对区申请空间 两个申请&#xff0c;主函数需要调用2次 (2)定义函数&#xff0c;实现字符串的输入 void input(char *p) (3)调用函数实现字符串比较…

BUT000增强字段BAPI结构激活出错(BUPA_CENTRAL_CI_CHANGE)

导语&#xff1a;BP主数据增强字段&#xff0c;需要使用BAPI&#xff1a;BUPA_CENTRAL_CI_CHANGE进行值写入&#xff0c;但是在SAP 2023以后的版本&#xff0c;激活会出错&#xff0c;原因是因为SAP的一个结构同时包含了BUS00_EEW以及BUS00_EEWX两个结构&#xff0c;导致结构字…

Spring Security 认证流程

Spring Scurity是spring生态下用于认证和授权的框架&#xff0c;具有高度的灵活性和可扩展行&#xff0c;本节主要对Spring Security的认证过程中进行概括性的介绍&#xff0c;主要介绍在该过程中&#xff0c;会涉及到哪些组件以及每个组件所承担的职责&#xff0c;希望大家可以…

电脑录音软件哪个好?7款录制音频工具大盘点,赶快学起来!(2024)

也许你渴望提取你最喜欢的节目的背景音乐&#xff0c;或者你希望录制自己的声音制作教程。如果是这样&#xff0c;你就需要一款优秀的电脑录音软件&#xff0c;来帮助你捕捉任何你想要的声音&#xff0c;而且不会损失音质。目前市场上存在着大量的录制音频工具&#xff0c;面对…

锁相环相位噪声仿真代码-汇总

24小时自动发货 所设计的压控振荡器输入电压为0.625V时&#xff0c;输出大致为500Mhz&#xff1b;输入电压为1.559时&#xff0c;输出电压大致为1Ghz 1.文件夹里面各个文件作用&#xff08;包括参考书PLL PHASE NOISE ANALYSIS、lee的射频微电子、以及前人留下的matlab文件还有…