mysql的主从复制,读写分离

news2024/10/5 12:51:26

主从复制:主mysql的数据,新增,修改,表里的数据都会同步到从mysql上

主从复制的模式:

1 异步复制

mysql 的最常用的复制,只要执行完,客户端提交事务,主mysql 会立即把结果返回给从服务器,主服务器并不关心从mysql是否接收是否处理,主一旦崩溃,主mysql的事务可能没有传到从MySQL,这个时候强行把从提升为主,可能到新mysql的数据不完整

2全同步复制

主库完成一个事务,所有的从库执行了该事物,才会返回给客户端,因为要等待所有从库全部执行完成,性能必须下降(适用于对数据一致性,和数据完整性很好的场景)

3 半同步复制

介于异步和全同步复制之后,主库执行完一个客户端的事务之后,至少等待一个库的接收完成之后,才会返回给客户端,半同步在一定程度上提高了数据的安全性,也会有一定的延迟延迟一般是个tcp、IP的往返时间(从发送到接收的时间,单位是是毫秒)半同步复制用在网络电视上,时间<1ms:round-trip time RTT

实验架构:

主从复制 和读写分离

Mysql1 主192.168.233.21

Mysql2 从 192.168.233.22

Mysql3 从192.168.233.23

Test1读写分离的服务器 amoeba 192.168.233.10

Test5 客户端 192.168.233.20

#关闭防火墙和安全机制

systemctl stop firewalld

setenforce 0

#设置主从服务器的时间同步工具

yum -y install ntp

#主服务器上本地设置时钟源,注意网段修改 

#设置时间层级为8(限制在15秒内)

#数字越小表示时钟源越精确。通常,
本地时钟源被设置为较高的 stratum 等级(例如,8)以表示它不是通过网络获取的,
而是本地的。

vim /etc/ntp.conf

systemctl restart ntpd

#从服务器设置

systemctl restart ntpd

#2台从服务器分别指向源服务器

/usr/sbin/ntpdate 192.168.233.21

#2台从服务器分别新建一个定时任务

crontab -e -u root

#3台主机的时间同时查看是否一致

date

#主mysql主服务器开启二进制日志,允许从服务器复制数据时,可以从主的二进制写到自己的二进制日志当中

vim /etc/my.cnf

systemctl restart mysqld

#进入主服务器的mysql的数据库

mysql -u root -p123456

##新建一个用户授权给从服务器授权

grant replication slave on *.* to 'myslave'@'192.168.233.%' indendified by '123456';

#查看主服务器的状态,查看position是多少

show master status;

##修改从服务器的的mysqld ,注意id  master 和两个slave的id 也要不同

vim /etc/my.cnf

systemctl restart mysqld

Server-id = 2

Relay-log=relay-log-bin

Relay-log-index=slave-relay-bin.index

Relay_log_recovery=1

默认是0  1开启中继日志的服务器,从服务器出现异常或者崩溃时,从服务器会从主服务器的二进制争取和应用中继日志同步

Server-id = 3

Relay-log=relay-log-bin

Relay-log-index=slave-relay-bin.index

Relay_log_recovery=1

第一台从id 是 2 

第二台id是3

##2台服务器进入musql数据库

mysql -u root -p123456

#配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致

CHANGEmastertomaster_host='192.168.233.21',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=604;               

2台从服务器操作

#启动同步,如有报错执行reset slave;

start slave;

#查看slave 状态

Slave_io_running:yes 负责和主库的io通信

Slave_sql running:yes 负责自己的slave mysql进程

##这里 如果报错显示是 slave io running:no

1 网络问题

2 my.cnf 配置文件写错了

3 密码、file文件名、pos偏移量不对
4 防火墙没有关闭

##验证主从复制是否成功

在主服务器上创建一个表,两个从也有表

mysql 的主从复制延迟

原因:

网络延迟

主从硬件设备导致(CPU主频,内存IO,硬盘IO)

同步复制,而不是异步复制

解决方案:

1硬件方面 

从库配置更好的硬件,提升随机写的性能,比如原本是机械盘,可以考虑更换为ssd固态。升级核心数更强的cpu,加大内存,避免使用虚拟云主机,使用物理机

2 网络方面

将从库分布在相同局域网内或者网路延迟较小的中,尽量避免夸机房,扩网域进行主从服务器的配置

3 架构方面

在事务中尽量对主库读写,其他事物的读在从库中,消除一部分延迟带来的数据库不一致,增加缓存降低一些从库的负载。

