day11-02-MyCAT分布式架构

数据库分布式架构方式

MyCAT官方网站:http://www.mycat.org.cn/

一、什么是MyCat

1.1

  MyCat是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户开源把它看作是一个数据库代理,用MySQL客户端工具和命令行访问,其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。

  MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储。而在最终用户看来,无论是哪种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。

1.2

  • 一个彻底开源的,面向企业应用开发的大数据库集群
  • 支持事务、ACID
  • 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
  • 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
  • 结合传统数据库和新型分布式数据仓库
  • 数据库中间件产品

1.3

  MyCat是一个开源的分布式数据库系统,但是由于真正的数据库需要存储引擎,而Mycat并没有存储引擎,所以并不是完全意义的分布式数据库系统。

  Mycat是一个数据库中间件,也可以理解为是数据库代理。在架构体系中是位于数据库和应用层之间的一个组件,并且对于应用层是透明的,即数据库感受不到mycat的存在,认为是直接连的mysql数据库(实际上是连接的mycat,mycat实现了mysql的原生协议)

  mycat的三大功能:分表、读写分离、主从切换

MyCAT 属于 中间件代理层

二、MyCat的关键特性

支持MySQL、Oracle、DB2、SQL Server、PostgreSQL等DB的常见SQL语法

支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster

基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群

支持前端作为MySQL通用代理,后端JDBC方式支持Oracle、DB2、SQL Server、mongodb

支持库内分表

官网特性:http://www.mycat.org.cn/

三、MyCat原理

MyCat就是一个数据库中间件,数据库的代理,它屏蔽了物理数据库,应用连接MyCat,然后MyCat再连接物理数据库。

通过中间代理层来统一管理所有的数据源,后端数据库集群对前端应用程序透明

优点:通用,对应用透明,改造少

缺点:实现难度大,有二次转发性能损失,单机损失30%左右

MyCat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。

![](D:\data\Sync-data\simon\学习笔记\Mysql 笔记\MySql-DBA\MySQL\day11-02-MyCAT分布式架构.assets\MyCAT原理.png)

1.application提交sql后,经过sql解析,优化,路由,解析为对应的sql指令,交给具体的sql机器执行

2.各节点的计算结果进行结果集合并

3.manager负责master的集群管理,内存管理等

四、MyCat的核心技术

数据库分片指:通过某种特定的条件,将我们存放在一个数据库中的数据分散存放在不同的多个数据库(主机)中,这样来达到分散单台设备的负载

MyCAT通过定义表的分片规则来实现分片,每个table可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法。

1.Schema:逻辑库,与MySQL中的Datebase(数据库)对应,一个逻辑库中定义了所包括的Table。

2.Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。

3.DataNode:MyCat的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上。

4.DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上。

5.分片规则:前面奖励数据切分,一个大表分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难

1、垂直拆分:(--单库性能瓶颈)

一个数据库由很多表的构成,每个表对应着不同的业务,垂直切分是指按照业务将表进行分类,分布到不同的数据库上面,这样也就将数据或者说压力分担到不同的库上面

	比如把业务上的3张表,分别拆分到不同的物理节点

  优点:拆分后业务清晰,拆分规则明确;

     			系统之间整合或扩展容易;

     数据维护简单

  缺点:部分业务表无法join,只能通过接口方式解决,提高了系统复杂度;

     受每种业务不同的限制存在单库性能瓶颈,不易数据扩展跟性能提高;

     事务处理复杂

2、水平拆分 :

	比如把一张热点表,按照策略,拆分到独立的几个节点里

	按照某个字段的某种规则来分散到多个库之中,每个表包含一部分数据。简单来说,可以将数据的水平切分理解为是按照数据行的切分,就是将表中的某些行切分到一个数据库,而另外的某些行又切分到其他的数据库中,主要有分表、分库两种模式

  优点:不存在单库大数据,高并发的性能瓶颈;

     对应用透明,应用端改造较少;

     按照合理拆分规则拆分;

     join操作基本避免跨库,提高了系统的稳定性跟负载能力

  缺点:拆分规则难以抽象;

     分片事务一致性难以解决;

     数据多次扩展难度跟维护量极大

     跨库join性能较差

	拆分策略

		range 范围拆分 ,比如取id列,按照id 1000-2000分一个,2000-4000分一个

		取模、枚举、hash、时间、等等

