Mysql集群部署实现主从复制读写分离分表分库 2

简介: Mysql集群部署实现主从复制读写分离分表分库

3 主从复制

主从复制的概念


为了使用Mycat进行读写分离,我们先要配置MySQL数据库的主从复制。

从服务器自动同步主服务器的数据,从而达到数据一致。

进而,我们可以写操作时,只操作主服务器,而读操作,就可以操作从服务器了。

原理:主服务器在处理数据时,生成binlog日志,通过对日志的备份,实现从服务器的数据同步。


2111d857be61478a873440ed4bba3e70.png

主服务器的配置


在第一个服务器上,编辑mysql配置文件

  // 编辑mysql配置文件
  vi /etc/my.cnf
  //在[mysqld]下面加上:
  log-bin=mysql-bin # 开启复制操作
  server-id=1 # master is 1
  innodb_flush_log_at_trx_commit=1
  sync_binlog=1

登录mysql,创建用户并授权

  // 登录mysql
  mysql -u root -p
  // 去除密码权限
  SET GLOBAL validate_password_policy=0;
  SET GLOBAL validate_password_length=1;
  // 创建用户
  CREATE USER 'hm'@'%' IDENTIFIED BY 'itheima';
  // 授权
  GRANT ALL ON *.* TO 'hm'@'%';

重启mysql服务,登录mysql服务

  // 重启mysql
  service mysqld restart
  // 登录mysql
  mysql -u root -p

查看主服务器的配置

  // 查看主服务器配置
  show master status;

2d614073bf2f4ef1803cceb6e32ef942.png

从服务器的配置


在第二个服务器上,编辑mysql配置文件

// 编辑mysql配置文件
vi /etc/my.cnf
// 在[mysqld]下面加上:
server-id=2

登录mysql

// 登录mysql
mysql -u root -p
// 执行
use mysql;
drop table slave_master_info;
drop table slave_relay_log_info;
drop table slave_worker_info;
drop table innodb_index_stats;
drop table innodb_table_stats;
source /usr/share/mysql/mysql_system_tables.sql;


重启mysql,重新登录,配置从节点

// 重启mysql
service mysqld restart
// 重新登录mysql
mysql -u root -p
// 执行
change master to master_host='主服务器ip地址',master_port=3306,master_user='hm',master_password='itheima',master_log_file='mysql-bin.000001',master_log_pos=4642;

重启mysql,重新登录,开启从节点

// 重启mysql
service mysqld restart
// 重新登录mysql
mysql -u root -p
// 开启从节点
start slave;
// 查询结果
show slave status\G;
//Slave_IO_Running和Slave_SQL_Running都为yes才表示同步成功。

a370f710ade2408da60f1a1336e204d8.png


测试


sqlyog连接主服务器

-- 主服务器创建db1数据库,从服务器会自动同步
CREATE DATABASE db1;

sqlyog连接从服务器

-- 从服务器创建db2数据库,主服务器不会自动同步
CREATE DATABASE db2;

启动失败的解决方案

启动失败:Slave_IO_Running为 NO 
方法一:重置slave
slave stop;
reset slave;
start slave ;
方法二:重设同步日志文件及读取位置
slave stop;
change master to master_log_file=’mysql-bin.000001’, master_log_pos=1;
start slave ;

4 读写分离

读写分离的概念


写操作只写入主服务器,读操作读取从服务器。

在主服务器上修改server.xml


user标签主要用于定义登录mycat的用户和权限。如上面定义用户名mycat和密码123456,该用户可以访问的schema的HEIMADB逻辑库。

<user name="root" defaultAccount="true">
    <property name="password">123456</property>
    <property name="schemas">HEIMADB</property>
    <!-- 表级 DML 权限设置 -->
    <!--    
    <privileges check="false">
      <schema name="TESTDB" dml="0110" >
        <table name="tb01" dml="0000"></table>
        <table name="tb02" dml="1111"></table>
      </schema>
    </privileges>   
     -->
</user>

在主服务器上修改schema.xml

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
  <schema name="HEIMADB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1"></schema>
  <dataNode name="dn1" dataHost="localhost1" database="db1" />
  <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
        writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <!-- 主服务器进行写操作 -->
    <writeHost host="hostM1" url="localhost:3306" user="root"
           password="itheima">
    <!-- 从服务器负责读操作 -->
    <readHost host="hostS1" url="192.168.203.135:3306" user="root" password="itheima" />
    </writeHost>
  </dataHost>
</mycat:schema>

配置详解


schema标签逻辑库的概念和mysql数据库中Datebase的概念相同,我们在查询这两个逻辑库中的表的时候,需要切换到该逻辑库下才可以查到所需要的表。


dataNode属性:该属性用于绑定逻辑库到某个具体的database上。


