首页 > 数据库 >MySQL--读写分离与分布式存储

MySQL--读写分离与分布式存储

时间:2024-08-10 10:23:52浏览次数:15  
标签:xml -- 读写 MySQL mycat int mysql root id

前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除

一、读写分离

1、什么是读写分离

在数据库集群架构中,让主库负责处理写入操作,而从库只负责处理select查询,让两者分工明确达到提高数据库整体读写性能。当然,主数据库另外一个功能就是负责将数据变更同步到从库中, 也就是写操作。

2、读写分离的好处

  • 分摊服务器压力,提高机器的系统处理效率
  • 在写入不变,大大分摊了读取,提高了系统性能。另外,当读取被分摊后,又间接提高了写入的性能
  • 增加冗余,提高服务可用性,当一台数据服务器宕机后可以调整另一台从库以最快速度恢复服务

二、Mycat数据库中间件

1、了解Mycat

Mycat 是一个开源的数据库系统,但是由于真正的数据库需要存储引擎,而 Mycat 并没有存储引擎,所以并不是完全意义的数据库系统。 那么 Mycat 是什么?Mycat 是数据库中间件,就是介于数据库与应用之间,进行数据处理与交互的中间服务是实现对主从数据库的读写分离、读的负载均衡。

常见的数据库中间件有:

数据库中间件所属
MySQL ProxyMySQL官方
Atlas奇虎360
DBProxy美团点评
Amoeba早期阿里巴巴
cober阿里巴巴
Mycat阿里巴巴

2、Mycat的架构:

3、配置文件详解--schema.xml

逻辑库和分表设置

 <schema name="testdb"           # 逻辑库名称,与server.xml的一致
         checkSQLschema="false"  # 不检查sql
         sqlMaxLimit="100"       # 最大连接数
         dataNode="dn1">         # 数据节点名称
 <!--这里定义的是分表的信息-->
 </schema>

数据节点:

 <dataNode name="dn1" // 此数据节点的名称
         dataHost="localhost1" // 主机组虚拟的
         database="testdb" />  // 真实的数据库名称

主机组:

 <dataHost name="localhost1" // 主机组
         maxCon="1000" minCon="10" // 连接
         balance="0" // 负载均衡
         writeType="0" // 写模式配置
         dbType="mysql" dbDriver="native" // 数据库配置
         switchType="1" slaveThreshold="100">
 <!--这里可以配置关于这个主机组的成员信息,和针对这些主机的健康检查语句-->
 </dataHost>


 # balance 属性
 # 负载均衡类型,目前的取值有 3 种:
 1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。
 2. balance="1", 全部的 readHost 与 writeHost 参与 select 语句的负载均衡,简单的说,
 当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与
 select 语句的负载均衡。
 3. balance="2", 所有读操作都随机的在 writeHost、readhost 上分发。
 4. balance="3", 所有读请求随机的分发到 wiriterHost 对应的 readhost 执行,writerHost
 不负担读压力, #注意 balance=3 只在 1.4 及其以后版本有,1.3 没有。
 writeType 属性
 负载均衡类型
 1. writeType="0", 所有写操作发送到配置的第一个 writeHost,第一个挂了切换到还生存的第二
 个writeHost,重新启动后已切换后的为准.
 2. writeType="1",所有写操作都随机的发送到配置的 writeHost,#版本1.5 以后废弃不推荐。

健康检查

 <heartbeat>select user()</heartbeat>        # 对后端数据进行检测,执行一个sql语句,user()内部函数

读写配置

 <writeHost host="hostM1" url="192.168.246.135:3306" user="mycat"
 password="Qf@12345!">
 <!-- can have multi read hosts -->
 <readHost host="hostS2" url="192.168.246.136:3306" user="mycat"
 password="Qf@12345!" />
 </writeHost>