分表

  对于数据量很大的表(千万级以上),mysql性能会有很大下降,因此尽量控制在每张表的大小在百万级别。对于数据量很大的一张表,可以考虑将这些记录按照一定的规则放到不同的数据库里面。这样每个数据库的数据量不是太大,性能也不会有太大损失。

  mycat分表的实现:首先在mycat的scheme.xml中配置逻辑表,并且在配置中说明此表在哪几个物理库上。此逻辑表的名字与真实数据库中的名字一致!然后需要配置分片规则,即按照什么逻辑分库!

读写分离

  经过统计发现,对数据库的大量操作是读操作,一般占到所有操作70%以上。所以做读写分离还是很有必要的,如果不做读写分离,那么从库也是一种很大的浪费。

MyCat基本元素

1.逻辑库:MyCat中存在,对应用来说相当于mysql数据库,后端困难对应了多个物理数据库,逻辑库中不保存数据

2.逻辑表:逻辑库中的表,对应用来说相当于mysql的数据表,后端困难对应多个物流数据库中的表,也不保存数据

逻辑表分类

  1)分片表:进行了水平切分的表,具有相同表结构但存储在不同数据库中的表,所有分片表的集合才是一张完整的表

  分片表,是指那些有很大数据,需要切分到多个数据库的表,这样每个分片都有一部分数据,所有分片构成了完整的数据。

<table name="t_goods" primaryKey="vid" autolncrement="true" dataNode="dn1,dn2" rule="rule1" />
	2)非分片表:垂直切分的表,一个数据库中就保存了一张完整的表

   一个数据库中并不是所有的表都很大,某些表是可以不用进行切分的,非分片是相对分片表来说的,就是那些不需要进行数据切分的表。

<table name="t_node" primaryKey="vid" autolncrement="true" dataNode="dn1" />
	3)全局表:所有分片数据库中都存在的表,如字典表,数据量少,由MyCat来进行维护更新

  意义:例如国家列表,存量小(100w以下的数据表),需要经常和其他表进行join,所以可以用空间换取时间,防止跨库访问,则所有分片上面都放入全局表。

  一个真实的业务系统中,往往存在大量的类似字典表的表,这些表基本上很少变动。

  问题:业务表往往需要和字典表join查询,当业务表因为规模而进行分片以后,业务表与字典表之间的关联跨库了。

  解决:MyCat中通过表冗余来解决这类表的join,即它的定义中指定的dataNode上都有一份该表的拷贝(将字典表或者符合字典表特性的表定义为全局表)

<table name="t_area" primaryKey="id" type="global" dataNode="sh1,sh2"/>   
	4)ER分片关系表:MyCat独有,子表依赖父表,保证在同一个数据库中

  MyCat中的ER分片表是基于E-R关系的数据分片策略,子表的记录与所关联的父表记录存放在同一个数据分片上,保证数据join不会跨库操作。

  ER分片是解决跨分片数据join的一种很好的思路,也是数据切分规划的一条重要规则。

<table name="customer" primaryKey="ID" dataNode="dn1,dn2" rule="sharding-by-intfile">
    <childTable name="orders" primaryKey="ID" joinKey="customer_id" parentKey="id">
        <childTable name="order_items" joinKey="order_id" parentKey="id"/>
    </childTable>
</table>

E-R使用场景:

A表数据量大,访问也很频繁,而且还会有join B表 操作

B表也很大

table primaryKey # A表要分片的字段

childTable joinKey # A和B 表的关联字段

childTable parentKey # 父表的id列

E-R分片示例:

有两个表:
t1:
id	name
1	a
2	b
3	c
4	d

t2
id	age	t1_id
101	12	1
102	14	2
103	11	3
104	15	4

通过MyCAT E-R分片表进行分片后变成,比如分片规则是按t1表id列取模(mod-long)


dataNode sh1:
1	a	101	12	1
3	c	103	11	3

dataNode sh2:
2	b	102	14	2
4	d	104	15	4


  1. MyCAT基础架构准备
    1.1 环境准备:
    两台虚拟机 db01 db02
    每台创建四个mysql实例:3307 3308 3309 3310

1.2 删除历史环境:
pkill mysqld
\rm -rf /data/330*
\mv /etc/my.cnf /etc/my.cnf.bak

1.3 创建相关目录初始化数据
mkdir /data/33{07..10}/data -p
mysqld --initialize-insecure --user=mysql --datadir=/data/3307/data --basedir=/application/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3308/data --basedir=/application/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3309/data --basedir=/application/mysql
mysqld --initialize-insecure --user=mysql --datadir=/data/3310/data --basedir=/application/mysql

