| ```basic |
| 1、一个彻底开源的,面向企业应用开发的大数据库集群 |
| 2、支持事务、ACID、可以替代MySQL的加强版数据库 |
| 3、一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群 |
| 4、一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server |
| 5、结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品 |
| 6、一个新颖的数据库中间件产品 |
| ``` |
|
|
|
| ## Mycat原理 |
|
|
|
| |
| 然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。 |
| 如下图: |
| |
| 因此你可以用一台到N台服务器来分片,分片规则为(sharding rule)典型的字符串枚举分片规则,一个规则的定义是分片字段(sharding column)+分片函数(rule function), |
| |
| |
|
| 然后将SQL发往这些分片去执行,最后收集和处理所有分片返回的结果数据,并输出到客户端。以select * from Orders where prov=?语句为例,查到prov=wuhan,按照分片函数,wuhan返回dn1, |
| 于是SQL就发给了MySQL1,去取DB1上的查询结果,并返回给用户。 |
|
| 如果上述SQL改为select * from Orders where prov in (‘wuhan’,‘beijing’),那么,SQL就会发给MySQL1与MySQL2去执行,然后结果集合并后输出给用户。但通常业务中我们的SQL会有Order By |
| 以及Limit翻页语法,此时就涉及到结果集在Mycat端的二次处理,这部分的代码也比较复杂,而最复杂的则属两个表的Jion问题, |
|
| 为此,Mycat提出了创新性的ER分片、全局表、HBT(Human Brain Tech)人工智能的Catlet、以及结合Storm/Spark引擎等十八般武艺的解决办法,从而成为目前业界最强大的方案,这就是开源的力量! |
|
| 1.png |
|
| ## 为什么使用Mycat |
|
| 如今随着互联网的发展,数据的量级也是撑指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系性数据库已经无法满足快速查询与插入数据的需求; |
|
|
|
| 一些折衷是无法满足使用场景的,就比如有些使用场景是绝对要有事务与安全指标的。这个时候NoSQL肯定是无法满足的,所以还是需要使用关系性数据库。 |
|
| 如何使用关系型数据库解决海量存储的问题呢?此时就需要做数据库集群,为了提高查询性能将一个数据库的数据分散到不同的数据库中存储,为应对此问题就出现了——MyCat |
|
| 核心技术(分库分表) |
|
| 数据库分片指:通过某种特定的条件,将我们存放在一个数据库中的数据分散存放在不同的多个数据库(主机)中,这样来达到分散单台设备的负载,根据切片规则,可分为以下两种切片模式 |
| MyCAT通过定义表的分片规则来实现分片,每个表格可以捆绑一个分片规则,每个分片规则指定一个分片字段并绑定一个函数,来实现动态分片算法 |
|
| 1 . Schema:逻辑库,与MySQL中的Database(数据库)对应,一个逻辑库中定义了所包括的Table。 |
| 2 . Table:逻辑表,即物理数据库中存储的某一张表,与传统数据库不同,这里的表格需要声明其所存储的逻辑数据节点DataNode。在此可以指定表的分片规则。 |
| 3 . DataNode:MyCAT的逻辑数据节点,是存放table的具体物理节点,也称之为分片节点,通过DataSource来关联到后端某个具体数据库上 |
| 4.DataSource:定义某个物理库的访问地址,用于捆绑到Datanode上 |
| 5 . 分片规则:前面讲了数据切分,一个大表被分成若干个分片表,就需要一定的规则,这样按照某种业务规则把数据分到某个分片的规则就是分片规则,数据切分选择合适的分片规则非常重要,将极大的避免后续数据处理的难 |
|
| ## Mycat读写分离 |
|
| · 基础架构图 |
|
|
|
| 2.png |
|
| ### 环境准备 |
|
|
|
|
|
|
|
|
|
|
|
|
| ### 二进制安装mysql |
|
| 1.创建目录初始化数据 |
|
| ```bash |
| mkdir /data/33{07..10}/data -p |
| mysqld --initialize-insecure --user=mysql --datadir=/data/3307/data --basedir=/app/mysql |
| mysqld --initialize-insecure --user=mysql --datadir=/data/3308/data --basedir=/app/mysql |
| mysqld --initialize-insecure --user=mysql --datadir=/data/3309/data --basedir=/app/mysql |
| mysqld --initialize-insecure --user=mysql --datadir=/data/3310/data --basedir=/app/mysql |
| ``` |
|
|
| 2.准备配置文件和启动脚本 |
|
| ```bash |
|
db01====== |
| cat >/data/3307/my.cnf<<EOF |
| [mysqld] |
| basedir=/app/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=/app/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=/app/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=/app/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=/app/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=/app/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=/app/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=/app/mysql/bin/mysqld --defaults-file=/data/3310/my.cnf |
| LimitNOFILE = 5000 |
| EOF |
|
db02======= |
| cat >/data/3307/my.cnf<<EOF |
| [mysqld] |
| basedir=/app/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=/app/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=/app/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=/app/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=/app/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=/app/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=/app/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=/app/mysql/bin/mysqld --defaults-file=/data/3310/my.cnf |
| LimitNOFILE = 5000 |
| EOF |
| ``` |
|
|
| 3.修改权限启动多实例 |
|
| ```bash |
| 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'" |
| ``` |
|
|
| 4.主从配置 |
|
| ```bash |
| 箭头指向谁是主库 |
| 10.0.0.51:3307 <-----> 10.0.0.52:3307 |
| 10.0.0.51:3309 ------> 10.0.0.51:3307 |
| 10.0.0.52:3309 ------> 10.0.0.52:3307 |
|
| 10.0.0.52:3308 <-----> 10.0.0.51:3308 |
| 10.0.0.52:3310 -----> 10.0.0.52:3308 |
| 10.0.0.51:3310 -----> 10.0.0.51:3308 |
| ``` |
|
|
| 5.分片规划 |
|
| ```bash |
| shard1: |
| Master:10.0.0.51:3307 |
| slave1:10.0.0.51:3309 |
| Standby Master:10.0.0.52:3307 |
| slave2:10.0.0.52:3309 |
| shard2: |
| Master:10.0.0.52:3308 |
| slave1:10.0.0.52:3310 |
| Standby Master:10.0.0.51:3308 |
| slave2:10.0.0.51:3310 |
| ``` |
|
|
| 6.配置操作 |
|
| ```bash |
| # db02 |
| mysql -S /data/3307/mysql.sock -e "grant replication slave on . to repl@'10.0.0.%' identified by '123';" |
| mysql -S /data/3307/mysql.sock -e "grant all on . to root@'10.0.0.%' identified by '123' with grant option;" |
|
| # db01 |
| mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';" |
| mysql -S /data/3307/mysql.sock -e "start slave;" |
| mysql -S /data/3307/mysql.sock -e "show slave status\G" |
|
|
| # db02 |
| mysql -S /data/3307/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';" |
| mysql -S /data/3307/mysql.sock -e "start slave;" |
| mysql -S /data/3307/mysql.sock -e "show slave status\G" |
|
| # db01 |
| mysql -S /data/3309/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';" |
| mysql -S /data/3309/mysql.sock -e "start slave;" |
| mysql -S /data/3309/mysql.sock -e "show slave status\G" |
|
| # db02 |
| mysql -S /data/3309/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3307, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';" |
| mysql -S /data/3309/mysql.sock -e "start slave;" |
| mysql -S /data/3309/mysql.sock -e "show slave status\G" |
|
| # db01 |
| mysql -S /data/3308/mysql.sock -e "grant replication slave on . to repl@'10.0.0.%' identified by '123';" |
| mysql -S /data/3308/mysql.sock -e "grant all on . to root@'10.0.0.%' identified by '123' with grant option;" |
|
| # db02 |
| mysql -S /data/3308/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';" |
| mysql -S /data/3308/mysql.sock -e "start slave;" |
| mysql -S /data/3308/mysql.sock -e "show slave status\G" |
|
| # db01 |
| mysql -S /data/3308/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';" |
| mysql -S /data/3308/mysql.sock -e "start slave;" |
| mysql -S /data/3308/mysql.sock -e "show slave status\G" |
|
| # db02 |
| mysql -S /data/3310/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.52', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';" |
| mysql -S /data/3310/mysql.sock -e "start slave;" |
| mysql -S /data/3310/mysql.sock -e "show slave status\G" |
|
| # db01 |
| mysql -S /data/3310/mysql.sock -e "CHANGE MASTER TO MASTER_HOST='10.0.0.51', MASTER_PORT=3308, MASTER_AUTO_POSITION=1, MASTER_USER='repl', MASTER_PASSWORD='123';" |
| mysql -S /data/3310/mysql.sock -e "start slave;" |
| mysql -S /data/3310/mysql.sock -e "show slave status\G" |
|
| Copy |
| 7.主从状态检测 |
| mysql -S /data/3307/mysql.sock -e "show slave status\G" |
| mysql -S /data/3308/mysql.sock -e "show slave status\G" |
| mysql -S /data/3309/mysql.sock -e "show slave status\G" |
| mysql -S /data/3310/mysql.sock -e "show slave status\G" |
| 注:如果中间出现错误,在每个节点进行执行以下命令 |
| mysql -S /data/3307/mysql.sock -e "stop slave; reset slave all;" |
| mysql -S /data/3308/mysql.sock -e "stop slave; reset slave all;" |
| mysql -S /data/3309/mysql.sock -e "stop slave; reset slave all;" |
| mysql -S /data/3310/mysql.sock -e "stop slave; reset slave all;" |
| ``` |
|
|
| ## mysql分布式架构介绍 |
|
| 3.png |
| 分布式架构介绍 |
|
|
|
| ## mycat基础应用 |
|
| ```bash |
|
|
|
| range |
| 取模 |
| 枚举 |
| hash |
| 时间 |
| 等等 |
| ``` |
|
| ### 主要配置文件介绍 |
|
| ```basic |
| rule.xml |
| schema.xml *****,主配置文件 |
| server.xml |
| log4j2.xml *** ,记录日志有关 |
| *.txt |
| ``` |
|
|
| ## mycat安装 |
|
| ### 安装Mycat |
|
| ```basic |
| # 预先安装Java运行环境 |
| yum install -y java |
|
| # 下载 |
| Mycat-server-xxxxx.linux.tar.gz |
| http://dl.mycat.io/ |
|
| # 解压文件 |
| [root@db01 application]# tar xf Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz |
|
| # 软件目录结构 |
| ls |
| bin catlet conf lib logs version.txt |
|
| # 启动和连接 |
| 配置环境变量 |
| vim /etc/profile.d/mycat.sh |
| export PATH=/application/mycat/bin:$PATH |
| source /etc/profile |
| 启动 |
| mycat start |
| 连接mycat: |
| mysql -uroot -p123456 -h 127.0.0.1 -P8066 |
| ``` |
|
|
| ### 数据导入 |
|
| ```basic |
| # 这里仅作为参考,也可以用其他数据 |
| [root@db01 ~]# mysql -uroot -p123 |
| mysql> source /root/world.sql; |
| [root@db07 ~]# mysql -uroot -p123 |
| mysql> source /root/world.sql; |
| ``` |
|
| ### mycat配置文件浓缩 |
|
| ```basic |
| # mycat配置文件有很多多余的,可以进行浓缩 |
| cd /application/mycat/conf |
| mv schema.xml schema.xml.bak |
| vim schema.xml |
|
|
| <mycat:schema xmlns:mycat="http://io.mycat/"> |
|
|
|
|
| select user() |
|
|
|
|
| </mycat:schema> |
| ``` |
|
|
| ### 配置文件介绍 |
|
| ```xml |
| # 前期介绍: |
| 逻辑库schema: |
|
|
|
| 数据节点: |
|
|
| 数据主机: |
|
| select user() |
|
|
|
|
|
| TESTDB:逻辑库名 |
| 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() 监测心跳 |
| ``` |
|
| ## Mycat使用 |
|
| ### 读写分离配置 |
|
| ```xml |
| vim schema.xml |
|
|
|
| <mycat:schema xmlns:mycat="http://io.mycat/"> |
|
|
|
|
| select user() |
|
|
|
|
| </mycat:schema> |
|
| 重启mycat |
| mycat restart |
|
| 读写分离测试 |
| mysql -uroot -p -h 127.0.0.1 -P8066 |
| show variables like 'server_id'; |
| begin; |
| show variables like 'server_id'; |
|
| 总结: |
|
| ``` |
|
|
| ### 读写分离和高可用 |
|
| ```xml |
| [root@db01 conf]# mv schema.xml schema.xml.rw |
| [root@db01 conf]# vim schema.xml |
|
|
|
| <mycat:schema xmlns:mycat="http://io.mycat/"> |
|
|
|
|
| select user() |
|
|
|
|
|
|
|
| </mycat:schema> |
|
| 真正的 writehost:负责写操作的writehost |
| standby writeHost :和readhost一样,只提供读服务 |
|
| 当写节点宕机后,后面跟的readhost也不提供服务,这时候standby的writehost就提供写服务, |
| 后面跟的readhost提供读服务 |
|
| 测试: |
| mysql -uroot -p123456 -h 127.0.0.1 -P 8066 |
| show variables like 'server_id'; |
| 读写分离测试 |
| mysql -uroot -p -h 127.0.0.1 -P8066 |
| show variables like 'server_id'; |
| show variables like 'server_id'; |
| show variables like 'server_id'; |
| begin; |
| show variables like 'server_id'; |
| 对db01 3307节点进行关闭和启动,测试读写操作 |
| ``` |
|
|
| ### 垂直分表 |
|
| ```xml |
| mv schema.xml schema.xml.ha |
| vim schema.xml |
|
|
| <mycat:schema xmlns:mycat="http://io.mycat/"> |
|
|
|
|
|
| select user() |
|
|
|
|
|
|
|
|
| select user() |
|
|
|
|
|
|
|
| </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中对表中插入数据,看是否对插入不同表时,数据放入到不同服务器中 |
| ``` |
|
|
| ### 分片(水平拆分) |
|
| ```xml |
| 1.前期说明 |
| 分片:对一个"bigtable",比如说t3表 |
|
| (1)行数非常多,800w |
| (2)访问非常频繁 |
|
| 分片的目的: |
| (1)将大数据量进行分布存储 |
| (2)提供均衡的访问路由 |
|
| 分片策略: |
| 范围 range 800w 1-400w 400w01-800w |
| 取模 mod 取余数 |
| 枚举 |
| 哈希 hash |
| 时间 流水 |
|
| 优化关联查询 |
| 全局表 |
| ER分片 |
|
| Copy |
| 2.配置操作 |
| 比如说t3表 |
| (1)行数非常多,2000w(1-1000w:sh1 1000w01-2000w:sh2) |
| (2)访问非常频繁,用户访问较离散 |
| mv schema.xml schema.xml.1 |
| vim schema.xml |
|
|
|
|
|
| vim rule.xml |
|
|
| id |
| rang-long |
|
| <function name="rang-long" |
| class="io.mycat.route.function.AutoPartitionByLong"> |
| autopartition-long.txt |
|
| =================================== |
| vim autopartition-long.txt |
| 0-10=0 |
| 11-20=1 |
|
| 创建测试表: |
| 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(4,'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'); |
| ``` |
|
|
| ### 取模分片(mod-long) |
|
| ```xml |
| 取余分片方式:分片键(一个列)与节点数量进行取余,得到余数,将数据写入对应节点 |
| 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.0.52 -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 |
| use taobao |
| select * from t4; |
|
| mysql -S /data/3308/mysql.sock |
| use taobao |
| select * from t4; |
| ``` |
|
|
| ### 枚举分片 |
|
| ```xml |
| 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.0.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'); |
|
| ``` |
|
|
| ### Mycat全局表 |
|
| ```xml |
| a b c d |
| join |
| t |
|
| select t1.name ,t.x from t1 |
| join t |
| select t2.name ,t.x from t2 |
| join t |
| select t3.name ,t.x from t3 |
| join t |
|
| # 使用场景: |
| 如果你的业务中有些数据类似于数据字典,比如配置文件的配置, |
| 常用业务的配置或者数据量不大很少变动的表,这些表往往不是特别大, |
| 而且大部分的业务场景都会用到,那么这种表适合于Mycat全局表,无须对数据进行切分, |
| 要在所有的分片上保存一份数据即可,Mycat 在Join操作中,业务表与全局表进行Join聚合会优先选择相同分片内的全局表join, |
| 避免跨库Join,在进行数据插入操作时,mycat将把数据分发到全局表对应的所有分片执行,在进行数据读取时候将会随机获取一个节点读取数据。 |
|
| vim schema.xml |
|
| 后端数据准备 |
| mysql -S /data/3307/mysql.sock |
| use taobao |
| create table t_area (id int not null primary key auto_increment,name varchar(20) not null); |
|
| mysql -S /data/3308/mysql.sock |
| use taobao |
| create table t_area (id int not null primary key auto_increment,name varchar(20) not null); |
|
| 重启mycat |
| mycat restart |
|
| 测试: |
| mysql -uroot -p123456 -h10.0.0.52 -P8066 |
|
| use TESTDB |
| insert into t_area(id,name) values(1,'a'); |
| insert into t_area(id,name) values(2,'b'); |
| insert into t_area(id,name) values(3,'c'); |
| insert into t_area(id,name) values(4,'d'); |
| ``` |
|
|
| ### E-R分片 |
|
| ```xml |
| A |
| join |
| B |
| 为了防止跨分片join,可以使用E-R模式 |
| A join B |
| on a.xx=b.yy |
| join C |
| on A.id=C.id |
|
| ``` |
|
| 1 |
|
|
|
|
|
|