了解完个部分的作用以及名称后,下面实现一份完整的配置文件:

 [root@mycat ~]# cd /usr/local/mycat/conf/
 [root@mycat conf]# cp schema.xml schema.xml.bak
 [root@mycat conf]# vim schema.xml
 <?xml version="1.0"?>
 <!DOCTYPE mycat:schema SYSTEM "schema.dtd">
 <mycat:schema xmlns:mycat="http://io.mycat/">
     <schema name="testdb" checkSQLschema="false" sqlMaxLimit="100"
 dataNode="dn1">
     </schema>
     <dataNode name="dn1" dataHost="localhost1" database="testdb" />
     <dataHost name="localhost1" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
         <heartbeat>select user()</heartbeat>
         <!-- can have multi write hosts -->
         <writeHost host="mysql-master" url="mysql-master:3306" user="mycat" password="Qf@1234!">
         <!-- can have multi read hosts -->
         <readHost host="mysql-slave" url="mysql-slave:3306" user="mycat" password="Qf@1234!" />
         </writeHost>
     </dataHost>
 </mycat:schema>

三、实验:实现读写分离

3.1、设置server_id(主从库)

# 主库mysql135
[root@mysql135 ~]# vim /etc/my.cnf
serve_id=135
log_bin=135

# 从库mysql136
[root@mysql136 ~]# vim /etc/my.cnf
serve_id=136

# 从库mysql137
[root@mysql137 ~]# vim /etc/my.cnf
serve_id=137

[root@mysql ~]# systemctl restart mysqld

3.2、开启binlog日志,查看binlog日志信息-(主库)

[root@mysql135 ~]# mysql
mysql> show master status;
+------------+----------+--------------+------------------+-------------------+
| File       | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------+----------+--------------+------------------+-------------------+
| 135.000001 |      154 |              |                  |                   |
+------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

3.3、授权(主库)

# 允许用户名为"user1",来自10.0.0.*网段的用户使用密码"123"登录到MySQL服务器,并拥有读取二进制日志的权限
mysql> grant replication slave on *.* to "user1"@"10.0.0.%" identified by "123";
mysql> flush privileges;		# 刷新权限

3.4、在从库指定主库信息

mysql> change master to master_host="10.0.0.135",master_user="user1",master_password="123",master_log_file="135.000001" ,master_log_pos=154;

3.5、启动slave

mysql> start slave;

3.6、查看从库状态,验证

mysql> show slave status\G   查看从库状态
...
   Slave_IO_Running: Yes    io线程
   Slave_SQL_Running: Yes   sql 线程

3.7、编辑配置文件

在mycat服务器上编辑schema.xml文件

[root@mycat ~]# cd /usr/local/mycat
[root@mycat conf]# cp schema.xml schema.xml.bak
[root@mycat conf]# vim schema.xml
# 不写表的话,代表可以创建任意表
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://io.mycat/">
	<schema name="DXFL" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
        <table name="student" primaryKey="ID" type="global" dataNode="dn1" />	
	</schema>
    
	<dataNode name="dn1" dataHost="mysql135" database="db1" />
    
	<dataHost name="mysql135" maxCon="1000" minCon="10" balance="3" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100">
		<heartbeat>select user()</heartbeat>
		<!-- can have multi write hosts -->
		<writeHost host="mysql135" url="mysql135:3306" user="user1" password="123">
  		<!-- can have multi read hosts -->
		<readHost host="mysql136" url="mysql136:3306" user="user1" password="123" />
        <readHost host="mysql137" url="mysql137:3306" user="user1" password="123" />
		</writeHost>
	</dataHost>
    
</mycat:schema>

3.8、启动mycat

[root@mycat conf]# /usr/local/mycat/bin/mycat start
[root@mycat conf]# netstat -tunlp |grep 8066
tcp6       0      0 :::8066                 :::*                    LISTEN      52918/java 

3.9、验证读写分离

在真实的 master 数据库上给用户授权

mysql> create database db1; //创建一个测试库
mysql> use db1;
mysql> grant all on testdb.* to user1@'%' identified by '123'; /授权
mysql> flush privileges;

客户端上远程登录上配置有mycat的中间件的主机的mysql中:

[root@client ~]# mysql -h 10.0.0.138 -P8066 -uroot -p123456

