目录
1 集群
1.1 集群的概念
-
如今随着互联网的发展,数据的量级也是成指数的增长,从GB到TB到PB。对数据的各种操作也是愈加的困难,传统的关系型数据库已经无法满足快速查询与插入数据的需求。一台数据库服务器已经无法满足海量数据的存储需求,所以由多台数据库构成的数据库集群成了必然的方式。不过,为了保证数据的一致性,查询效率等,同时又要解决多台服务器间的通信、负载均衡等问题。
-
MyCat是一款数据库集群软件,是阿里曾经开源的知名产品——Cobar,简单的说,MyCAT就是:一个新颖的数据库中间件产品支持MysqL集群,提供高可用性数据分片集群。你可以像使用MysqL一样使用mycat。对于开发人员来说根本感觉不到mycat的存在。MyCat不单单是支持MysqL,像常用的关系型数据库Oracle、sqlServer都支持。
1.2 集群的原理
- 我们来说个例子,大海捞针和一个水瓶里捞针,毋庸置疑水瓶里一定能更快找到针,因为它需要检索的范围更小。数据库集群也是如此原理,我们可以将一个数据量为300G的数据库数据平均拆分成3部分,每个数据库中只存储100G数据,此时用户搜索,先经过我们中间代理层,中间代理层同时发出3个请求执行查询,比如第1台返回100条数据,耗时3秒,第2台返回200条数据,耗时3秒,第3台返回500条数据,耗时3秒,此时中间件只需要在800条记录中进行筛选,即可检索出用户要的结果,此时耗时其实一共只有3秒,因为每台机器做运算的时候,都是同时执行。如果我们此时直接在300G的数据库查询,耗时10秒,那使用中间件进行集群的效率就非常明显
2 Mycat环境搭建
2.1 Mycat下载和安装
- 官网:
http://www.mycat.io/
- 下载地址 :
http://dl.mycat.io/
- 选择1.6.7.1的版本,下载到D盘,安装包入下图:
sftp> put D:\Mycat-server-1.6.7.1-release-20190627191042-linux.tar.gz
- 解压:解压mycat.tar.gz并查看
tar -zxvf mycat.tar.gz
cd mycat
ll
- 授权:设置mycat权限
chmod -R 777 mycat
- 环境变量:配置环境变量
vi /etc/profile
// 添加
export MYCAT_HOME=/root/mycat
// 使环境变量生效
source /etc/profile
- 启动mycat
// 进入bin目录
[root@localhost]# cd /root/mycat/bin
// 执行启动命令
[root@localhost bin]# ./mycat start
-
查看:检测端口监听状况,Mycat的端口号是8066
[root@localhost bin]# netstat -ant|grep 8066
- 连接:使用sqlYog连接Mycat
- 连接后显示:
2.2 环境准备
- 配置模型
- 克隆虚拟机
- 重启网络
// 重启网络
service network restart
//查看ip地址
ip addr
//将两台服务器的防火墙关闭
systemctl stop firewalld
//启动两台服务器的MysqL
service MysqLd restart
//启动两台服务器的mycat
cd /root/mycat/bin
./mycat restart
//查看监听端口
netstat -ant|grep 3306
netstat -ant|grep 8066
//使用sqlyog测试连接
3 主从复制
-
主从复制的概念
// 编辑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 -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
service MysqLd restart
// 登录MysqL
MysqL -u root -p
- 查看主服务器的配置
// 查看主服务器配置
show master status;
-
从服务器的配置
// 编辑MysqL配置文件 vi /etc/my.cnf // 在[MysqLd]下面加上: server-id=2
// 登录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 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 service MysqLd restart // 重新登录MysqL MysqL -u root -p // 开启从节点 start slave; // 查询结果 show slave status\G; //Slave_IO_Running和Slave_sql_Running都为yes才表示同步成功。
-
测试
- 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 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标签: datanode标签定义了mycat中的数据节点,也就是数据分片。一个datanode标签就是一个独立的数据分片。
-
name属性:定义数据节点的名字,这个名字需要是唯一的,我们需要在table标签上应用这个名字,来建立表与分片对应的关系。
-
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指定读实例,组合这些读写实例来满足系统的要求。
-
-
测试
- 重启主服务器的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 分库分表
-
分库分表的概念
-
Mycat水平拆分
-
修改主服务器的server.xml
<!-- 修改主键的方式 --> <property name="sequnceHandlerType">0</property>
- 修改主服务器的sequence_conf.properties
#default global sequence GLOBAL.HISIDS= # 可以自定义关键字 GLOBAL.MINID=10001 # 最小值 GLOBAL.MAXID=20000 # 最大值 GLOBAL.CURID=10000
- 修改主服务器的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"> <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>
-
测试
- sqlyog连接mycat
-- 创建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;
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。