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

news2024/12/25 0:37:58

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

一、读写分离

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>

致谢

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

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

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

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

相关文章

部署MySQL数据库时常见错误

登录数据库 时&#xff0c;可能会出现如图错误 1.确认是否部署MySQL服务 2.过滤MySQL端口号&#xff0c;查看服务是否开启&#xff08;如图上半部分&#xff0c;则是服务未开启&#xff09; 3.如图部分&#xff0c;则是密码错误 4.如果忘记了 mysql 的密码&#xff0c;或者登陆…

Apple Vision Pro 游戏开发:挑战与反思

随着Apple Vision Pro的推出,许多游戏开发者开始尝试在这个全新的平台上构建沉浸式的虚拟现实体验。然而,开发者们很快发现,在这个新兴领域中面临着不少挑战,包括支付延迟、技术支持不足、设备性能限制等问题。本文将探讨这些挑战,并提出一些开发者需要注意的关键点。 支…

Qt:自定义钟表组件

使用QWidget绘制两种钟表组件&#xff0c;效果如下&#xff1a; 源码下载链接&#xff1a;GitHub - DengYong1988/Clock-Widget: Qt 自定义钟表组件 https://download.csdn.net/download/ouyangxiaozi/89616407 主要代码如下&#xff1a; ClockWgt.h #ifndef CLOCKWGT_H #d…

spring源码阅读-推断构造方法

如何构造一个对象&#xff1f; 1、默认情况下&#xff0c;或者只有一个构造方法的情况下&#xff0c;就会使用默认构造方法或者唯一的一个构造方法 2、由程序员指定构造方法入参值&#xff0c;通过getBean()的方式获取&#xff0c;可以指定参数类型以及个数&#xff0c;但是该…

【康复学习--LeetCode每日一题】572. 另一棵树的子树

题目&#xff1a; 给你两棵二叉树 root 和 subRoot 。检验 root 中是否包含和 subRoot 具有相同结构和节点值的子树。如果存在&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 二叉树 tree 的一棵子树包括 tree 的某个节点和这个节点的所有后代节点。tree …

SpringBoot3里的文件上传

需求分析&#xff1a; 在用户更换头像或者添加文章时&#xff0c;都需要携带一个图片的URL访问地址。当用户访问文件上传接口将图片的数据上传成功后&#xff0c;服务器会返回一个地址。我们后台需要提供一个文件上传的接口&#xff0c;用来接收前端提交的文件的数据并且返回文…

C++入门基础(完整版)含下卷

C入门基础 hello 各位未来的程序员大佬们&#xff0c;这一篇是详细介绍入门基础&#xff0c;和上一篇不同的是这一篇补完了引用的知识和inline&#xff0c;nullptr的知识&#xff0c;希望大家有所收获 namespace的价值 在C/C中&#xff0c;变量、函数和后⾯要学到的类都是⼤…

【w门大学】云计算与大数据零基础特训班视频教程合辑

提取地址 云计算与大数据零基础特训班 课程目录

“数据要素×”大赛江西分赛官网正式上线 共设置12个赛道

7月17日&#xff0c;2024年“数据要素”大赛江西分赛在南昌市拉开帷幕。作为全国“数据要素”大赛的地方分赛&#xff0c;江西分赛由国家数据局、江西省人民政府指导&#xff0c;江西省发展改革委&#xff08;省数据局&#xff09;联合18家省级单位共同主办&#xff0c;江西分赛…

CCRC-DSA数据安全评估师:ISC.AI2024数字安全峰会:安全大模型引领安全行业革命

7月31日&#xff0c;以“构建先进的安全模型&#xff0c;引领安全产业变革”为主题&#xff0c;ISC.AI 2024数字安全峰会在北京国家会议中心成功举办。 本次峰会旨在鼓励行业通过大规模模型重构安全框架&#xff0c;确保数字经济的稳健前进。 会上&#xff0c;众多院士级专家…

【pytorch】全连接网络简单二次函数拟合

下面是一个使用PyTorch实现全连接网络来拟合简单二次函数 y x 2 y x^2 yx2 的示例。我们将创建一个简单的神经网络&#xff0c;定义损失函数和优化器&#xff0c;并进行训练。 下面是完整的代码示例&#xff1a; import torch import torch.nn as nn import torch.optim …

Linux笔记(1)

在敲出 文件 &#xff0f; 目录 &#xff0f; 命令 的前几个字母之后&#xff0c;按下 tab 键 如果输入的没有歧义&#xff0c;系统会自动补全 如果还存在其他 文件 &#xff0f; 目录 &#xff0f; 命令 &#xff0c;再按一下 tab 键&#xff0c;系统会提示可能存在的命令 小…

【算法速刷(5/100)】LeetCode —— 20.有效的括号

题目要求比较明晰简洁&#xff0c;编码难度并不算高 下面贴出代码和思路 bool isValid(string s) {stack<char> stk;for(const char& c : s){if(stk.empty()){stk.push(c);continue;}if(c ( || c [ || c {){stk.push(c);continue;}else{char top stk.top();boo…

Java Lambda表达式总结(快速上手图解)

Java Lambda表达式总结&#xff08;快速上手详解&#xff09;-CSDN博客https://blog.csdn.net/m0_66070037/article/details/140912566?spm1001.2014.3001.5501

idea 设置自动移除多余 的import (或整个项目删除)

1、开发的时候&#xff0c;直接自动去除多余的引入 2、如果想把整个项目的移除可以如下操作

Linux 异常 sh: /usr/bin/xauth: not found

异常原因&#xff1a; 远程连接时出现错误&#xff0c;由于 Omega 上没有 X 环境&#xff0c;因此在尝试交换凭据以设置转发时会失败 解决办法&#xff1a; 进入高级 SHH 设置&#xff0c;并勾选了 X11 转发。取消勾选该框。

Studying-代码随想录训练营day59| dijkstra(堆优化版)精讲、Bellman_ford 算法精讲

第59天&#xff0c;dijkstra算法的优化版本&#xff0c;以及Bellman_ford 算法&#x1f4aa;&#x1f4aa;(ง •_•)ง&#xff0c;编程语言&#xff1a;C 目录 dijkstra&#xff08;堆优化版&#xff09;精讲 思路 图的存储 邻接矩阵 邻接表 本题图的存储 堆优化细节…

x86 8086 CPU 寄存器详解

8086 寄存器及其地址详细介绍 8086 微处理器是 Intel 在 1978 年推出的一款 16 位微处理器&#xff0c;它在计算机体系结构的发展中占有重要地位。8086 处理器拥有 14 个 16 位寄存器&#xff0c;这些寄存器被分为几类&#xff1a;通用寄存器、段寄存器、指令指针寄存器和标志…

力扣第五十四题——螺旋矩阵

内容介绍 给你一个 m 行 n 列的矩阵 matrix &#xff0c;请按照 顺时针螺旋顺序 &#xff0c;返回矩阵中的所有元素。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]] 输出&#xff1a;[1,2,3,6,9,8,7,4,5]示例 2&#xff1a; 输入&#xff1a;matrix …

【好用的个人工具】部署Dokcer容器速查表工具

【好用的个人工具】部署Dokcer容器速查表工具 一、getting-started介绍1.1 getting-started简介1.2 getting-started内容 二、本地环境介绍2.1 本地环境规划2.2 本次实践介绍 三、本地环境检查3.1 检查Docker服务状态3.2 检查Docker版本3.3 检查docker compose 版本 四、下载ge…