案例:MySQL主从复制与读写分离

一、案例分析

1.案例概述

        在实际的生产环境中,如果对数据库的读和写都在同一个数据库服务器中操作,无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,一般来说都是通过主从复制(Master-Slave)来同步数据,再通过读写分离来提升数据库并发负载能力的方案来进行部署与实施。

2.案例前置知识点

(1)MySQL主从复制原理

        MySQL的主从复制和 MySQL的读写分离两者有着紧密联系,首先要部署主从复制,只有主从复制完成了,才能在此基础上进行数据的读写分离。

        MySQL支持的复制类型
        ①基于语句的复制。在主服务器上执行的 SQL语句,在从服务器上执行同样的语句。MySQL 默认采用基于语句的复制,效率比较高。
        ②基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。
        ③混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。

(2)复制的工作过程

MySQL复制的工作过程如图所示

        在每个事务更新数据完成之前,Master将这些改变记录进二进制日志。写入二进制日志完成后,Master通知存储引擎提交事务。
        Slave 将 Master 的 Binary log 复制到其中继日志(Relay log)。首先,Slave 开始一个工作线程--/0 线程,I/O 线程在 Master 上打开一个普通的连接,然后开始 Binlog dump process。Binlog  dump process 从 Master 的二进制日志中读取事件,如果已经跟上Master,它会睡眠并等待 Master 产生新的事件。I/0 线程将这些事件写入中继日志。
        SQL slave thread(SQL 从线程)处理该过程的最后一步。SQL 线程从中继日志读取事件,并重放其中的事件而更新 Slave 数据,使其与 Master 中的数据保持一致。只要该线程与 1/0 线程保持一致,中继日志通常会位于 OS 的缓存中,所以中继日志的开销很小。
        复制过程有一个很重要的限制,即复制在 Slave 上是串行化的,也就是说 Master 上的并行更新操作不能在 Slave 上并行操作。

2.MySQL读写分离原理

        简单来说,读写分离就是只在主服务器上写,只在从服务器上读。基本的原理是让主数据库处理事务性查询,而从数据库处理select查询。数据库复制被用来把主数据库上事务性查询导致的变更同步到集群中的从数据库。 目前较为常见的 MySQL 读写分离分为两种。

(1)基于程序代码内部实现         

        在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的。优点是性能较好,因为在程序代码中实现,不需要增加额外的设备作为硬件开支;缺点是需要开发人员来实现,运维人员无从下手。 

(2)基于中间代理层实现

  代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,有两个代表性程序。
        ① MySQL-Proxy。MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断,虽然是 MySQL 官方产品,但是 MySQL 官方并不建议将 MySQL-Proxy 用到生产环境。
        ② Amoeba。由陈思儒开发,作者曾就职于阿里巴巴。该程序由 Java 语言进行开发,阿里巴巴将其用于生产环境。它不支持事务和存储过程。
        经过上述简单的比较,通过程序代码实现 MySQL读写分离自然是一个不错的选择,但是并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java 应用,如果在程序代码中实现读写分离对代码改动就较大。所以,像这种应用一般会考虑使用代理层来实现。本章后续案例通过 Amoeba 实现。

3.案例环境

 (1)本案例环境

本案例环境使用五台服务器模拟搭建,具体的网络拓扑如图所示

(2)案例需求

要求通过Amoeba实现MySQL数据库请求的读写分离。

(3)案例实现思路

        安装 MySQL 数据库;
        配置 MySQL 主从复制;
        安装并配置 Amoeba;
        客户端测试读写分离。

二、案例实施

1.搭建MySQL主从复制

(1).在Master、Slave1、Slave2服务器上安装MySQL数据库

(2).配置Master主服务器

        在/etc/my.cnf中修改或者增加下面的内容

[root@localhost ~]# vim /etc/my.cnf
server-id =11
log-bin = master-bin
log-slave-updates = true

        重启MySQL服务

