Mycat相关知识点梳理

一、Mycat入门

Mycat是一个数据库分库分表中间件,是目前国内最活跃、性能最好的开源数据库中间件。Mycat是彻底开源的,它面向企业应用开发的大数据库集群。它支持事务ACID特性,对于开发者来说,它是一个可以代替MySQL的加强版数据库。Mycat是结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品,同时Mycat还支持NoSQL、HDFS等数据库。
Mycat的应用场景如下:
在这里插入图片描述
假设我们现在有一个订单表order,需要将此表按照省份分库分表,那么使用Mycat来做的一个流程应该是这样的:
(1)将订单表order数据按省份分片;
(2)应用程序连接上Mycat,提交SQL;
(3)Mycat“拦截”,它拦截了用户发送的SQL语句;首先,Mycat解析SQL语句,做一些特定分析,如分片分析、路由分析、读写分离分析、缓存分析等等;然后,将此SQL往后端真实的MySQL数据库发送,并将返回的结果做适当的处理,如结果合并、聚合处理、排序处理、分页处理等等;最终,将结果返回给用户。
Mycat的工作原理示意图如下所示:
在这里插入图片描述
Mycat的架构图如下所示:
在这里插入图片描述
Mycat有如下一些关键的特性:
在这里插入图片描述

在这里插入图片描述
Mycat的未来长期规划如下:
在这里插入图片描述

二、Mycat参数说明及读写分离配置

首先我们需要明确一点:Mycat对应应用程序来说,就是一个数据库,开发者直接连接Mycat并当做MySQL使用即可;而Mycat对于后端真实的MySQL数据库集群来说,是一个代理服务器。
对于Mycat的核心概念,有如下的图示:
在这里插入图片描述
如上图所示,各部分解释分别为:(【注意】其中1-4是逻辑概念,5-6是物理概念)
(1)逻辑库:Mycat中数据库服务的定义、管理的数据库;(<schema>标签表示)
(2)逻辑表:逻辑库中包含的需要分库分表存储的表;(<table>标签表示,在<schema>标签中)
(3)dataNode:数据节点(分片节点),逻辑表分片的存放节点,如一张大数据量的表拆分为几个分片存储,每个分片就是一个dataNode;(<dataNode>标签表示,可在<table>标签中配置)
(4)dataHost:数据主机(节点主机),即数据节点dataNode所在的主机;(<dataHost>标签表示)
(5)writeHost:写主机,包含真实数据库的地址、用户名、密码等配置;(<writeHost>标签表示,在<dataHost>标签中)
(6)readHost:读主机,包含真实数据库的地址、用户名、密码等配置。(<readHost>标签表示,在<dataHost>标签中)
以上的配置都写在schema.xml配置文件中,例子如下:
在这里插入图片描述
以下是各配置参数值说明:
(1)逻辑库:
1>schema配置:
在这里插入图片描述
2>schema配置-table元素属性说明:
在这里插入图片描述
在这里插入图片描述
3>childTable标签属性说明(在table标签中,相当于某个表的子表,通过标签上的属性与父表关联,这样做可以避免跨库join):
在这里插入图片描述
(2)dataHost:
1>dataHost配置:
在这里插入图片描述
在这里插入图片描述
2>heartbeat配置:
用于和后端数据库进行心跳检查的语句。
3>writeHost和readHost配置:
在这里插入图片描述
【注意】一个dataHost中可以定义多个writeHost和readHost,但是如果writeHost指定的后端数据库宕机,则此writeHost绑定的所有的readHost都不可用。另一方面,由于此writeHost宕机,Mycat会自动检测,并切换到备用的writeHost上去(可以配多个writeHost,但是默认只选第一个,只有第一个writeHost宕机才会选第二个,以此类推;同时多个writeHost上的数据需要主从复制,否则宕机了数据会不一致)。
对于Mycat读写分离的测试,可以看我在最后一节的配置。需要说明的是,读写分离的配置方式有两种(我测试里用的是第一种),分别是:
(1)配置writeHost和readHost:此种方式如果writeHost宕机,那么readHost也不能提供读服务;
(2)配置多个writeHost,并且把<dataHost>标签的balance属性设置为1:因为balance属性设置为1表示全部的readHost和“Stand By”的writeHost都参与读操作的负载均衡;所以此时配置的第一个writeHost变成了“写库”,而“Stand By”的writeHost变成了“读库”;这样做的好处是,即使第一个writeHost宕机,也不会影响Mycat提供读服务,而且还会自动切换到第二个writeHost作为“写库”。