dataNode标签: dataNode标签定义了mycat中的数据节点,也就是数据分片。一个dataNode标签就是一个独立的数据分片。


name属性:定义数据节点的名字,这个名字需要是唯一的,我们需要在table标签上应用这个名字,来建立表与分片对应的关系。


dataHost属性:该属性用于定义该分片属于那个数据库实例,属性值是引用datahost标签定义的name属性。


database属性:该属性用于定义该分片属于那个具体数据库实例上的具体库,因为这里使用两个纬度来定义分片,就是:实例+具体的库。因为每个库上建立的表和表结构是一样的。所以这样做就可以轻松的对表进行水平拆分。


dataHost标签:该标签在mycat逻辑库中也是作为最底层的标签存在,直接定义了具体的数据库实例、读写分离配置和心跳语句。


balance属性: 负载均衡类型

balance=0: 不开启读写分离,所有读操作都发送到当前可用的writeHost上。

balance=1: 全部的readHost与Stand by writeHost都参与select语句的负载均衡

balance=2: 所有的读操作都随机在writeHost,readHost上分发。

balance=3: 所有的读请求都随机分配到writeHost对应的readHost上执行,writeHost不负担读压力。


switchType属性:

-1:表示不自动切换。

1 :默认值,表示自动切换

2:表示基于MySQL主从同步状态决定是否切换,心跳语句: show slave status.

3:表示基于mysql galary cluster的切换机制,适合mycat1.4之上的版本,心跳语句show status like “%esrep%”;


writeHost标签,readHost标签:这两个标签指定后端数据库的相关配置给mycat,用于实例化后端连接池。唯一不同的是,writeHost指定写实例、readHost指定读实例,组合这些读写实例来满足系统的要求。


host属性:用于标识不同的实例,对于writehost,一般使用M1;对于readhost一般使用S1.

url属性:后端实例连接地址,如果使用native的dbDriver,则一般为address:port这种形式,用JDBC或其他的dbDriver,则需要特殊指定。当使用JDBC时则可以这么写:jdbc:mysql://localhost:3306/。

user属性:后端存储实例的用户名。

password属性:后端存储实例的密码

测试


重启主服务器的mycat

// 重启mycat
cd /root/mycat/bin
./mycat restart
// 查看端口监听
netstat -ant|grep 8066

sqlyog连接mycat

-- 创建学生表
CREATE TABLE student(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(10)
);
-- 查询学生表
SELECT * FROM student;
-- 添加两条记录
INSERT INTO student VALUES (NULL,'张三'),(NULL,'李四');
-- 停止主从复制后,添加的数据只会保存到主服务器上。
INSERT INTO student VALUES (NULL,'王五');

sqlyog连接主服务器

-- 主服务器:查询学生表,可以看到数据
SELECT * FROM student;

sqlyog连接从服务器

-- 从服务器:查询学生表,可以看到数据(因为有主从复制)
SELECT * FROM student;
-- 从服务器:删除一条记录。(主服务器并没有删除,mycat中间件查询的结果是从服务器的数据)
DELETE FROM student WHERE id=2;

5 分库分表

分库分表的概念


将庞大的数据进行拆分

水平拆分:根据表的数据逻辑关系,将同一表中的数据按照某种条件,拆分到多台数据库服务器上,也叫做横向拆分。例如:一张1000万的大表,按照一模一样的结构,拆分成4个250万的小表,分别保存到4个数据库中。

垂直拆分:根据业务的维度,将不同的表切分到不同的数据库之上,也叫做纵向拆分。例如:所有的订单都保存到订单库中,所有的用户都保存到用户库中,同类型的表保存在同一库,不同的表分散在不同的库中。

Mycat水平拆分


修改主服务器的server.xml


0:本地文件方式


在mycat/conf/sequence_conf.properties文件中:

GLOBAL.MINDI=10000最小值

GLOBAL.MAXID=20000最大值,建议修改到9999999999


1:数据库方式


分库分表中保证全局主键自增唯一,但是需要执行mycat函数,配置sequence_db_conf.properties


2:时间戳方式


mycat实现的时间戳,建议varchar类型,要注意id的长度

<!-- 修改主键的方式 -->
<property name="sequnceHandlerType">0</property>

修改主服务器的sequence_conf.properties

#default global sequence
GLOBAL.HISIDS=      # 可以自定义关键字
GLOBAL.MINID=10001  # 最小值
GLOBAL.MAXID=20000  # 最大值
GLOBAL.CURID=10000

修改主服务器的schema.xml

table标签定义了逻辑表,所有需要拆分的表都需要在这个标签中定义。

rule属性:拆分规则。mod-long是拆分规则之一,主键根据服务器数量取模,在rule.xml中指定。如果是3个数据库,那么数据取模后,平均分配到三个库中。