1.4 准备DB01配置文件和启动脚本
cat >/data/3307/my.cnf<<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/3307/data
socket=/data/3307/mysql.sock
port=3307
log-error=/data/3307/mysql.log
log_bin=/data/3307/mysql-bin
binlog_format=row
skip-name-resolve
server-id=7
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
EOF

cat >/data/3308/my.cnf<<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/3308/data
port=3308
socket=/data/3308/mysql.sock
log-error=/data/3308/mysql.log
log_bin=/data/3308/mysql-bin
binlog_format=row
skip-name-resolve
server-id=8
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
EOF

cat >/data/3309/my.cnf<<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/3309/data
socket=/data/3309/mysql.sock
port=3309
log-error=/data/3309/mysql.log
log_bin=/data/3309/mysql-bin
binlog_format=row
skip-name-resolve
server-id=9
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
EOF
cat >/data/3310/my.cnf<<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/3310/data
socket=/data/3310/mysql.sock
port=3310
log-error=/data/3310/mysql.log
log_bin=/data/3310/mysql-bin
binlog_format=row
skip-name-resolve
server-id=10
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
EOF

cat >/etc/systemd/system/mysqld3307.service<<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3307/my.cnf
LimitNOFILE = 5000
EOF

cat >/etc/systemd/system/mysqld3308.service<<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3308/my.cnf
LimitNOFILE = 5000
EOF

cat >/etc/systemd/system/mysqld3309.service<<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3309/my.cnf
LimitNOFILE = 5000
EOF
cat >/etc/systemd/system/mysqld3310.service<<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3310/my.cnf
LimitNOFILE = 5000
EOF

1.5 准备DB02配置文件和启动脚本

cat >/data/3307/my.cnf<<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/3307/data
socket=/data/3307/mysql.sock
port=3307
log-error=/data/3307/mysql.log
log_bin=/data/3307/mysql-bin
binlog_format=row
skip-name-resolve
server-id=17
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
EOF
cat >/data/3308/my.cnf<<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/3308/data
port=3308
socket=/data/3308/mysql.sock
log-error=/data/3308/mysql.log
log_bin=/data/3308/mysql-bin
binlog_format=row
skip-name-resolve
server-id=18
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
EOF
cat >/data/3309/my.cnf<<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/3309/data
socket=/data/3309/mysql.sock
port=3309
log-error=/data/3309/mysql.log
log_bin=/data/3309/mysql-bin
binlog_format=row
skip-name-resolve
server-id=19
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
EOF

cat >/data/3310/my.cnf<<EOF
[mysqld]
basedir=/application/mysql
datadir=/data/3310/data
socket=/data/3310/mysql.sock
port=3310
log-error=/data/3310/mysql.log
log_bin=/data/3310/mysql-bin
binlog_format=row
skip-name-resolve
server-id=20
gtid-mode=on
enforce-gtid-consistency=true
log-slave-updates=1
EOF

cat >/etc/systemd/system/mysqld3307.service<<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3307/my.cnf
LimitNOFILE = 5000
EOF

cat >/etc/systemd/system/mysqld3308.service<<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3308/my.cnf
LimitNOFILE = 5000
EOF

cat >/etc/systemd/system/mysqld3309.service<<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3309/my.cnf
LimitNOFILE = 5000
EOF
cat >/etc/systemd/system/mysqld3310.service<<EOF
[Unit]
Description=MySQL Server
Documentation=man:mysqld(8)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target
[Install]
WantedBy=multi-user.target
[Service]
User=mysql
Group=mysql
ExecStart=/application/mysql/bin/mysqld --defaults-file=/data/3310/my.cnf
LimitNOFILE = 5000
EOF