[root@localhost ~# systemctl restart mysqld

        登录MySQL程序,给从服务器授权

[root@localhost ~]#mysql -u root -p
mySql>GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.1.%' IDENTIFIED BY '123456';
mySql>FLUSH PRIVILEGES:
mysql>show master status;

        其中 File 列显示日志名,Position 列显示偏移量,这两个值在后面配置从服务器的时候需要。Slave 应从该点上进行新的更新。

(3)配置Slave从服务器

        在 Slave1、Slave2 服务器上面分别执行下面步骤。

        在/etc/my.cnf中增加以下内容,server-id不能相同

[root@localhost ~]# vim /etc/my.cnf
server-id= 22                            //两个Slave服务器的server-id不能相同
relay-log = relay-log-bin
relay-log-index= slave-relay-bin.index

        重启MySQL服务

[root@localhost ~]# systemctl restart mysqld

        登录MySQL,配置同步,按主服务器结果更改下面命令中 master_log _file 和 master _log_pos 参数。

[root@localhost ~]# mysql -u root -p
mysql>change master to master_host='192.168.1.101',master_user='myslave' master_password='123456',master_log_ file='File值',master_log_pos=Position的值;

        启动同步

mysql>start slave;

        查看Slave状态,确保Slave_IO_Running Slave_SQL_Running两个值为YES

mysql>show slave status\G;
************************1.row****************************
Slave_IO_State:Waiting for master to send event
Master Host: 192.168.1.101
Master User: myslave
Master Port: 3306
Connect Retry: 60
Master Log File: master-bin.000002
Read Master Log Pos: 410
Relay_Log_File: relay-log-bin.000002
Relay Log Pos: 284
Relay_Master Log_File: master-bin.000002
Slave_IO_Running: YesSlave SQL Running: Yes
Replicate_Do_DB:
Replicate_Ignore_DB:
......

(4)验证主从复制效果

在主、从服务器上登录MySQL,在主服务器新建数据库
在两台从服务器上分别查看数据库,显示数据库相同,则主从复制成功

2.搭建MySQL读写分离

        Amoeba(变形虫)项目开源框架于 2008 年发布一款 Amoeba for MySQL 软件。这个软件致力于 MySQL分布式数据库前端代理层,它主要为应用层访问 MSQL的时候充当SQL路由功能,并具有负载均衡、高可用性、SQL过滤、读写分离、可路由到相关的目标数据库、可并发请求多台数据库。通过 Amoeba 能够完成多数据源的高可用、负载均衡、数据切片的功能,目前 Amoeba 已在很多企业的生产线上使用,其版本可在官网进行下载。

(1)在Amoeda上安装Java环境 

        因为 Amoeba 基于是jdk1.5 开发的,所以官方推荐使用 jdk1.5或1.6版本,高版本不建议使用。 

[root@localhost ~]# chmod +x jdk-6u14-inux-x64.bin
[root@localhost ~]# ./jdk-6u14-linux-x64.bin    //根据提示按 Enter 键完成即可
[root@localhost ~# mv jdk1.6.0 14/ /usr/local/jdk1.6
[root@localhost ~]# vim /etc/profileexport JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=SCLASSPATH:$JAVA HOMEЛb:$JAVA HOME/jre/lib
export PATH=$JAVA_HOME/ib:$JAVA HOME/jre/bin:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba/
export PATH=$PATH:$AMOEBA_HOME/bin[root@localhost ~]# source /etc/profile
[root@localhost ~]# 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)

(2)安装并配置Amoeba软件

[root@localhost ~# mkdir /usr/local/amoeba
[root@localhost ~]# tar zxf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
[root@localhost ~l# chmod -R 755 /usr/localamoeba/
[root@localhost ~]# /usr/local/amoeba/bin/amoeba

(3)配置Amoeba读写分离,两个Slave读负载均衡

        在三个mysql服务器中开放权限给amoeba访问(只在master中即可,会复制到slave中)

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

        关闭防火墙

[root@localhost amoeba]# systemctl stop firewalld

        编辑amoeba.xml配置文件

[root@localhost ~]# cd /usr/local/amoeba/conf
[root@localhost conf]# vim amoeba.xml<property name="user">amoeba</property>                 ##30行<property name="password">123456</property>               ##32行
...
<property name="defaultPool">master</property>             ##115行
<property name="writePool">master</property>             ##118行
<property name="readPool">slaves</property>    ##119行此处的注释去掉

        编辑dbServer.xml文件

[root@localhost conf]# vim dbServers.xml<property name="user">test</property>         ##26行<property name="password">123.com</property>  ##29行,去掉注释符<dbServer name="master"  parent="abstractServer">         ##45行<factoryConfig><!-- mysql ip --><property name="ipAddress">192.168.10.101</property>            ##48行</factoryConfig></dbServer><dbServer name="slave1"  parent="abstractServer">	        ##52行<factoryConfig><!-- mysql ip --><property name="ipAddress">192.168.10.102</property>            ##55行</factoryConfig></dbServer><dbServer name="slave2"  parent="abstractServer">         ##这段配置复制slave1<factoryConfig><!-- mysql ip --><property name="ipAddress">192.168.10.103</property></factoryConfig></dbServer><dbServer name="slaves" virtual="true">                    ##59行<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 --><property name="poolNames">slave1,slave2</property>          ##65行</poolConfig></dbServer>

        启动amoeba软件

(4)启动amoeba软件
[root@localhost ~]# cd /usr/local/amoeba/
[root@localhost amoeba]# bin/amoeba start&
//当在前台运行某个作业时,终端被该作业占据;而在后台运行作业时,它不会占据终端。可以使用&命令把作业放到后台执行
[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.10.103:3306 ESTABLISHED 31083/java
tcp6  0  0  192.168.8.100:37810 192.168.10.102:3306 ESTABLISHED 31083/java
tcp6  0  0  192.168.8.100:56066 192.168.10.101:3306 ESTABLISHED 31083/java

(4)测试

        在client上安装mysql,在master,slave1,slave2中分别添加数据,在clinent中查询,发现只有在master写入的数据,说明写入的操作是在master上。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/38448.shtml

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

相关文章

uniapp + vite中 uni.scss 使用 /deep/ 不生效(踩坑记录三)

vite 中使用 /deep/ 进行样式穿透报错 原因&#xff1a;vite 中不支持&#xff0c;换成 ::v-deep 或:deep即可

python setup函数中,name参数的作用

setup函数是setuptools库中的一个函数&#xff0c;用于配置和分发Python软件包。 setup函数的name参数指定了该软件包的名称&#xff0c;这个名称在包发布到PyPI&#xff08;Python Package Index&#xff09;时会作为该包的标识符。其他开发者可以通过这个名称来安装和使用你…

C语言 求最大公约数和最小公倍数

这个程序定义了两个函数&#xff0c;一个用于计算两个正整数的最大公约数 (GCD)&#xff0c;另一个用于计算最小公倍数 (LCM)。在主函数中读取用户输入的两个正整数&#xff0c;并调用这两个函数输出结果。 #include <stdio.h>// 计算最大公约数的函数&#xff0c;使用辗…

[大师C语言(第四十篇)]C语言volatile关键字深度解析与实战技巧

第一部分&#xff1a;C语言volatile关键字深度解析 一、volatile关键字的作用 在C语言中&#xff0c;volatile关键字是一个用于声明变量的修饰符。它用于指定一个变量的值在程序执行过程中可能会被外部设备或中断服务程序修改&#xff0c;因此编译器不应该对这样的变量进行优…

浅谈人工智能发展趋势

第三次浪潮 人类科技发展的主线正沿着“能源”和“新型”展开。AI的尽头是光伏和储能。 如今我们正在经历第三次浪潮——信息文明。 社会生产力 劳动对象 劳动工具 劳动者 生产要素 农业文明铜器铁器 材料 人力工具 农民 土地人力 工业文明机车电力 材料动力 动力…

判断一个函数是否有装饰器

判断一个函数是否有装饰器 如何判断一个函数是否有装饰标记&#xff0c;如果有我们在pytest收集用例的时候能做一些什么操作呢 def my_decorator(func):def wrapper(*args, **kwargs):print("Function is being decorated!")return func(*args, **kwargs)return wr…

Java web应用性能分析之【prometheus监控K8s指标说明】

常规k8s的监控指标 单独 1、集群维度 集群状态集群节点数节点状态&#xff08;正常、不可达、未知&#xff09;节点的资源使用率&#xff08;CPU、内存、IO等&#xff09; 2、应用维度 应用响应时间 应用的错误率 应用的请求量 3、系统和集群组件维度 API服务器状态控…

springboot try...catch 影响事务回滚

示例 事务不会回滚 OverrideTransactional(rollbackFor Exception.class)public CommonResponse modifyTeaFormula(GemiTeaFormulaReq gemiTeaFormulaReq) {try {省略部分代码teaFormulaDao.deleteById(id);teaFormulaDetailDao.deleteById(id);} catch (Exception e) {logger…

Calendar类在Java中的高级应用与使用技巧

Calendar类在Java中的高级应用与使用技巧 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; **1. **引言 在Java中&#xff0c;处理日期和时间是开发中经常遇到…

2024 vue3入门教程:01vscode终端命令创建第一个vue项目

参考vue官网手册&#xff1a;https://cn.vuejs.org/guide/quick-start.html 一、找个盘符&#xff0c;新建文件夹存储以后得vue项目 我的是e盘下创建了vueproject 二、使用vscode打开存储vue项目的文件夹 因为我生成过项目&#xff0c;所以有文件&#xff0c;你们初次是没有…

IT专业入门,高考假期预习指南

文章目录 一、了解IT专业的基本概念二、选择适合的编程语言入门三、掌握基本的编程工具和环境四、学习基础的数据结构和算法五、实践项目和动手实验六、利用在线资源进行学习七、参加编程竞赛和社区活动总结 高考结束后&#xff0c;许多同学将迎来大学生活&#xff0c;而对于选…

C++将模板类用作参数

#include <iostream> // 包含头文件。 using namespace std; // 指定缺省的命名空间。template <class T, int len> class LinkList // 链表类模板。 { public:T* m_head; // 链表头结点。int m_len len; // 表长。void…

mysql的前缀索引

什么是前缀索引 所谓的前缀索引&#xff0c;说白了就是对文本的前几个字符建立索引(具体是几个字符在建立索引时去指定)&#xff0c;比如以产品名称的前10位来建索引&#xff0c;这样建立起来的索引更小&#xff0c;查询效率更快有点类似oracle中对字段使用left函数来建立函数索…

Java与机器学习模型的集成与部署

Java与机器学习模型的集成与部署 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01;今天我们来探讨如何使用Java集成和部署机器学习模型。 随着人工智能和机器学习…

【SQL】使用索引的好处

使用索引可以显著加快查询速度&#xff0c;主要原因有以下几个方面&#xff1a; 1. 减少数据扫描量 索引类似于一本书的目录&#xff0c;可以让数据库快速找到特定的数据行&#xff0c;而不是从头到尾扫描整个表。例如&#xff0c;没有索引的情况下&#xff0c;查询 SELECT *…

简洁版人工智能训练流程

人工智能&#xff08;AI&#xff09;训练流程是指使用数据来训练机器学习模型&#xff0c;使其能够执行特定任务的过程。以下是人工智能训练的一般流程&#xff1a; #mermaid-svg-qZ5c5PU9yms7cVOB {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:…

Java中如何优雅地处理NamingException异常?

Java中如何优雅地处理NamingException异常&#xff1f; 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在Java开发中&#xff0c;NamingException异常是JNDI&…

鸿蒙arkts api9 图片验证码 canvas

/*** 图片验证码***/ Component export default struct RandomTxtCanvas {Link imgRandomTxt:string//图片验证private settings: RenderingContextSettings new RenderingContextSettings(true)private context: CanvasRenderingContext2D new CanvasRenderingContext2D(th…

DataWhaleAI Tsak1 运行Baseline

题目背景 在当今数字化时代&#xff0c;企业积累了丰富的对话数据&#xff0c;这些数据不仅是客户与企业之间交流的记录&#xff0c;更是隐藏着宝贵信息的宝库。在这个背景下&#xff0c;群聊对话分角色要素提取成为了企业营销和服务的一项重要策略。 群聊对话分角色要素提取…

nlp--最大匹配分词(计算召回率)

最大匹配算法是一种常见的中文分词算法&#xff0c;其核心思想是从左向右取词&#xff0c;以词典中最长的词为优先匹配。这里我将为你展示一个简单的最大匹配分词算法的实现&#xff0c;并结合输入任意句子、显示分词结果以及计算分词召回率。 代码 : # happy coding…