name属性:定义逻辑表的表名,这个名字就如同在数据库中执行create table命令指定的名字一样,同一个schema标签中定义的表名必须是唯一的。

dataNode属性: 定义这个逻辑表所属的dataNode,该属性的值需要和dataNode标签中name属性的值相互对应。

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
  <schema name="HEIMADB" checkSQLschema="false" sqlMaxLimit="100">
    <table name="product" primaryKey="id" dataNode="dn1,dn2,dn3" rule="mod-long"/>
  </schema>
  <dataNode name="dn1" dataHost="localhost1" database="db1" />
  <dataNode name="dn2" dataHost="localhost1" database="db2" />
  <dataNode name="dn3" dataHost="localhost1" database="db3" />
  <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
        writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <!-- write -->
    <writeHost host="hostM1" url="localhost:3306" user="root"
           password="itheima">
    <!-- read -->
    <readHost host="hostS1" url="192.168.203.135:3306" user="root" password="itheima" />
    </writeHost>
  </dataHost>
</mycat:schema>

修改主服务器的rule.xml

<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
    <!-- 数据库的数量 -->
    <property name="count">3</property>
</function>

测试


mycat操作

-- 创建product表
CREATE TABLE product(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(20),
  price INT
);
-- 添加6条数据
INSERT INTO product(id,NAME,price) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'苹果手机',6999);
INSERT INTO product(id,NAME,price) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'华为手机',5999); 
INSERT INTO product(id,NAME,price) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'三星手机',4999); 
INSERT INTO product(id,NAME,price) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'小米手机',3999); 
INSERT INTO product(id,NAME,price) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'中兴手机',2999); 
INSERT INTO product(id,NAME,price) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'OOPO手机',1999); 
-- 查询product表
SELECT * FROM product; 

主服务器操作

-- 在不同数据库中查询product表
SELECT * FROM product;

从服务器操作

-- 在不同数据库中查询product表
SELECT * FROM product;

Mycat垂直拆分


修改主服务器的schema

<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
  <schema name="HEIMADB" checkSQLschema="false" sqlMaxLimit="100">
    <table name="product" primaryKey="id" dataNode="dn1,dn2,dn3" rule="mod-long"/>
    <!-- 动物类数据表 -->
    <table name="dog" primaryKey="id" autoIncrement="true" dataNode="dn4" />
    <table name="cat" primaryKey="id" autoIncrement="true" dataNode="dn4" />
       <!-- 水果类数据表 -->
    <table name="apple" primaryKey="id" autoIncrement="true" dataNode="dn5" />
    <table name="banana" primaryKey="id" autoIncrement="true" dataNode="dn5" />
  </schema>
  <dataNode name="dn1" dataHost="localhost1" database="db1" />
  <dataNode name="dn2" dataHost="localhost1" database="db2" />
  <dataNode name="dn3" dataHost="localhost1" database="db3" />
  <dataNode name="dn4" dataHost="localhost1" database="db4" />
  <dataNode name="dn5" dataHost="localhost1" database="db5" />
  <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
        writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
    <heartbeat>select user()</heartbeat>
    <!-- write -->
    <writeHost host="hostM1" url="localhost:3306" user="root"
           password="itheima">
    <!-- read -->
    <readHost host="hostS1" url="192.168.203.135:3306" user="root" password="itheima" />
    </writeHost>
  </dataHost>
</mycat:schema>

测试


-- 创建dog表
CREATE TABLE dog(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(10)
);
-- 添加数据
INSERT INTO dog(id,NAME) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'哈士奇');
-- 查询dog表
SELECT * FROM dog;
-- 创建cat表
CREATE TABLE cat(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(10)
);
-- 添加数据
INSERT INTO cat(id,NAME) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'波斯猫');
-- 查询cat表
SELECT * FROM cat;
-- 创建apple表
CREATE TABLE apple(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(10)
);
-- 添加数据
INSERT INTO apple(id,NAME) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'红富士');
-- 查询apple表
SELECT * FROM apple;
-- 创建banana表
CREATE TABLE banana(
  id INT PRIMARY KEY AUTO_INCREMENT,
  NAME VARCHAR(10)
);
-- 添加数据
INSERT INTO banana(id,NAME) VALUES (NEXT VALUE FOR MYCATSEQ_GLOBAL,'香蕉');
-- 查询banana表
SELECT * FROM banana;

sqlyog连接主服务器

-- 查询dog表
SELECT * FROM dog;
-- 查询cat表
SELECT * FROM cat;
-- 查询apple表
SELECT * FROM apple;
-- 查询banana表
SELECT * FROM banana;

sqlyog连接从服务器