# 发现数据库有我们自定义的DXFL
mysql> show databases;
+----------+
| DATABASE |
+----------+
| DXFL     |
+----------+
1 row in set (0.00 sec)
# 通样的,DXFL库中有我们自定义的逻辑表student,当然此表不可使用,需要我们按配置规则创建
mysql> use DXFL;
mysql> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| student       |
+---------------+
1 row in set (0.00 sec)
mysql> create table student (id int primary key,sharding_id int);
Query OK, 0 rows affected (0.02 sec)

# 实验:往创建好的student表中插入数据;
mysql> insert into student (id,sharding_id) values(1,99),(2,67),(3,45);
Query OK, 3 rows affected (0.00 sec)
Records: 3  Duplicates: 0  Warnings: 0

接下来,在三台mysql服务器上验证

# mysql135
mysql> use db1;
mysql> select * from student;
+----+-------------+
| id | sharding_id |
+----+-------------+
|  1 |          99 |
|  4 |          67 |
|  5 |          45 |
+----+-------------+
# 因为三个库是主-从-从架构,因此mysql136与mysql137也是通用的表与结构

至此,本实验成功实现读写分离;

四、实验:实现分布式存储

1、环境准备

IP地址充当角色用处
10.0.0.135mysql135mysql数据库
10.0.0.136mysql136mysql数据库
10.0.0.137mysql137mysql数据库
10.0.0.138mycat
10.0.0.139client

2、实现步骤

(1)改主机名、关闭防火墙、关闭selinux(每台主机执行)、写hosts文件

[root@135 ~]# hostnamectl set-hostname mysql135
[root@135 ~]# systemctl stop firewalld
[root@135 ~]# systemctl enable firewalld
[root@135 ~]# setenforce 0		# 临时关闭selinux
# 只在mycat服务器上编写hosts文件
[root@mycat ~]# vim /etc/hosts
192.168.1.135 mysql135
192.168.1.136 mysql136
192.168.1.137 mysql137

(2)135、136、137安装MySQL服务并授权

# 安装完成后建库
135: 
mysql> create database db1
136:
mysql> create database db2
137: 
mysql> create database db3

# 授权
mysql> grant all on *.* to "mycat"@"10.0.0.%" identified by "123";

(3)mycat安装jdk和mycat

# 配置阿里yum
[root@mycat ~]# wget -O /etc/yum.repos.d/CentOS-Base.repo https://mirrors.aliyun.com/repo/Centos-vault-8.5.2111.repo

[root@mycat ~]# yum -y install java-1.8.0-openjdk
# 上传mycat安装包与解压
[root@mycat ~]# rz
[root@mycat ~]# tar xf xxx -C /usr/local/
[root@mycat ~]# cd /usr/local/mycat

(4)配置mycat

server.xml:主配置文件,定义连接mycat的用户信息和逻辑库,无需修改

schema.xml:定义库和表以及读写数据库的信息

[root@mycat conf]# vim schema.xml

rule.xml:分片规则

partiton-hash-int.txt:hash-int的规则,添加一行

[root@mycat conf]# vim partition-hash-int.txt 
10000=0
10010=1
10020=2

(5)启动mycat

[root@mycat conf]# /usr/local/mycat/bin/mycat start
Starting Mycat-server...
Mycat-server is already running.
[root@mycat conf]# netstat -tunlp |grep 8066
tcp6       0      0 :::8066                 :::*                    LISTEN      52918/java 

(6)验证

[root@client ~]# mysql -h 10.0.0.138 -P8066 -uroot -p123456

mysql> create database TESTDB;
mysql> use TESTDB;
mysql> create table employee(id int primary key,sharding_id int,name char(25));
mysql> insert into employee (id,sharding_id,name) values(1,10000,'zhangsan'),(2,10010,'lisi'),(3,10020,'wangwu');

# 然后分别在135/136/137中查看表
# 135:
mysql> use db1;
mysql> select * from emploee;
+----+-------------+----------+
| id | sharding_id | name     |
+----+-------------+----------+
|  1 |       10000 | zhangsan |
+----+-------------+----------+

