详解MySQL主从复制

这篇具有很好参考价值的文章主要介绍了详解MySQL主从复制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

目录

1.概述

2.配置使用

2.1.master配置

2.2.slave配置

2.3.认主

2.4.确认认主结果

3.请求分发

3.1.概述

3.2.手动分发

3.2.1.原生JDBC

3.2.2.数据源

3.2.3.中间件


1.概述

在实际的数据密集型应用中,数据库层面往往呈现两个特点:

  • 单点数据库难以扛得住。
  • 读操作远远多于写操作。

综上所述我们可以使用多个数据库节点来组成集群的。采用主从结构来进行数据同步,多个slave节点向一个master节点拿数据。对数据库的写操作(insert)全在master上节点上进行,从而保证master的数据是全局最新最完整的,slave去master上拿数据进行数据同步,然后读操作就可以负载均衡的分发到不同的从节点上进行处理,这样就有效的减轻了数据库中单节点的压力。

以上说的方式就是MySQL的"主从复制",它是MySql最常见的集群方式之一。

以下是MySQL主从复制的实现原理:

master将操作记录写到自己的二进制日志文件,salve开一个线程去读master的日志文件,将日志内容写到中继日志中,再照着中继日志,做一遍其中的事件。

详解MySQL主从复制

2.配置使用

2.1.master配置

配置文件添加以下内容:

server-id=1  集群中每个server的server-id保持唯一性。

log-bin=mysql-bin 开启二进制日志文件,并将日志文件命名为mysql-bin

2.2.slave配置

配置文件添加以下内容:

server-id=2 集群中每个server的server-id保持唯一性。

log-bin=XXX  如果是扮演单独的从节点,而不扮演链式结构中其他节点的主节点,可以不配。

2.3.认主

注意:无论master还是slave,重启后都必须重新认主!

在master上使用

show master status;

可以查看到主节点的日志文件在集群中的名称以及分区号:

详解MySQL主从复制

在从节点上进行认主操作:

change master to master_host='192.168.1.100',

master_user='root',master_password='admin',

master_log_file=' mysql-bin.000001',

master_log_pos= 154;

注意:从节点上配置认主的时候,master_user 和master_password所配置的账号必须要有复制权限,如果没有权限的话,需要额外进行权限分配。

分配方式:

在master上:

GRANT REPLICATION SLAVE ON *.* TO '用户名'@'%';

FLUSH PRIVILEGES;

2.4.确认认主结果

认主操作完成后,可以在从节点上确认是否成功与master同步:

show slave status\G0;

会显示以下内容:

详解MySQL主从复制

其中有两个进程:

  1. slave_io_running,负责与master通信,

    slave_sql_running,负责自己的sql。

两个进程都必须同时为yes才可以正常完成主从复制。

但是默认情况下一旦出现sql错误,slave_sql_running线程会直接阻塞,变为状态变为no。

通过在slave上配置遇见错误跳过,即可:

详解MySQL主从复制

3.请求分发

3.1.概述

配置完主从复制后,还存在一个问题,就是业务层面怎么将请求区分出来分别进行转发,怎么将写请求分发到master节点、将读请求分发到slave节点。

方法有两种:

  • 手动分发
  • 使用中间件

手动分发,即手动将写操作分发到master节点上,读操作分发到slave节点上。

3.2.手动分发

3.2.1.原生JDBC

实际工程中原生JDBC很少会使用了,这里节约篇幅只说一下实现思想,不做展开。如果是使用原生JDBC的话,每个数据库节点准备一套对应的JDBC连接参数(url、username、password),读的时候进行一次负载均衡,先确定出写到哪个slave上去,然后用该slave对应的那套JDBC连参数去取connection就行了。

3.2.2.数据源

如果是使用了数据源的话,可以使用多数据源的方式来实现请求的分发。为master和slave分别准备数据源,将写操作、读操作分别放在不同的mapper,每个mapper用不同的数据源,将请求分发到不同的节点上去。