-- 查询dog表
SELECT * FROM dog;
-- 查询cat表
SELECT * FROM cat;
-- 查询apple表
SELECT * FROM apple;
-- 查询banana表
SELECT * FROM banana;
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
目录
相关文章
|
SQL 关系型数据库 MySQL
如何实现 MySQL 的读写分离?
本文介绍了 MySQL 读写分离的实现方式及其主从复制原理,解释了如何通过主从架构提升读并发能力。重点分析了主从同步延时问题及解决方案,如半同步复制、并行复制等技术手段,并结合实际案例探讨了高并发场景下的优化策略。文章还提醒开发者在编写代码时需谨慎处理插入后立即查询的情况,避免因主从延时导致的数据不一致问题。
1579 44
如何实现 MySQL 的读写分离?
|
SQL 网络协议 关系型数据库
MySQL 主从复制
主从复制是 MySQL 实现数据冗余和高可用性的关键技术。主库通过 binlog 记录操作,从库异步获取并回放这些日志,确保数据一致性。搭建主从复制需满足:多个数据库实例、主库开启 binlog、不同 server_id、创建复制用户、从库恢复主库数据、配置复制信息并开启复制线程。通过 `change master to` 和 `start slave` 命令启动复制,使用 `show slave status` 检查同步状态。常见问题包括 IO 和 SQL 线程故障,可通过重置和重新配置解决。延时原因涉及主库写入延迟、DUMP 线程性能及从库 SQL 线程串行执行等,需优化配置或启用并行处理
500 40
|
关系型数据库 MySQL 数据库
RDS用多了,你还知道MySQL主从复制底层原理和实现方案吗?
随着数据量增长和业务扩展,单个数据库难以满足需求,需调整为集群模式以实现负载均衡和读写分离。MySQL主从复制是常见的高可用架构,通过binlog日志同步数据,确保主从数据一致性。本文详细介绍MySQL主从复制原理及配置步骤,包括一主二从集群的搭建过程,帮助读者实现稳定可靠的数据库高可用架构。
1167 9
RDS用多了,你还知道MySQL主从复制底层原理和实现方案吗?
|
SQL 存储 关系型数据库
MySQL主从复制 —— 作用、原理、数据一致性,异步复制、半同步复制、组复制
MySQL主从复制 作用、原理—主库线程、I/O线程、SQL线程;主从同步要求,主从延迟原因及解决方案;数据一致性,异步复制、半同步复制、组复制
2208 11
|
关系型数据库 MySQL 数据库
docker高级篇(大厂进阶):安装mysql主从复制
docker高级篇(大厂进阶):安装mysql主从复制
531 24
|
NoSQL 关系型数据库 Redis
《docker高级篇(大厂进阶):1.Docker复杂安装详说》包括:安装mysql主从复制、安装redis集群
《docker高级篇(大厂进阶):1.Docker复杂安装详说》包括:安装mysql主从复制、安装redis集群
585 14
|
SQL 关系型数据库 MySQL
Mysql中搭建主从复制原理和配置
主从复制在数据库管理中广泛应用,主要优点包括提高性能、实现高可用性、数据备份及灾难恢复。通过读写分离、从服务器接管、实时备份和地理分布等机制,有效增强系统的稳定性和数据安全性。主从复制涉及I/O线程和SQL线程,前者负责日志传输,后者负责日志应用,确保数据同步。配置过程中需开启二进制日志、设置唯一服务器ID,并创建复制用户,通过CHANGE MASTER TO命令配置从服务器连接主服务器,实现数据同步。实验部分展示了如何在两台CentOS 7服务器上配置MySQL 5.7主从复制,包括关闭防火墙、配置静态IP、设置域名解析、配置主从服务器、启动复制及验证同步效果。
704 0
Mysql中搭建主从复制原理和配置
|
缓存 关系型数据库 BI
使用MYSQL Report分析数据库性能(下)
使用MYSQL Report分析数据库性能
767 158
|
关系型数据库 MySQL 数据库
自建数据库如何迁移至RDS MySQL实例
数据库迁移是一项复杂且耗时的工程,需考虑数据安全、完整性及业务中断影响。使用阿里云数据传输服务DTS,可快速、平滑完成迁移任务,将应用停机时间降至分钟级。您还可通过全量备份自建数据库并恢复至RDS MySQL实例,实现间接迁移上云。
|
关系型数据库 MySQL 数据库
阿里云数据库RDS费用价格:MySQL、SQL Server、PostgreSQL和MariaDB引擎收费标准
阿里云RDS数据库支持MySQL、SQL Server、PostgreSQL、MariaDB,多种引擎优惠上线!MySQL倚天版88元/年,SQL Server 2核4G仅299元/年,PostgreSQL 227元/年起。高可用、可弹性伸缩,安全稳定。详情见官网活动页。
1991 152

推荐镜像

更多