4 mysql 的服务配置方面

该配置针对mysql主从复制性能优化最大化,安全性并不高,如果从安全的角度考虑的话,就要设置双一设置

追求安全性的双一设置:

innodb_flush_log_at_trx_commit=1

0: 事务提交时不刷新事务日志,而是每秒进行一次日志刷新,这可以提高性能,但在发生故障时可能会导致数据丢失

1:默认值 每次事务提交都会刷新日志,确保事务的持久性,这提供了最高级别的数据安全性,但可能会影响性能

2 事务提交时将四五日志写入操作系统缓存中,但不进行物理刷新,这提供了一定的数据安全性和性能

sync_binlog=1

0: 二进制日志写入操作系统缓存,但不进行物理刷新,这提高了最高性能,但在发生故障时可能会导致数据丢失

1 :默认值,每次提交事务都会二进制日志刷新到磁盘,以确保日志的持久性,这提供了较高级别的数据安全性

N:每次事务提交时,将二进制日志刷新到磁盘,但是最多每N个事务执行一次物理刷新,这在某些情况下可以提高性能,但是在发生故障时可能会导致少量数据丢失

追求性能化设置:

sync_binlog=0:

设置为0表示二进制日志(binary log)写入操作系统缓存,但不进行物理刷新。

这提供了较高的性能,但在系统崩溃或断电时可能会导致未刷新的二进制日志数据的丢失。

innodb_flush_log_at_trx_commit=2:

设置为2表示事务提交时将事务日志写入操作系统缓存,但不进行物理刷新。

这提供了一定的性能提升,但在系统崩溃或断电时可能会导致未刷新的事务日志数据的丢失。

logs-slave-updates=0:

如果设置为0,表示不将从库的更新写入二进制日志。

这对于避免在主从复制中引入循环复制(circular replication)很有用。

增大 innodb_buffer_pool_size:

innodb_buffer_pool_size 控制 InnoDB 存储引擎的缓冲池大小。增大这个值可以提高 InnoDB 的性能,

因为更多的数据和索引可以缓存在内存中,减少了对磁盘的访问次数。但要注意,

设置得太大可能导致系统内存不足。

主从复制的工作过程:

1 主节点的数据记录发生变化,都会记录到二进制日志

2 slave节点会在一定时间内对主库的二进制文件进行探测,看是否发生 变化,开启一个I/O的线程,请求到主库的二进制事件

3 主库会把每一个I/O的线程启动一个dump,用于发送二进制事件给从库,从库通过I/O线程获取更新,slave sql 负责更新写入到从库本地,实现主从一致

主从复制问题:

1 只能在主库发生变化,然后同步到从

2 复制过程是串行化过程,在从库上时复制串行的,主库的更新不能从从库上操作。

3 主从涉及的目的就是为了在主库上写,在从库上查,读写分离实现高可用

读写分离:

要实现读写分离,必须要实现主从复制

读写分离:所有的写入操作都在主库,从库只负责读(select)r如果有更新是从主库到从库

为什么要有读写分离:

1 数据库在写入数据时比较耗时

2 但是读的速度很快

读写分离之后数据库的写入和读取是分开,哪怕写入的数据量比较大,也不影响查询的效率。

什么场景下需要读写分离:

数据库不是一定要读写分离的,只有在某些程序的使用数据库中, 更新少查询的较多,或者读写读写需求差不多的情况下,会考虑读写分离

生产中一般都会读写分离

测试库一般不用

在工作中,数据库都会做读写分离,数据库的读写不在同一个库完成,否则不能实现高可用,高并发,

mysql读写分离的原理:

1 根据脚本实现,在代码中实现路由分类,select insert 进行路由分类,这种方式最多的,性能好,在代码中可以实现,不需要额外的设备

缺点:开发实现的和我们无关,如果是大型复杂的应用,涉及改动的代码非常多

2 基于中间代理层实现

mysql-proxy自带的开源项目,基于自带的java脚本,这些脚本不是现成的,要自己写,不熟悉他的内置变量,写不出来,

atlas 360 内部多自己使用的代理工具,每天的读写请求载量可以达到几十亿条,支持事务支持存储的过程,

amoeba 陈思儒是由Java开发的一个开源团建,不支持事务,也不支持存储过程

搭建MySQL读写分离

注:做读写分离实验之前必须有一主两从环境

Mysql1 主192.168.233.21

Mysql2 从 192.168.233.22

Mysql3 从192.168.233.23

Test1读写分离的服务器 amoeba 192.168.233.10