三、Mycat数据拆分原则及分库分表配置

Mycat中表的分类如下:
(1)分片表:指那些有很大数据量,需要拆分到多个数据库的表(分库分表),这样每个分片都有一部分数据,所有分片构成了完整的数据;例子如下:
在这里插入图片描述
(2)非分片表:指数据量不是很大,不需要拆分的表;例子如下:
在这里插入图片描述
(3)ER表:数据量很大的表需要拆分,但是这个表又有父子关系,为了避免跨库join,所以有父子关系的表可以放到一个数据库上去;例子如下:
在这里插入图片描述
(4)全局表:一个真实的业务系统中,存在大量类似字典的表,且这些表基本很少变动;为了跨库join,会在定义这个表的每个dataNode上都冗余一张该表的拷贝。例子如下:
在这里插入图片描述
对于分库分表,我们需要指定规则,Mycat分库分表规则配置在conf/rule.xml文件中,例子如下:
在这里插入图片描述
对于分库分表有如下一些原则:
(1)能不分就不分,1000 万以内的表,不建议分片,通过合适的索引,读写分离等方式,可以很好的解决性能问题;
(2)分片数量尽量少,分片尽量均匀分布在多个DataHost 上,因为一个查询SQL 跨分片越多,则总体性能越差,虽然要好于所有数据在一个分片的结果,只在必要的时候进行扩容,增加分片数量;
(3)分片规则需要慎重选择,分片规则的选择,需要考虑数据的增长模式,数据的访问模式,分片关联性问题,以及分片扩容问题,最常用的分片策略为范围分片,枚举分片,一致性Hash 分片,这几种分片都有利于扩容;
(4)尽量不要在一个事务中的SQL 跨越多个分片,分布式事务一直是个不好处理的问题;
(5)查询条件尽量优化,尽量避免Select * 的方式,大量数据结果集下,会消耗大量带宽和CPU 资源,查询尽量避免返回大量结果集,并且尽量为频繁使用的查询语句建立索引。
对于数据拆分有如下一些原则:
(1)达到一定数量级才拆分(800 万);
(2)不到800 万但跟大表(超800 万的表)有关联查询的表也要拆分,在此称为大表关联表;
(3)大表关联表如何拆:小于100 万的使用全局表;大于100 万小于800 万跟大表使用同样的拆分策略;无法跟大表使用相同规则的,可以考虑从java 代码上分步骤查询,不用关联查询,或者破例使用全局表;
(4)破例的全局表:如item_sku 表250 万,跟大表关联了,又无法跟大表使用相同拆分策略,也做成了全局表。破例的全局表必须满足的条件:没有太激烈的并发update,如多线程同时update 同一条id=1 的记录。虽有多线程update,但不是操作同一行记录的不在此列。多线程update 全局表的同一行记录会死锁。批量insert没问题;
(5)拆分字段是不可修改的;
(6)拆分字段只能是一个字段,如果想按照两个字段拆分,必须新建一个冗余字段,冗余字段的值使用两个字段的值拼接而成(如大区+年月拼成zone_yyyymm 字段)
(7)拆分算法的选择和合理性评判:按照选定的算法拆分后每个库中单表不得超过800 万;
(8)能不拆的就尽量不拆。如果某个表不跟其他表关联查询,数据量又少,直接不拆分,使用单库即可。
对于dataNode分布问题:
DataNode 代表MySQL 数据库上的一个Database,因此一个分片表的DataNode 的分布可能有以下几种:
(1)都在一个DataHost 上;
(2)在几个DataHost 上,但有连续性,比如dn1 到dn5 在Server1 上,dn6 到dn10 在Server2 上,依次类推;
(3)在几个DataHost 上,但均匀分布,比如dn1,dn2,d3 分别在Server1,Server2,Server3 上,dn4 到dn5 又重复如此。
一般情况下,不建议第一种,二对于范围分片来说,在大多数情况下,最后一种情况最理想,因为当一个表的数据均匀分布在几个物理机上的时候,跨分片查询或者随机查询,都是到不同的机器上去执行,并行度最高,IO 竞争也最小,因此性能最好。当我们有几十个表都分片的情况下,怎样设计DataNode 的分布问题,就成了一个难题,解决此难题的最好方式是试运行一段时间,统计观察每个DataNode上的SQL 执行情况,看是否有严重不均匀的现象产生,然后根据统计结果,重新映射DataNode 到DataHost 的关系。
对于Mycat内置的常用分片规则:
(1)分片枚举(列表分片):通过在配置文件中配置可能的枚举id,自己配置分片,本规则适用于特定的场景,比如有些业务需要按照省份或区县来做保存,而全国省份区县固定的,这类业务使用本条规则;
(2)范围分片:此分片适用于,提前规划好分片字段某个范围属于哪个分片;
(3)按日期范围分片:此规则为按日期段进行分片;
(4)自然月分片:按月份列分区,每个自然月一个分片;
(5)取模:此规则为对分片字段进行十进制运算,来分片数据;
(6)取模范围分片:此种规则是取模运算与范围约束的结合,主要为了后续数据迁移做准备,即可以自主决定取模后数据的节点分布;
(7)二进制取模范围分片:本条规则类似于十进制的求模范围分片,区别在于是二进制的操作,是分片列值的二进制低10位&1111111111。 此算法的优点在于如果按照10 进制取模运算,在连续插入1-10 时候1-10会被分到1-10 个分片,增大了插入的事务控制难度,而此算法根据二进制则可能会分到连续的分片,减少插入事务控制难度;
(8)范围取模分片:先进行范围分片计算出分片组,组内再求模;优点可以避免扩容时的数据迁移,又可以一定程度上避免范围分片的热点问题。综合了范围分片和求模分片的优点,分片组内使用求模可以保证组内数据比较均匀,分片组之间是范围分片可以兼顾范围查询;
(9)一致性Hash:一致性hash 算法有效解决了分布式数据的扩容问题;
(10)应用指定:此规则是在运行阶段有应用自主决定路由到那个分片;
(11) 截取字符ASCII求和求模范围分片:此种规则类似于取模范围约束,只是计算的数值是取前几个字符的ASCII值和,再取模,再对余数范围分片。
对于Mycat主键值生成说明如下:(具体见我给的文档)
(1)本地文件方式;
(2)数据库方式;
(3)本地时间戳方式;
(4)分布式ZK ID 生成器;
(5)Zk 递增方式。