# 136:
mysql> use db2;
mysql> select * from emploee;
+----+-------------+----------+
| id | sharding_id | name     |
+----+-------------+----------+
|  2 |       10010 |     lisi |
+----+-------------+----------+

# 137:
mysql> use db3;
mysql> select * from emploee;
+----+-------------+----------+
| id | sharding_id | name     |
+----+-------------+----------+
|  3 |       10020 |   wangwu |
+----+-------------+----------+

3、自定义库和表

(7)目前只有TESTDB库,我们可以自定义库和表,下面新建一个YJS库

# 1、修改server.xml的逻辑库
[root@mycat conf]# vim server.xml
...
<user name="root">
	<property name="password">123456</property>
	<property name="schames">TESTDB,YJS</property>
</user>
<user name="user">
	<property name="password">user</property>
	<property name="schames">TESTDB,YJS</property>
	<property name="readOnly">True</property>
</user>
...

# 2、在shecma.xml文件中添加一对schema标签
[root@mycat conf]# vim schema.xml
  <schema name="YJS" checkSQLschema="false" sqlMaxLimit="100">
            <table name="mysql" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" />
            <table name="docker" primaryKey="ID"  dataNode="dn1,dn2,dn3" rule="mod-long" />
    </schema>
# 因为mysql表的类型为global,因此每个节点都会存储数据
mysql> use YJS;
mysql> create table mysql (id int primary key,sharding_id int,name char(255));
mysql> insert into mysql (id,sharding_id,name) values(1,10000,'10'),(2,10010,'20'),

# 而docker表类型为mod-long,因此会计算取模值而存储到结果节点之中
mysql> create table docker (id int primary key,sharding_id int,score int);
mysql> select * from docker;
mysql> insert into docker (id,sharding_id,score) values(1,4,100),(2,5,99),(3,6,88);

4、分片规则

rule.xml 里面定义了我们对表进行拆分所涉及到的规则定义。我们可以灵活的对表使用不同的分片算法,或者对表使用相同的算法但具体的参数不同。这个文件里面主要有 tableRule 和 function 这两个标签。

4.1、rule.xml

(1)<tableRule>标签

<tableRule name="rule1">
    <rule>
        <columns>id</columns>
        <algorithm>func1</algorithm>
    </rule>
</tableRule>
  • name:属性指定唯一的名字,标识不同的表规则。内嵌的rule标签则指定对物理表中的哪一列进行拆分和使用什么路由算法
  • columns:内指定要拆分的列名字
  • argorihm:使用function标签中的name属性。连接表规则和具体路由算法。

(2)<function>标签

<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
    <property name="mapFile">partition-hash-int.txt</property>
</function>
  • name:指定算法的名字
  • class:指定路由算法具体的类名字
  • property:为算法需要用到的一些属性

4.2、常用的分片规则

(1)分片枚举---sharding-by-intfile

通过在配置文件中配置可能的枚举 id自己配置分片

rule.xml配置如下:

<tableRule name="sharding-by-intfile">
    <rule>
        <columns>region_id</columns>
        <algorithm>hash-int</algorithm>
    </rule>
</tableRule>

<function name="hash-int" class="io.mycat.route.function.PartitionByFileMap">
    <property name="mapFile">partition-hash-int.txt</property>
    <property name="type">1</property>
    <property name="defaultNode">0</property>
</function> 

partition-hash-int.txt 配置:

# 这里的0,1,2等是data node index
850=0
851=1
852=2
853=3
DEFAULT_NODE=0

(2)取模---mod-long

为对分片字段求模运算

<tableRule name="mod-long">
    <rule>
        <columns>user_id</columns>
        <algorithm>mod-long</algorithm>
    </rule>
</tableRule>
<function name="mod-long" class="io.mycat.route.function.PartitionByMod">
    <!-- how many data nodes -->
    <property name="count">3</property>
</function>

致谢