Test5 客户端 192.168.233.20

jdk1.5开发的官方推荐我们使用1.5.1.6

amoeba 服务器配置

##安装java环境

因为amoeba是基于jdk1.5开发的,所有官方推荐使用jdk1.5/jdk1.6版本,高版本不建议使用,

cd /opt/

cp jdk-6u14-linux-x64.bin /usr/local/

cd /usr/local/

chmod +x jdk-6u14-linux-x64.bin

./jdk-6u14-linux-x64.bin

//按yes,按enter

mv jdk1.6.0_14/ /usr/local/jdk1.6

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:$HOME/bin

export AMOEBA_HOME=/usr/local/amoeba

export PATH=$PATH:$AMOEBA_HOME/bin

source /etc/profile

java -version

##安装 Amoeba软件##

mkdir /usr/local/amoeba

tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/

chmod -R 755 /usr/local/amoeba/

/usr/local/amoeba/bin/amoeba

//如显示amoeba start|stop说明安装成功

##配置 Amoeba读写分离,两个 Slave 读负载均衡##

#先在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问

grant all on *.* to amoeba@'192.168.233.%' identified by '123456';

flush privileges;

###再回到amoeba服务器配置amoeba服务:

cd /usr/local/amoeba/conf/

cp amoeba.xml amoeba.xml.bak

vim amoeba.xml #修改amoeba配置文件

--30行--

<property name="user">amoeba</property>

--32行--

<property name="password">123456</property>

--115行--

<property name="defaultPool">master</property>

--117-去掉注释-

<property name="writePool">master</property>

<property name="readPool">slaves</property>

cp dbServers.xml dbServers.xml.bak

vim dbServers.xml #修改数据库配置文件

--23行--注释掉  作用:默认进入test库 以防mysql中没有test库时,会报错

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

--26--修改

<property name="user">amoeba</property>

--28-30--去掉注释

<property name="password">123456</property>

--45--修改,设置主服务器的名Master

<dbServer name="master"  parent="abstractServer">

--48--修改,设置主服务器的地址

<property name="ipAddress">192.168.233.21</property>

--52--修改,设置从服务器的名slave1

<dbServer name="slave1"  parent="abstractServer">

--55--修改,设置从服务器1的地址

<property name="ipAddress">192.168.233.22</property>

--58--复制上面6行粘贴,设置从服务器2的名slave2和地址

<dbServer name="slave2"  parent="abstractServer">

<property name="ipAddress">192.168.233.23</property>

--65行--修改

<dbServer name="slaves" virtual="true">

--71行--修改

<property name="poolNames">slave1,slave2</property>

/usr/local/amoeba/bin/amoeba start & #启动Amoeba软件,按ctrl+c 返回

netstat -anpt | grep java #查看8066端口是否开启,默认端口为TCP 8066

配置用户信息

少个图

----测试读写分离 ----

yum install -y mariadb-server mariadb

systemctl start mariadb.service

#在主从服务器上开启查询日志

general_log=ON

general_log_file=/usr/local/mysql/data/mysql_general.log

在客户端服务器上测试:

mysql -u amoeba -p123456 -h 192.168.233.10 -P8066

//通过amoeba服务器代理访问mysql ,在通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从--从服务器

在主服务器上:

use db_test;

create table test (id int(10),name varchar(10),address varchar(20));

在两台从服务器上:

stop slave; #关闭同步

use db_test;

//在slave1上:

insert into test values('1','zhangsan','this_is_slave1');

//在slave2上:

insert into test values('2','lisi','this_is_slave2');

//在主服务器上:

insert into test values('3','wangwu','this_is_master');

//在客户端服务器上:

use db_test;

select * from test; //客户端会分别向slave1和slave2读取数据,显示的只有在两个从服务器上添加的数据,没有在主服务器上添加的数据

insert into test values('4','qianqi','this_is_client'); //只有主服务器上有此数据

//在两个从服务器上执行 start slave; 即可实现同步在主服务器上添加的数据

start slave;

少了个图

面试题:

1 主从复制的原理

2 读取分离的实现方式: 脚本,amoeba实现,mycat实现

通过amoeba代理服务器,实现只在主服务器上写,只在从服务器上读;

主数据库处理事务性查询,从数据库处理select 查询;

数据库复制被用来把事务查询导致的变更同步的集群中的从数据库

3如何查看主从复制时候否成功?

在从服务器上内输入 show slave status\G 查看主从信息查看里面有IO线程的状态信息,还有master服务器的IP地址、端口事务开始号。

