小阿轩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主从复制与读写分离

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Python tkinter: 开发一个目标检测GUI小程序

程序提供了一个用户友好的界面&#xff0c;允许用户选择图片或文件夹&#xff0c;使用行人检测模型进行处理&#xff0c;并在GUI中显示检测结果。用户可以通过点击画布上的检测结果来获取更多信息&#xff0c;并使用键盘快捷键来浏览不同的图片。 一. 基本功能介绍 界面布局&am…

C++封装

1. 封装 1.1. struct 当单一变量无法完成描述需求的时候&#xff0c;结构体类型解决了这一问题。可以将多个类型打包成一体&#xff0c;形成新的类型&#xff0c;这是c语言中的封装 但是&#xff0c;新类型并不包含&#xff0c;对数据类的操作。所有操作都是通过函数的方式进…

CrimsonEDR:一款恶意软件模式识别与EDR策略评估工具

关于CrimsonEDR CrimsonEDR是一个功能强大的开源项目&#xff0c;该项目旨在帮助广大研究人员识别特定的恶意软件模式&#xff0c;以此来优化终端检测与响应&#xff08;EDR&#xff09;的策略方案。通过使用各种不同的检测方案&#xff0c;可以加深开发人员与研究人员加深对安…

在Ubuntu 14.04上安装和配置Mumble服务器(Murmur)的方法

前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。点击跳转到网站。 介绍 Mumble是一款免费开源的语音通信应用程序&#xff0c;主要设计用于游戏玩家使用。Mumble类似于TeamSpeak和Ventrilo。Mumble采用客…

考研生活day1--王道课后习题2.2.1、2.2.2、2.2.3

2.2.1 题目描述&#xff1a; 解题思路&#xff1a; 这是最基础的操作&#xff0c;思路大家应该都有&#xff0c;缺少的应该是如何下笔&#xff0c;很多同学都是有思路但是不知道如何下笔&#xff0c;这时候看思路的意义不大&#xff0c;可以直接看答案怎么写&#xff0c;最好…

cube-studio 开源一站式云原生机器学习/深度学习/大模型训练推理平台介绍

全栈工程师开发手册 &#xff08;作者&#xff1a;栾鹏&#xff09; 一站式云原生机器学习平台 前言 开源地址&#xff1a;https://github.com/tencentmusic/cube-studio cube studio 腾讯开源的国内最热门的一站式机器学习mlops/大模型训练平台&#xff0c;支持多租户&…

python sklearn机械学习模型-分类

&#x1f308;所属专栏&#xff1a;【机械学习】✨作者主页&#xff1a; Mr.Zwq✔️个人简介&#xff1a;一个正在努力学技术的Python领域创作者&#xff0c;擅长爬虫&#xff0c;逆向&#xff0c;全栈方向&#xff0c;专注基础和实战分享&#xff0c;欢迎咨询&#xff01; 您…

什么是应用安全态势管理 (ASPM):综合指南

软件开发在不断发展&#xff0c;应用程序安全也必须随之发展。 传统的应用程序安全解决方案无法跟上当今开发人员的工作方式或攻击者的工作方式。 我们需要一种新的应用程序安全方法&#xff0c;而ASPM在该方法中发挥着关键作用。 什么是 ASPM&#xff1f; 应用程序安全…

神经网络训练(一):基于残差连接的图片分类网络(ResNet18)

目录 一、简介:二、图片分类网络1.记载训练数据(torch自带的cifa10数据集)2.数据增强3.模型构建4.模型训练三、完整源码及文档一、简介: 基于残差连接的图片分类网络,本网络使用ResNet18作为基础模块,根据cifa10的特点进行改进网络,使用交叉熵损失函数和SGD优化器。本网…

源代码层面分析Appium-inspector工作原理

Appium-inspector功能 Appium Inspector 基于 Appium 框架&#xff0c;Appium 是一个开源工具&#xff0c;用于自动化移动应用&#xff08;iOS 和 Android&#xff09;和桌面应用&#xff08;Windows 和 Mac&#xff09;。Appium 采用了客户端-服务器架构&#xff0c;允许用户通…