以下是spring boot+mybatis的示例:

配置多数据源:

# 主节点数据源配置
spring.datasource.master.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.master.jdbc-url=jdbc:mysql://master-host:3306/database
spring.datasource.master.username=username
spring.datasource.master.password=password

# 从节点数据源配置
spring.datasource.slave.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.slave.jdbc-url=jdbc:mysql://slave-host:3306/database
spring.datasource.slave.username=username
spring.datasource.slave.password=password

配置数据源和SqlSessionFactory:

@Configuration
@MapperScan(basePackages = "com.example.mappers", sqlSessionTemplateRef = "masterSqlSessionTemplate")
public class MasterDataSourceConfig {
    @Bean(name = "masterDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSource masterDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "masterSqlSessionFactory")
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);
        // 其他配置项
        return sessionFactoryBean.getObject();
    }

    @Bean(name = "masterSqlSessionTemplate")
    public SqlSessionTemplate masterSqlSessionTemplate(@Qualifier("masterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

@Configuration
@MapperScan(basePackages = "com.example.mappers", sqlSessionTemplateRef = "slaveSqlSessionTemplate")
public class SlaveDataSourceConfig {
    @Bean(name = "slaveDataSource")
    @ConfigurationProperties(prefix = "spring.datasource.slave")
    public DataSource slaveDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean(name = "slaveSqlSessionFactory")
    public SqlSessionFactory slaveSqlSessionFactory(@Qualifier("slaveDataSource") DataSource dataSource) throws Exception {
        SqlSessionFactoryBean sessionFactoryBean = new SqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);
        // 其他配置项
        return sessionFactoryBean.getObject();
    }

    @Bean(name = "slaveSqlSessionTemplate")
    public SqlSessionTemplate slaveSqlSessionTemplate(@Qualifier("slaveSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
        return new SqlSessionTemplate(sqlSessionFactory);
    }
}

在mapper上进行分发:

@Mapper
@Qualifier("masterSqlSessionTemplate")
public interface MasterMapper {
    // 主节点操作
    @Insert("XXXXX")
    int insertToMaster();
}

@Mapper
@Qualifier("slaveSqlSessionTemplate")
public interface SlaveMapper {
    // 从节点操作
    @Select("XXXX")
    List<MyEntity> selectFromSlave();
}

这里还是会存在一个问题就是没有充分利用到slave节点来进行负载均衡,我们可以改进一下:

首先实现自己的负载均衡策略:

public class LoadBalanceDataSource {
    private List<SqlSessionTemplate> sqlSessionTemplates;

    public LoadBalanceDataSource(List<SqlSessionTemplate> sqlSessionTemplates) {
        this.sqlSessionTemplates = sqlSessionTemplates;
    }

    public SqlSessionTemplate getReadSqlSessionTemplate() {
        // 根据负载均衡算法选择一个从节点
        int index = calculateIndex();
        return sqlSessionTemplates.get(index);
    }

    private int calculateIndex() {
        // 自定义负载均衡算法,例如轮询、随机等
        // 这里仅作示例,实际应根据具体情况选择适合的算法
        // ...
    }
}

然后将这个策略实体托管给IOC:

@Configuration
@MapperScan(basePackages = "com.example.mappers")
public class MyDataSourceConfig {
    @Autowired
    private List<SqlSessionTemplate> sqlSessionTemplates;

    @Bean
    public LoadBalanceDataSource loadBalanceDataSource() {
        return new LoadBalanceDataSource(sqlSessionTemplates);
    }
}

然后,在需要的地方,注入:

@Service
public class MyService {
    @Autowired
    private LoadBalanceDataSource loadBalanceDataSource;

    public void readOperation() {
        SqlSessionTemplate readSqlSessionTemplate = loadBalanceDataSource.getReadSqlSessionTemplate();
        // 使用readSqlSessionTemplate执行读操作
        // ...
    }
}

3.2.3.中间件

前面手动分发的时候我们会发现一个问题,就是我们需要大量的代码去手写整个分发过程,而且需要我们去手动去写负载均衡算法,往往我们自己实现的负载均衡算法,效果不会很好。所以有没有开源组件可以帮我们实现请求分发的这个效果喃?其实有专门的这一类组件——数据库中间件。它们在client和数据库server间作为中间层,请求先走到它们上面,它们再对请求做二次处理,这种二次处理就提供了诸如:负载均衡、安全访问控制、故障转移、请求过滤等能力。

以下给出一个使用数据库中间件中最热门、应用最为广泛的proxy sql解决读写请求分发的示例:

1.安装ProxySQL:根据您的操作系统,从ProxySQL的官方网站下载并安装适当版本的ProxySQL。

2.配置ProxySQL:创建ProxySQL的配置文件,通常为proxysql.cnf,并根据您的环境进行配置。以下是一个示例配置文件的基本结构:

datadir="/var/lib/proxysql"

admin_variables=
{
    admin_credentials="admin:admin"
    mysql_ifaces="0.0.0.0:6032"
}

mysql_variables=
{
    threads=4
    max_connections=2048
    default_query_delay=0
    default_query_timeout=36000000
    have_compress=true
    poll_timeout=2000
    interfaces="0.0.0.0:6033;/path/to/mysql.sock"
    default_schema="information_schema"
    stacksize=1048576
}

mysql_servers =
(
    { address = 'master_host', port = master_port, hostgroup = 1 },
    { address = 'slave1_host', port = slave1_port, hostgroup = 2 },
    { address = 'slave2_host', port = slave2_port, hostgroup = 2 },
    ...
)

mysql_users =
(
    { username = 'your_username', password = 'your_password', default_hostgroup = 1, active = 1 },
)

mysql_query_rules =
(
    { rule_id = 1, match_pattern = "^SELECT.*FOR UPDATE", destination_hostgroup = 1 },
    { rule_id = 2, match_pattern = ".*", destination_hostgroup = 2 },
)

在上述配置中,·需要替换以下内容:

admin_credentials中的用户名和密码,用于访问ProxySQL的管理接口。

mysql_servers中的主节点和从节点的主机名(或IP地址)和端口号。

mysql_users中的用户名和密码,用于连接到MySQL数据库。

mysql_query_rules中的规则,用于指定不同类型的查询应该转发到哪个主机组。

3.启动ProxySQL:运行以下命令启动ProxySQL:

proxysql --initial -f -c /path/to/proxysql.cnf

4.配置应用程序连接:将应用程序的数据库连接配置更改为连接到ProxySQL的地址和端口号。例如,使用JDBC连接字符串:

jdbc:mysql://proxysql_host:proxysql_port/database_name

proxysql_hostproxysql_port替换为ProxySQL的主机名(或IP地址)和端口号,database_name替换为实际的数据库名称。文章来源地址https://www.toymoban.com/news/detail-456250.html

到了这里,关于详解MySQL主从复制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • MySQL8.0.33主从复制配置记录

    官网:https://dev.mysql.com/downloads/mysql/ 在线下载或者下载到本地再上传 准备wget下载工具: 进入MySQL的bin目录 初始化并得到密码 ./mysqld: error while loading shared libraries: libnuma.so.1: cannot open shared object file: No such file or directory 报错,缺依赖:::: yum install -y libaio yum -y install numactl 再初始

    2024年02月02日
    浏览(41)
  • Mysql - 配置Mysql主从复制-keepalived高可用-读写分离集群

    目录 高可用: 为什么需要高可用呢? 高可用的主要作用: keepalived是什么?它用在哪里? 什么是VRRP协议,它的作用是什么? 搭建一个基于keepalived的高可用Mysql主从复制读写分离集群 一、项目中的IP地址配置表: 二、项目拓扑图: 项目步骤:(主从复制、读写分离、单vi

    2024年02月13日
    浏览(44)
  • MySQL主从复制入门指南:基础概念和配置步骤

    为了巩固所学的知识,作者尝试着开始发布一些学习笔记类的博客,方便日后回顾。当然,如果能帮到一些萌新进行新技术的学习那也是极好的。作者菜菜一枚,文章中如果有记录错误,欢迎读者朋友们批评指正。 (博客的参考源码可以在我主页的资源里找到,如果在学习的

    2024年02月14日
    浏览(44)
  • MySql运维篇---008:日志:错误日志、二进制日志、查询日志、慢查询日志,主从复制:概述 虚拟机更改ip注意事项、原理、搭建步骤

    错误日志是 MySQL 中最重要的日志之一,它记录了当 mysqld 启动和停止时,以及服务器在运行过程中 发生任何严重错误时的相关信息 。当数据库出现任何故障导致无法正常使用时,建议首先查看此日志。 该日志是默认开启的,默认存放目录 /var/log/,默认的日志文件名为 mysq

    2024年02月04日
    浏览(69)
  • CentOS7安装Mysql8并进行主从复制配置

    CentOS7中安装Mysql8并配置远程连接和修改密码等: CentOS7中安装Mysql8并配置远程连接和修改密码等_霸道流氓气质的博客-CSDN博客 在上面实现安装Mysql8的基础上,克隆出两台机器,修改ip后进行mysql的主从复制搭建。 在主库上把数据更改记录到二进制日志中(Binary Log)中,这些记

    2024年02月16日
    浏览(42)
  • 使用docker进行MYSQL主从复制(一主两从)

    目录 概述主从介绍 主从作用 主从作用有: 主从形式有:  配置步骤 主要配置 1创建三个进程 2修改配置文件 3主机配置 4从机配置 5将文件修改后,复制到容器里面 6进入主机进行配置 6.1创建用户 6.2给用户授权 6.3刷新权限 7进入从机进行配置 对M1S1 对M2S2  8最后开启主从 9测

    2024年02月16日
    浏览(41)
  • Redis(主从复制、哨兵模式、集群)概述及部署

    目录 一、Redis高可用 二、redis持久化 2.1 持久化的功能 2.2 Redis 提供两种方式进行持久化 2.3 RDB 持久化 2.3.1 触发条件  2.3.2 执行流程 2.3.3 启动时加载 2.4 AOF持久化 2.5 执行流程 2.5.1 命令追加(append)  2.5.2 文件写入(write)和文件同步(sync) 2.5.3 文件重写(rewrite) 2.5.3.1 文件重写的

    2024年02月15日
    浏览(35)
  • mysql(九)mysql主从复制

    MySQL的内建功能是构建基于MySQL的大规模,高性能应用的基础,这类应用使用所谓的“水平扩展”的架构。我们可以通过为服务器配置一个或多个从库的方式来进行数据同步,复制功能不仅有利于构建高性能的应用,同时也是高可用,可扩展性,灾难恢复,备份以及数据仓库等

    2024年02月09日
    浏览(42)
  • mysql的主从复制

    主从复制的原理是通过基于日志的复制方式实现数据的同步。当主服务器上发生数据变更时,会将这些变更写入二进制日志(Binary Log)中。从服务器通过连接到主服务器,请求从主服务器获取二进制日志,并将这些日志应用到自己的数据库中。 1. 主服务器生成二进制日志:

    2024年02月15日
    浏览(31)
  • 【MySQL】主从复制&部署

    SQL 什么是SQL? Structure Query Language(结构化查询语言) 它被美国国家标准局(ANSI)确定为关系型数据库语言的美国标准,后被国际化标准组织(ISO)采纳为关系数据库语言的国际标准。 数据库管理系统可以通过SQL管理数据库;定义和操作数据,维护数据的完整性和安全性。 优点 简单

    2024年02月08日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包