当 Slave_IO_Running和Slave_SQL_Running都是YES时 ,表示主从同步状态成功

4 如果slave_IO_running no 排查思路?

大概率是配置文件出错

首先排查网络问题,使用ping 命令查看从服务器是否能与主服务器通信

再查看防火墙和核心防护是否关闭(增强功能)

接着查看从服务slave是否开启

两个从服务器的server-id 是否相同导致只能连接一台

master_log_file master_log_pos的值跟master值是否一致

5 show slave status\G;能看到的信息有哪些

IO和sql的线程状态信息

MASTER服务的ip 地址,端口事务开始的位置

最近一次的错误信息,和错误的位置

最近一次IO 报错信息

最近i一次sql的报错信息

6 主从复制的延迟如何解决?

主服务器的负载过大,被多个睡眠或 僵尸线程占用  导致系统负载过大,从库硬件比主库差,导致复制延迟

主从复制单线程,如果主库写作并发太大,来不及传送到从库,就会到导致延迟

慢sql语句过多

网络延迟

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

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

相关文章

大厂设计师必备的8款Sketch插件

每个设计师都渴望有一个高效的插件来提高他们的设计能力。设计插件有助于自动化工作流程&#xff0c;快速组织设计文件或简化内容创建。Sketch可以说是设计师知名的设计工具&#xff0c;特别是其资源社区拥有丰富的Sketch插件&#xff0c;大大提高了设计师的工作效率。本文让设…

虹科教您 | 如何选择超声波储罐液位传感器(二)

来源&#xff1a;虹科传感器 虹科教您 | 如何选择超声波储罐液位传感器&#xff08;二&#xff09; 教程背景 超声波储罐液位传感器具有非接触式测量的优点&#xff0c;可以适用于各种不同的液体和环境。本教程将紧跟上期&#xff0c;通过Q&A的形式&#xff0c;帮助您根…

同城服务如何引流和推广 同城小程序制作

客观原因线下实体店经营变得很艰难&#xff0c;而抖音推出的同城号功能&#xff0c;为许多商家带来了新的生机。抖音同城号的操作很简单&#xff0c;只需在短视频发布时打开同城号&#xff0c;短视频将被投入到同城流量池中&#xff0c;可以让位置附近的用户看到&#xff0c;线…

阿里云容器镜像服务的运维总结

一、背景 容器镜像服务&#xff0c;作为一个可选付费产品&#xff0c;主要作用是存储docker的镜像仓库&#xff0c;供k8s拉取到Pod节点里。 你可以自己搭建一个harbor镜像仓库&#xff0c;在公司的开发环境下&#xff0c;将image推送到仓库&#xff1b;然后在生产k8s从仓库拉取…

Matplotlib的使用方法

Matplotlib是Python最著名的绘图库&#xff0c;它提供了一整套和Matlab相似的命令API&#xff0c;十分适合交互式地进行制图。而且也可以方便地将它作为绘图控件&#xff0c;嵌入到GUI应用程序中。Matplotlib能够创建多数类型的图表&#xff0c;如条形图、散点图、条形图、饼图…

数据结构 1、基本概念 动态数组实现

一、大O表示法 判断一个算法的效率 难点 二、线性表 1.定义 2.数学定义 线性表是具有相同类型的n&#xff08;n>0&#xff09;个数据元素的有限序列&#xff08;a0,a1,a2,...,an&#xff09;,ai是表项&#xff0c;n是表长度 3.性质 4.线性表的基本操作 1.创建线性表 2…

blockly编程简介

blockly编程简介 blockly是google发布的可视化编程工具&#xff0c;基于web技术构建。 在功能/设计上和MIT的儿童编程语言Scratch类似&#xff0c;采用可视化搭积木编程方式。 可以将基于block程序转化为基于普通文本的常规代码&#xff08;如JavaScript、Python等&#xff…

leetcode:2935. 找出强数对的最大异或值 II【最大异或值还是得看01Trie树啊!】

题目截图 题目分析 排序后&#xff0c;限定了x和y的相对位置 假设y > x&#xff0c;随着y的移动&#xff0c;必须要保证2x > y 所以可以使用滑动窗口维护一堆满足条件的x 这些x的异或值记录在Trie树中即可 ac code class Node:__slots__ children, cntdef __init__(s…

C++ 对象的拷贝、赋值、清理和移动(MyString类)