四、Mycat高可用架构

Mycat高可用方案如下:
(1)Haproxy+Mycat集群+读写分离:
在这里插入图片描述
【注】具体安装见我给的文档。
(2)负载不同类型的数据到不同的数据库:
在这里插入图片描述

五、Mycat安装及测试

以下是Mycat的安装步骤:
1.环境准备:
(1)JDK使用的是jdk-8u261-linux-x64.rpm
(2)MySQL使用的是5.7.22版本
(3)MyCat使用的是Mycat-server-1.6.6.1-release-20181031195535-linux.tar
2.JDK安装:
(1)上传jdk安装包到linux机器上
(2)root用户身份安装,命令:

rpm -ivh jdk-8u162-linux-x64.rpm

(3)vim /etc/profile 在末尾添加

export JAVA_HOME=/usr/java/latest
export CLASSPATH=.:$JAVA_HOME/lib
export PATH=$JAVA_HOME/bin:$PATH

(4)保存退出
(5)使配置生效,执行命令:

source /etc/profile

(6)验证:

java -version

3.MySQL主从安装:
(1)启动mysql主容器:

docker run --restart=always --name mysql-master --privileged=true -v /home/mysql/master-data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d xiaochunping/mysql-master

(2)启动mysql从容器:

docker run --restart=always --name mysql-slave --privileged=true -v /home/mysql/slave-data:/var/lib/mysql -p 3307:3306 --link mysql-master:master -e MYSQL_ROOT_PASSWORD=root -d xiaochunping/mysql-slave