实践Go的命令模式

简介 现在的软件系统往往是分层设计。在业务层执行一次请求时&#xff0c;我们很清楚请求的上下文&#xff0c;包括&#xff0c;请求是做什么的、参数有哪些、请求的接收者是谁、返回值是怎样的。相反&#xff0c;基础设施层并不需要完全清楚业务上下文&#xff0c;它只需知道…

Typora导出为Word

文章目录 一、场景二、安装1、网址2、解压并验证 三、配置四、重启Typora 一、场景 在使用Typora软件编辑文档时&#xff0c;我们可能需要将其导出为Word格式文件 当然我们可以直接在菜单里进行导出操作 文件-> 导出-> Word(.docx) 如果是第一次导出word文件&#xff0…

Python实现接糖果小游戏

介绍: 基于Pygame的糖果从屏幕顶部下落的游戏代码。这个游戏包括了一个可以左右移动的篮子来接住下落的糖果&#xff0c;接住糖果会增加得分。 代码: import pygame import random import os# 初始化pygame和设置屏幕大小 pygame.init() screen_width, screen_height 800, 6…

数据资产的创新应用与未来展望:探讨数据资产在人工智能、物联网等新兴领域的应用前景,提出前瞻性的数据资产解决方案,为企业探索新的增长点,推动行业创新发展

目录 一、引言 二、数据资产在人工智能领域的应用 1、机器学习与深度学习 2、自然语言处理 3、计算机视觉 三、数据资产在物联网领域的应用 1、智能家居 2、工业物联网 3、智慧城市 四、前瞻性的数据资产解决方案 1、构建统一的数据管理平台 2、加强数据安全和隐私…

OkHttp的源码解读1

介绍 OkHttp 是 Square 公司开源的一款高效的 HTTP 客户端&#xff0c;用于与服务器进行 HTTP 请求和响应。它具有高效的连接池、透明的 GZIP 压缩和响应缓存等功能&#xff0c;是 Android 开发中广泛使用的网络库。 本文将详细解读 OkHttp 的源码&#xff0c;包括其主要组件…

认识100种电路之耦合电路

在电子电路的世界中&#xff0c;耦合电路宛如一座精巧的桥梁&#xff0c;连接着各个功能模块&#xff0c;发挥着至关重要的作用。 【为什么电路需要耦合】 在复杂的电子系统中&#xff0c;不同的电路模块往往需要协同工作&#xff0c;以实现特定的功能。然而&#xff0c;这些模…

推荐算法学习笔记2.1:基于深度学习的推荐算法-基于共线矩阵的深度推荐算法-NeuralCF模型

NeuralCF模型 NeuralCF模型将矩阵分解和逻辑回归思想进行结合&#xff0c;利用神经网络分别学习用户和物品的隐向量表示&#xff08;Embedding&#xff09;&#xff0c;然后将矩阵分解中的内积互操作替换成神经网络计算&#xff0c;从而更好地从特征中学习到有用的信息。 原论…

【划分型动态规划 马拉车 中心扩展】2472. 不重叠回文子字符串的最大数目

如果有不明白的&#xff0c;请加文末QQ群。 本文涉及知识点 划分型动态规划 马拉车 中心扩展 LeetCode2472. 不重叠回文子字符串的最大数目 给你一个字符串 s 和一个 正 整数 k 。 从字符串 s 中选出一组满足下述条件且 不重叠 的子字符串&#xff1a; 每个子字符串的长度 …

SCI一区 | Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测

SCI一区 | Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测 目录 SCI一区 | Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测预测效果基本介绍程序设计参考资料 预测效果 基本介绍 1.【SCI一区级】Matlab实现DBO-TCN-LSTM-Attention多变量时间序列预测&#xff08;程…

Golang | Leetcode Golang题解之第210题课程表II

题目&#xff1a; 题解&#xff1a; func findOrder(numCourses int, prerequisites [][]int) []int {var (edges make([][]int, numCourses)indeg make([]int, numCourses)result []int)for _, info : range prerequisites {edges[info[1]] append(edges[info[1]], info[0…