MyString类 MyString.h #ifndef MYSTRING_H #define MYSTRING_H#include <iostream> using namespace std;class MyString {private:char* str nullptr;unsigned int MaxSize 0;public:MyString(); /*默认构造函数*/MyString(unsigned int n); /*有…

Spring源码系列-Spring AOP

目录 AOP的用法 注解用法 早期的基于接口的用法 递归实现的责任链模式 简单实现 责任链模式就两个关键点 传统的aop实现方式的局限性 Advisor 解决不能精确到方法级别的增强 注解形式的Advisor 解决需要创建多个FactoryBean 纯注解的AOP实现原理 AOP源码解析 AOP…

pta 6翻了 Python3

“666”是一种网络用语&#xff0c;大概是表示某人很厉害、我们很佩服的意思。最近又衍生出另一个数字“9”&#xff0c;意思是“6翻了”&#xff0c;实在太厉害的意思。如果你以为这就是厉害的最高境界&#xff0c;那就错啦 —— 目前的最高境界是数字“27”&#xff0c;因为这…

camera tuning 常识

#灵感# 把收集的乱东西&#xff0c;归在一起。字体颜色标浅色的&#xff0c;是扩展内容&#xff0c;为了先简单了解&#xff0c;并不做很细致的阐述。 &#xff08;1&#xff09;模组 集成封装好的模组&#xff0c;一般由三个部分组成&#xff1a;镜头&#xff08;lens&#…

如何利用反欺诈(羊毛盾)API提升电商平台交易安全性?

前言 近年来&#xff0c;随着网络交易的普及和互联网金融的快速发展&#xff0c;各类网络欺诈事件层出不穷。面对这些问题&#xff0c;电商平台必须采取有效的措施来保障交易安全。而反欺诈&#xff08;羊毛盾&#xff09;API正是一种高效、智能的解决方案&#xff0c;能够帮助…

LeetCode(10)跳跃游戏 II【数组/字符串】【中等】

目录 1.题目2.答案3.提交结果截图 链接&#xff1a; 45. 跳跃游戏 II 1.题目 给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说&#xff0c;如果你在 nums[i] 处&#xff0c;你可以跳转到任意 nu…

XML Web 服务 Eclipse实现中的sun-jaxws.xml文件

说明 在sun-jaxws.xml文件&#xff0c;可以配置endpoint、handler-chain等内容。在这个文件中配置的内容会覆盖在Java代码中使用注解属性配置的的内容。 这个文件根据自己的项目内容修改完成以后&#xff0c;作为web应用的一部分部署到web容器中&#xff08;放到web应用的WEB…

高效批量剪辑、处理和添加水印,用视频批量剪辑高手轻松搞定!

您是否曾经在处理大量视频时&#xff0c;因为剪辑、处理和添加水印等问题而感到烦恼&#xff1f;是否因为这些问题而大大降低了您的工作效率&#xff1f;现在&#xff0c;我们为您推荐一款全新的视频批量剪辑工具——视频批量剪辑高手&#xff0c;让您的工作效率瞬间翻倍&#…

听10秒语音就能判断糖尿病,这个AI大模型太硬核了!

加拿大的Klick科研人员在顶级健康杂志《梅奥诊所文集&#xff1a;数字健康》上发布了一个AI大模型&#xff0c;只需要听一段6—10秒的语音&#xff0c;就能诊断是否患有2型糖尿病&#xff08;T2DM&#xff09;。 目前糖尿病的主要检测方式依赖于血糖测量&#xff0c;但这种方法…

【06】VirtualService高级流量功能

5.3 weight 部署demoapp v10和v11版本 --- apiVersion: apps/v1 kind: Deployment metadata:labels:app: demoappv10version: v1.0name: demoappv10 spec:progressDeadlineSeconds: 600replicas: 3selector:matchLabels:app: demoappversion: v1.0template:metadata:labels:app…

基于token的多平台身份认证架构设计

1 概述 在存在账号体系的信息系统中&#xff0c;对身份的鉴定是非常重要的事情。 随着移动互联网时代到来&#xff0c;客户端的类型越来越多&#xff0c; 逐渐出现了 一个服务器&#xff0c;N个客户端的格局 。 不同的客户端产生了不同的用户使用场景&#xff0c;这些场景&…

Python实现cpu密集型多线程

问题&#xff1a; 想通过以下代码实现多线程 class ThreadTest(threading.Thread):def __init__(self, num, *args, **kwargs):super(ThreadTest, self).__init__(*args, **kwargs)self.num numprint(num)def run(self):print(self.num)print(time.time())if __name__ &quo…