(3)进入主mysql的容器并进行相关配置(命令依次执行):

1>docker exec -it mysql-master /bin/bash
2>mysql -uroot -proot
3>grant replication slave on *.* to 'test'@'%' identified by '123456';
4>flush privileges;
5>show master status;

(4)进入从mysql的容器并进行相关配置(命令依次执行):

1>docker exec -it mysql-slave /bin/bash
2>mysql -uroot -proot
3>change master to master_host='master', master_user='test', 
master_password='123456', \
master_port=3306, master_log_file='mysql-bin.000003', master_log_pos=589, 
master_connect_retry=30;(注意,mysql-bin.000003589这两个值是主容器的数据)
4>start slave;(注意,启动失败可以执行"reset slave;"并再次执行)
5>show slave status\G(注意,必须要有两个"YES"才算成功)

4.MyCat安装:
(1)解压安装包到目标安装目录:

tar -zxvf Mycat-server-1.6.6.1-release-20181031195535-linux.tar.gz -C /usr/local/

(2)配置环境变量,执行vim /etc/profile 并在最后加上:

export MYCAT_HOME=/usr/local/mycat

(3)新增用户mycat(建议不要用root用户来运行mycat):

useradd mycat

(4)设置密码

passwd mycat

(5)修改mycat安装目录的所有者为mycat用户:

chown -R mycat:mycat /usr/local/mycat

(6)切换到mycat下的conf目录,可以配置MyCat:

cd /usr/local/mycat/conf

【注】conf目录包含:MyCat服务器参数(server.xml)、逻辑库定义等(schema.xml)、分片规则(rule.xml)和更改MyCat日志设置(log4j2.xml)
(7)以下依次是我的配置:
1>server.xml配置:
在这里插入图片描述
2>schema.xml配置:
在这里插入图片描述
【注】这里的0机器和1机器分别指的是配置的dn1和dn2,以此类推。
3>rule.xml配置(部分)和id-range-partition(分片路由规则):
在这里插入图片描述
在这里插入图片描述
4>log4j2.xml配置:
在这里插入图片描述
(8)切换到mycat下的bin目录,可以启动MyCat:

1>cd /usr/local/mycat/bin
2>./mycat start
3>使用jps检查MyCat服务是否启动

(9)查看MyCat日志:

tail -f /usr/local/mycat/logs/mycat.log

(10)查看MyCat日志,测试读写分离、分库分表:
1>首先执行插入SQL:

insert into `user` VALUES (8,"测试名称","888")

2>再执行查询SQL:

select * FROM `user` 	

3>可以看到以下结果;写操作在主数据库上,读操作在从数据库上,读写分离测试成功:
在这里插入图片描述
在这里插入图片描述
4>接着插入一批数据:
在这里插入图片描述
5>观察0机器的库和1机器的库,发现确实按照我们指定的规则分库分表了,分库分表测试成功:
在这里插入图片描述
在这里插入图片描述
【注】最后附上一份Mycat相关文档(安装与说明),需要的自取:Mycat相关文档 提取码:4psz

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值