在此,我要对所有为知识共享做出贡献的个人和机构表示最深切的感谢。同时也感谢每一位花时间阅读这篇文章的读者,如果文章中有任何错误,欢迎留言指正。 

学习永无止境,让我们共同进步!!

标签:xml,--,读写,MySQL,mycat,int,mysql,root,id
From: https://blog.csdn.net/lerp020321/article/details/140930614

相关文章

  • Linux Shell编程--正则表达式、grep、sed、awk
    前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除!一、正则表达式1、正则表达式定义1.1、简介正则表达式是一种强大的文本模式匹配工具,用于搜索、替换或分割字符串。在Shell脚本中,正则表达式通常与grep、sed和awk等工具一起使用。1.2、层次分类基......
  • Docker快速入门指南
    ......
  • MySQL--主从复制
    前言:本博客仅作记录学习使用,部分图片出自网络,如有侵犯您的权益,请联系删除一、什么是主从复制1、定义主从复制,是用来建立一个和主数据库完全一样的数据库环境,称为从数据库;主数据库一般是准实时的业务数据库。2、作用做数据的热备,作为后备数据库,主数据库服务器故障后,可切......
  • 触想工控设备在工业“无人化”场景的应用
    今年七月,比酷暑更加火爆的,当属频登热搜的武汉无人驾驶出租车“萝卜快跑”——L4级自动驾驶、360°三维感知、AI大模型算法……高端科技与“低价揽客”的反差感使得“萝卜快跑”迅速走红。△图源|萝卜快跑官网平台“萝卜快跑”的神秘面纱“萝卜快跑”无人驾......
  • Cisco ASAv 9.20.3 - 思科自适应安全虚拟设备 (ASAv)
    CiscoASAv9.20.3-思科自适应安全虚拟设备(ASAv)CiscoAdaptiveSecurityVirtualAppliance(ASAv)请访问原文链接:https://sysin.org/blog/cisco-asav/,查看最新版。原创作品,转载请保留出处。思科自适应安全虚拟设备(ASAv):跨物理和虚拟环境扩展安全性思科自适应安全虚......
  • 08-09 题解
    08-09题解A小水题思路假设我们选定了当前子序列的绝对众数\(x\),那么该序列里最多再放\(num_x-1\)个其他数字为了分出最少的子序列,肯定要让每个子序列在拥有绝对众数的同时能消化尽量多的其他数字由此,可以得到一个贪心策略:每次取出出现次数最多的一个数字,消掉出现......
  • ABC 365
    赛时通过:A、B、C。赛后补题:D、E。A依题判断即可。#include<bits/stdc++.h>usingnamespacestd;inty;intmain(){ cin>>y; if(y%4!=0)cout<<365; if(y%4==0&&y%100!=0)cout<<366; if(y%100==0&&y%400!=0)cout<<365; if(y%400==0)......
  • 前端黑科技:使用 JavaScript 实现网页扫码功能
    在数字化时代,二维码已经渗透到我们生活的方方面面。从移动支付到产品溯源,二维码凭借其便捷性和高效性,成为了信息传递的重要载体。而随着前端技术的不断发展,我们甚至可以使用JavaScript在网页端实现二维码扫描功能,为用户提供更加便捷的操作体验。本文将带您深入了解如何使用Jav......
  • CryptoHouse:由 ClickHouse 和 Goldsky 支持的免费区块链分析服务(ClickHouse 博客)
    我们很高兴地宣布CryptoHouse,在crypto.clickhouse.com上可访问,这是一个由ClickHouse提供支持的免费区块链分析服务。https://crypto.clickhouse.com/现有的公共区块链分析服务通常需要定时、异步查询,而ClickHouse提供实时分析,通过即时查询响应来普及访问权限。用户可以......
  • proteus 中单片机串口仿真实验
    位置:                    连线如图:问题解决在进行仿真的时候,可能不会出现terminal显示框,可以在菜单栏debug->virtualterminal来让它显示:如果visualterminal显示的是乱码,我们就需要根据实际情况修改单片机时钟频率,双击单片机,在......