1.6 修改权限,启动多实例
chown -R mysql.mysql /data/*
systemctl start mysqld3307
systemctl start mysqld3308
systemctl start mysqld3309
systemctl start mysqld3310

mysql -S /data/3307/mysql.sock -e "show variables like 'server_id'"
mysql -S /data/3308/mysql.sock -e "show variables like 'server_id'"
mysql -S /data/3309/mysql.sock -e "show variables like 'server_id'"
mysql -S /data/3310/mysql.sock -e "show variables like 'server_id'"

1.7 节点主从规划
箭头指向谁是主库
10.0.50.61:3306 <-----> 10.0.50.63:3306
10.0.50.61:3307 ------> 10.0.50.61:3306
10.0.50.63:3307 ------> 10.0.50.63:3306

10.0.50.62:3306  <----->    10.0.50.64:3306
10.0.50.62:3307   ----->    10.0.50.62:3306
10.0.50.64:3307   ----->    10.0.50.64:3306

1.8 分片规划
shard1:
Master:10.0.50.61:3306
slave1:10.0.50.61:3307
Standby Master:10.0.50.63:3306
slave2:10.0.50.63:3307
shard2:
Master:10.0.50.62:3306
slave1:10.0.50.62:3307
Standby Master:10.0.50.64:3306
slave2:10.0.50.64:3307

1.9 开始配置

第一组四节点结构

10.0.50.61:3306 <-----> 10.0.50.63:3306

db03:

mysql -S /tmp/mysql.sock -e "grant replication slave on . to repl@'10.0.50.%' identified by 'repl';"
mysql -S /tmp/mysql.sock -e "grant all on . to root@'10.0.50.%' identified by '123' with grant option;"

db01:

mysql -S /tmp/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.63', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /tmp/mysql.sock -e "start slave;"
mysql -S /tmp/mysql.sock -e "show slave status\G"

db03:

mysql -S /tmp/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.61', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /tmp/mysql.sock -e "start slave;"
mysql -S /tmp/mysql.sock -e "show slave status\G"

=======================

10.0.50.61:3307 ------> 10.0.50.61:3306

db01:

mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.61', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /data/3307/mysql.sock -e "start slave;"
mysql -S /data/3307/mysql.sock -e "show slave status\G"

10.0.50.63:3307 ------> 10.0.50.63:3306

db03:

mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.63', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /data/3307/mysql.sock -e "start slave;"
mysql -S /data/3307/mysql.sock -e "show slave status\G"

第二组四节点

10.0.50.62:3306 <-----> 10.0.50.64:3306

db04:

mysql -S /tmp/mysql.sock -e "grant replication slave on . to repl@'10.0.50.%' identified by 'repl';"
mysql -S /tmp/mysql.sock -e "grant all on . to root@'10.0.50.%' identified by '123' with grant option;"

db02:

mysql -S /tmp/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.64', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /tmp/mysql.sock -e "start slave;"
mysql -S /tmp/mysql.sock -e "show slave status\G"

db04:

mysql -S /tmp/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.62', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /tmp/mysql.sock -e "start slave;"
mysql -S /tmp/mysql.sock -e "show slave status\G"

10.0.50.62:3307 -----> 10.0.50.62:3306

db02:

mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.62', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /data/3307/mysql.sock -e "start slave;"
mysql -S /data/3307/mysql.sock -e "show slave status\G"

10.0.50.64:3307 -----> 10.0.50.64:3306

db04:

mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.50.64', MASTER_PORT=3306, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='repl';"
mysql -S /data/3307/mysql.sock -e "start slave;"
mysql -S /data/3307/mysql.sock -e "show slave status\G"

1.10 检测主从状态
mysql -S /tmp/mysql.sock -e "show slave status\G"|grep Yes
mysql -S /data/3307/mysql.sock -e "show slave status\G"|grep Yes

==================================================================
注:如果中间出现错误,在每个节点进行执行以下命令,从第1.9步重新开始即可

mysql -S /tmp/mysql.sock -e "stop slave; reset slave all;"

mysql -S /data/3307/mysql.sock -e "stop slave; reset slave all;"

  1. MyCAT安装
    2.1 预先安装Java运行环境
    yum install -y java
    2.2下载
    Mycat-server-xxxxx.linux.tar.gz
    http://dl.mycat.io/
    2.3 解压文件
    [root@db01 application]# tar xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz
    2.4 软件目录结构
    ls
    bin catlet conf lib logs version.txt
    2.5 启动和连接
    配置环境变量
    vim /etc/profile
    export PATH=/application/mycat/bin:$PATH
    source /etc/profile
    启动
    mycat start
    连接mycat:
    mysql -uroot -p123456 -h 127.0.0.1 -P8066

  2. 数据库分布式架构方式
    3.1 垂直拆分
    3.2 水平拆分
    range
    取模
    枚举
    hash
    时间
    等等

  3. Mycat基础应用
    4.1 主要配置文件介绍
    rule.xml *****,分片策略定义
    schema.xml *****,主配置文件
    server.xml *** ,mycat服务有关
    log4j2.xml *** ,记录日志有关
    *.txt ,分片策略使用的规则

4.2 用户创建及数据库导入
db01:
mysql -S /data/3307/mysql.sock
grant all on . to root@'10.0.50.%' identified by '123';
source /root/world.sql

mysql -S /data/3308/mysql.sock
grant all on . to root@'10.0.50.%' identified by '123';
source /root/world.sql

4.3 配置文件结构介绍
cd /application/mycat/conf
mv schema.xml schema.xml.bak
vim schema.xml

<mycat:schema xmlns:mycat="http://io.mycat/">

mycat 逻辑库定义:

==================================================

数据节点定义:

<dataNode name="sh1" dataHost="oldguo1" database= "world" />   

==================================================

后端主机定义:

select user()


    </dataHost>  

===================================================

</mycat:schema>

4.4 mycat实现1主1从读写分离
vim schema.xml

<mycat:schema xmlns:mycat="http://io.mycat/">




select user()




</mycat:schema>

4.5 Mycat高可用+读写分离
mv schema.xml schema.xml.1
vim schema.xml

<mycat:schema xmlns:mycat="http://io.mycat/">




select user()







</mycat:schema>

说明:





第一个 whost: 10.0.50.51:3307 真正的写节点,负责写操作
第二个 whost: 10.0.50.52:3307 准备写节点,负责读,当 10.0.50.51:3307宕掉,会切换为真正的写节点

测试:
[root@db01 conf]# mysql -uroot -p123456 -h 10.0.50.51 -P 8066

读:
mysql> select @@server_id;
写:
mysql> begin ;select @@server_id; commit;

4.6 配置中的属性介绍:

balance属性
负载均衡类型,目前的取值有3种:

  1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
  2. balance="1",全部的readHost与standby writeHost参与select语句的负载均衡,简单的说,
    当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
  3. balance="2",所有读操作都随机的在writeHost、readhost上分发。

writeType属性
负载均衡类型,目前的取值有2种:

  1. writeType="0", 所有写操作发送到配置的第一个writeHost,
    第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为主,切换记录在配置文件中:dnindex.properties .
  2. writeType=“1”,所有写操作都随机的发送到配置的writeHost,但不推荐使用

switchType属性
-1 表示不自动切换
1 默认值,自动切换
2 基于MySQL主从同步的状态决定是否切换 ,心跳语句为 show slave status
datahost其他配置

maxCon="1000":最大的并发连接数
minCon="10" :mycat在启动之后,会在后端节点上自动开启的连接线程

tempReadHostAvailable="1"
这个一主一从时(1个writehost,1个readhost时),可以开启这个参数,如果2个writehost,2个readhost时
select user() 监测心跳

  1. Mycat高级应用-分布式解决方案
    5.1 垂直分表
    mv schema.xml schema.xml.ha
    vim schema.xml

<mycat:schema xmlns:mycat="http://io.mycat/">







select user()






<dataHost name="oldguo2" maxCon="1000" minCon="10" balance="1"  writeType="0" dbType="mysql"  dbDriver="native" switchType="1">
    <heartbeat>select user()</heartbeat>
<writeHost host="db1" url="10.0.50.51:3308" user="root" password="123">
        <readHost host="db2" url="10.0.50.51:3310" user="root" password="123" />
</writeHost>
<writeHost host="db3" url="10.0.50.52:3308" user="root" password="123">
        <readHost host="db4" url="10.0.50.52:3310" user="root" password="123" />
</writeHost>
</dataHost>	

</mycat:schema>

创建测试库和表:
[root@db01 conf]# mysql -S /data/3307/mysql.sock -e "create database taobao charset utf8;"
[root@db01 conf]# mysql -S /data/3308/mysql.sock -e "create database taobao charset utf8;"
[root@db01 conf]# mysql -S /data/3307/mysql.sock -e "use taobao;create table user(id int,name varchar(20))";
[root@db01 conf]# mysql -S /data/3308/mysql.sock -e "use taobao;create table order_t(id int,name varchar(20))"

重启mycat :
mycat restart

测试功能:
[root@db01 conf]# mysql -uroot -p123456 -h 10.0.50.51 -P 8066
mysql> use TESTDB
mysql> insert into user(id ,name ) values(1,'a'),(2,'b');
mysql> commit;

mysql> insert into order_t(id ,name ) values(1,'a'),(2,'b');
mysql> commit;

[root@db01 ~]# mysql -S /data/3307/mysql.sock -e "show tables from taobao;"
+------------------+
| Tables_in_taobao |
+------------------+
| user |
+------------------+
[root@db01 ~]# mysql -S /data/3308/mysql.sock -e "show tables from taobao;"
+------------------+
| Tables_in_taobao |
+------------------+
| order_t |
+------------------+
[root@db01 ~]#

5.2 Mycat分布式-水平拆分(分片)介绍
分片:对一个"bigtable",比如说t3表
(1)行数非常多,800w
(2)访问非常频繁

分片的目的:
(1)将大数据量进行分布存储
(2)提供均衡的访问路由

分片策略:
范围 range 800w 1-400w 400w01-800w
取模 mod 取余数
枚举
哈希 hash
时间 流水

优化关联查询
全局表
ER分片

5.3 Mycat分布式-范围分片
比如说t3表
(1)行数非常多,2000w(1-1000w:sh1 1000w01-2000w:sh2)
(2)访问非常频繁,用户访问较离散
cp schema.xml schema.xml.11
vim schema.xml




vim rule.xml


id
rang-long


autopartition-long.txt

===================================

vim autopartition-long.txt
1-10=0 -----> >=1 , <=10
10-20=1 -----> >10 ,<=20

创建测试表:
mysql -S /data/3307/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"

mysql -S /data/3308/mysql.sock -e "use taobao;create table t3 (id int not null primary key auto_increment,name varchar(20) not null);"

测试:
重启mycat
mycat restart

mysql -uroot -p123456 -h 127.0.0.1 -P 8066
insert into t3(id,name) values(1,'a');
insert into t3(id,name) values(2,'b');
insert into t3(id,name) values(3,'c');
insert into t3(id,name) values(10,'d');
insert into t3(id,name) values(11,'aa');
insert into t3(id,name) values(12,'bb');
insert into t3(id,name) values(13,'cc');
insert into t3(id,name) values(14,'dd');
insert into t3(id,name) values(20,'dd');

5.4 取模分片(mod-long):
取余分片方式:分片键(一个列)与节点数量进行取余,得到余数,将数据写入对应节点
vim schema.xml

vim rule.xml
2

准备测试环境
创建测试表:
mysql -S /data/3307/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"
mysql -S /data/3308/mysql.sock -e "use taobao;create table t4 (id int not null primary key auto_increment,name varchar(20) not null);"

重启mycat
mycat restart

测试:
mysql -uroot -p123456 -h10.0.50.51 -P8066

use TESTDB
insert into t4(id,name) values(1,'a');
insert into t4(id,name) values(2,'b');
insert into t4(id,name) values(3,'c');
insert into t4(id,name) values(4,'d');

分别登录后端节点查询数据
mysql -S /data/3307/mysql.sock -e "select * from taobao.t4;"
mysql -S /data/3308/mysql.sock -e "select * from taobao.t4;"

  1. 枚举分片
    t5 表
    id name telnum
    1 bj 1212
    2 sh 22222
    3 bj 3333
    4 sh 44444
    5 bj 5555

sharding-by-intfile

vim schema.xml

vim rule.xml

name
hash-int

partition-hash-int.txt 1 0

partition-hash-int.txt 配置:
bj=0
sh=1
DEFAULT_NODE=1

columns 标识将要分片的表字段,algorithm 分片函数, 其中分片函数配置中,mapFile标识配置文件名称

准备测试环境

mysql -S /data/3307/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"

mysql -S /data/3308/mysql.sock -e "use taobao;create table t5 (id int not null primary key auto_increment,name varchar(20) not null);"
重启mycat
mycat restart
mysql -uroot -p123456 -h10.0.50.51 -P8066
use TESTDB
insert into t5(id,name) values(1,'bj');
insert into t5(id,name) values(2,'sh');
insert into t5(id,name) values(3,'bj');
insert into t5(id,name) values(4,'sh');
insert into t5(id,name) values(5,'tj');
分别登录后端节点查询数据
mysql -S /data/3307/mysql.sock -e "select * from taobao.t5;"
mysql -S /data/3308/mysql.sock -e "select * from taobao.t5;"

======================================

DBLE自己研究

posted @   oldSimon  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 如何调用 DeepSeek 的自然语言处理 API 接口并集成到在线客服系统
· 【译】Visual Studio 中新的强大生产力特性
点击右上角即可分享
微信分享提示