系统开发中,数据库是非常重要的一个点。除了程序的本身的优化,如:SQL语句优化、代码优化,数据库的处理本身优化也是非常重要的。主从、热备、分表分库等都是系统发展迟早会遇到的技术问题问题。Mycat是一个广受好评的数据库中间件,已经在很多产品上进行使用了。下面就针对Mycat的基础知识和应用做一总结性梳理,这些内容有的是从网上收集的,有的是自己做的测试验证信息,如有错误,烦请谅解和指出!
操作系统:CentOS-6.6-x86_64
JDK版本:jdk1.7.0_72
HAProxy版本:haproxy-1.5.16.tar.gz
MyCat版本:Mycat-server-1.4-release-20151019230038-linux.tar.gz
MySQL版本:mysql-5.6.26.tar.gz
图解说明:
HAProxy负责将请求分发到MyCat上,起到负载均衡的作用,同时HAProxy也能检测到MyCat是否存活,HAProxy只会将请求转发到存活的MyCat上。如果一台MyCat服务器宕机,HAPorxy转发请求时不会转发到宕机的MyCat上,所以MyCat依然可用。
1、 查看镜像列表
docker image ls
docker image ls|grep “镜像名模糊查询字段”
2、 查看某个镜像详细信息
docker inspect REPOSITORY:TAGS
如:docker inspect rancher/rancher:latest
可以留意volume目录,可以看出容器内的数据卷路径,方便的找到容器内的项目路径
3、 删除镜像
docker rmi REPOSITORY:TAGS
如:docker rmi redis:5.0.5-alpine3.10
4、 执行如下命令查看我们刚才启动的容器信息
docker container ls
docker image ls|grep 容器名模糊查询字段
或 docker ps -a 这里的-a可以查看所有的容器,包括启动失败的容器,不加-a则看不到失败的容器
5、 日志打印
docker logs -f -t --tail 200 容器id
6、 进入容器内部(进入容器后不支持ll,支持ls)
docker exec -it 容器id /bin/bash
或 docker exec -it 容器id /bin/sh
如:docker exec -it 44fc0f0582d9 /bin/bash
或 docker exec -it 44fc0f0582d9 /bin/sh
7、 将容器打成本地镜像文件
docker commit 容器id 自定义REPOSITORY:自定义TAGS
如: docker commit 82c2ec442fe5 mysql_master:v1
8、 登录docker,登录后可以推送镜像到docker hub中
docker login
然后输入用户名,密码
docker logout 注销登录
9、 修改镜像名称
docker tag 镜像原名称:版本号 修改后的镜像名称:版本号
版本号为latest时,可省略
如:docker tag mysql_master:v1 zhoupeng1107/mysql-master
10、 将镜像推送到DockerHub中
docker push 注册用户名/镜像名:版本号
如:docker push zhoupeng1107/mysql-master:latest
版本号为latest时,可省略
11、 从DockerHub中搜索镜像
docker search 镜像名称模糊查询字段
如:docker search zhoupeng1107/mysql-master
1、mysql集群原理及原因分析:
1)若干个数据库共同组成了一个集群,称为数据库集群。它包括两种常见结构:一主多从,多主多从。
2)一主多从服务器,当主服务器挂掉了,那么整个数据库集群系统就全部挂掉了,这显然不是我们希望看到的,那么自然的就想到了使用多个主服务器来提供服务,当其中一个主服务器挂掉了,其他的主服务器还能继续提供服务。这就是多主多从存在的意义
3)对于MySQL主从集群,我们的需求是master挂了,slave还能提供读的功能。
2、mysql提供的主从复制原理分析:
1)主从复制的原理也非常简单,通俗的讲就是:当对主服务器进行写的操作时,主服务器将自己的操作记录到一个二进制日志文件中,从服务器有一个心跳机制,定时的去读取主服务器的日志文件,当对比自己的日志文件有差异时,将差异部分同步更新到自己的服务器上
3、读写分离原因分析:
1)读写分离的好处: 第一,增加了冗余(备份数据)。第二, 读写分开,减轻机器压力,提高数据库并发。
4、mysql集群中间件方案整理:
1)Mycat自身不提供主从复制的功能,也不做数据备份,因此应用Mycat做读写分离,主从复制还得使用Mysql的机制。
5、部署mysql单服务
点击资源菜单下的配置映射,点击添加配置映射
填写名称和选择命名空间,后续不可更改。然后配置映射的键和值,键就是文件名,值就是配置文件的内容,如果这个服务还需要改其他的配置文件,点击添加配置映射值就可以添加多个了。
然后开始部署服务,点击部署服务按钮
填写名称,之后不可改,类型使用默认的,选择一个命名空间。需要重点讲的是docker镜像的地址怎么填。
第一种是公有镜像,官方的仓库网站Docker Hub:https://hub.docker.com/ 中有许多人上传的镜像,包括许多产品官方上传的镜像。仓库中所有的镜像都是可以直接拿来用的,镜像地址就是Tags页签下每个版本右侧的docker pull命令后的地址。如:mysql:lastest;mysql:8.0.22等。
第二种是私有镜像,私有镜像其实就是产品的压缩包,用自己编写的一个简单的Docker File,通过docker工具就可以打成一个镜像了,把这个镜像文件上传到主机上就可以使用了。它的镜像地址就是REPOSITORY:TAG,如laydocker/sentinel:0.0.1
添加端口映射,因为mysql的默认端口是3306,如果不进行映射的话,就会直接使用3306端口,那就无法在一台主机上部署多个mysql服务了。
端口映射共有四种网络模式,这里介绍两种常用的。第一种是NodePort,选择这种方式的话,如果该服务是可以被所有主机发现的话,那么K8S集群内的所有主机都可以通过这个端口来访问这个服务。
该方式在容器创建成功后,这里的端口映射默认第一次会随机分配一个可用的端口,后续是不会改变的,所以也不需要指定主机监听端口,避免重复。端口名称可不填,会自动生成。
例如部署mysql服务,使用NodePort模式,那么可以通过K8S集群中任何一台主机加上随机的端口来连接这个mysql服务。
第一种是HostPort,选择这种方式的话,K8S集群内的所有主机都可以通过这个端口来访问这个服务。
该方式必须手动指定一个主机端口监听。
例如部署mysql服务,使用HostPort模式,那么只能通过主机调度中指定的主机或主机调度中随机分配到的主机加上指定的端口来连接这个mysql服务。
环境变量,mysql服务必须要配一个MYSQL_ROOT_PASSWORD的变量,指定登录mysql的密码,这个key是mysql这个产品指定的,照着写就行了。TZ可以指定时区,中国用Asia/Shanghai。
主机调度就是指定这个服务在哪个主机上面运行,我们可以看到一开始我们有3台主机,为了自己区分方便,且为了给mysql指定一台性能较好的主机,我们手动指定一台,当然,随机也没问题。
健康检查可以通过TCP端口或HTTP等来进行检查容器的健康状态。分为就绪状态检查 (readiness)和存活状态检查(liveness)。检查容器是否启动成功和容器是否运行健康。
我们使用TCP端口检查,然后单击有上方的蓝色小字:单独配置存活状态(liveness)检查。然后填写mysql的TCP端口3306,然后使用默认的配置即可。
健康阈值是指在容器(当前标记为非健康)被再次认为是健康前成功的检查响应次数。
不健康阈值是指在容器(当前标记为健康)被认为是非健康前失败的检查响应次数。
接下来就是重点了,点击添加卷,选择使用现有的pvc。
首先我们需要了解添加pvc映射有什么用,其实主要作用就是将容器内部路径下的所有文件和nfs下自定义的外部路径中所有文件进行关联。这样可以实现两个目的,第一是将容器内的文件拿出来了,这样容器停止后,数据文件也不会丢失,比如mysql的数据库文件;而且放到容器外部的文件操作起来会比较方便。第二是可以直接在外部修改配置文件,然后直接关联到容器内部的配置文件,实现配置文件在容器外修改。
然后我们再回到rancher的配置,首先卷名是默认给的,没有用,然后选择之前添加好的pvc,容器路径其实就是容器内部的路径,看你想把哪个路径和外部进行关联,每个产品都是不一样的。
比如mysql的文件都在/var/lib/mysql和/etc/mysql中,mycat的文件都在/usr/local/mycat中。
想知道只能自己百度,然后自己去容器内部查看这个路径是否存在。子路径就是pv所在目录的自定义下级目录,就是想关联的容器外部目录,也就是说是随便填的,在我们启动容器的时候会自动生成。
比如百度了mysql的数据库文件在/var/lib/mysql中,然后我们可以先不配置这个数据卷的内容,先直接启动容器。
然后到启动该容器的对应的主机中使用docker container ls查询到该容器的id,容器都是按时间倒序排列的,一般就是最新的第一个。
然后使用docker exec -it 容器id /bin/bash或者docker exec -it 容器id /bin/sh,进入容器。然后直接cd /var/lib/mysql查看是不是数据库文件的存储路径,如果是,那么就说明我们的容器路径找到了。
然后我们想把这些文件放到容器外面来,也就是我们的nfs中,我们就先查看我们配置pv的时候填写的nfs路径,进入nfs服务所在主机后,进入该nfs路径内查看,只要不和已存在的文件夹重名即可。
我们的pv的路径填写的是/data/nfs/rancher/mysql,查看到当前路径下的文件夹后,我们的子路径可以随便填不重复的路径,如mysql/data。
接下来就是如何修改配置了,主要是两种方式,先说第一种,通过pvc映射的方式,我们使用的不是该方式,不想知道的直接看第二种方式即可,注意不要添加下列配置。
首先先使用docker exec进入容器中的/etc/mysql路径下,找到my.cnf。这个路径也是mysql规定的。然后复制到容器外部并下载下来。然后我们修改好配置后,再上传到nfs路径下对应的文件夹中,这里我们是放在mysql7/master1/conf中,文件夹不存在就自己建一下。
然后在pvc映射中添加一行路径映射即可。
第二种方式是我们使用的方式,主要是比较方便,可以在线添加和修改配置。
会使用到我们在一开始就添加好了配置映射。首先点击添加卷,选择配置映射卷。
卷名是默认的,没有用;默认模式改为444,还有一种644模式会在mycat配置中用到;配置映射名选择开始配置好的mysql的配置;容器路径就填到配置文件所在的容器内部路径,mysql就是/etc/mysql的默认路径,子路径不用填,因为不会关联到容器外部的路径;其他都使用默认即可。
都配置完成后,点击最下方启动即可。可以去我们的pv路径下,也就是/data/nfs/rancher/mysql下查看自动生成的文件,是否和容器内路径下的文件一致。
6、部署mysql主从复制
使用mysql自带的binlog主从复制,部署双主双从集群,保证稳定性。
原理是:
master1为第一个主库,master2和slave1为master1的从库;
master2为第二个主库,master1和slave2为master2的从库。
和部署mysql单服务唯一的不同之处是每个mysql的配置文件不同,需要单独添加配置映射。配置中唯一不同的地方是server_id一定要保证唯一,这里就给一个配置,其他配置修改server_id即可。
特别参数说明:
log-slave-updates = true #将复制事件写入binlog,一台服务器既做主库又做从库此选项必须要开启
#理论上来说,应该要限制主库A的id都是奇数,主库B的id都是偶数,这样两个库同时写也不会有id重复,但是因为我们会使用mycat做读写分离,同时只会有一个库进行写的操作,所以暂时不用该配置。该配置添加后无法再按照id排序,因为两个库的增长是不同的。
#masterA自增长ID auto_increment_offset = 1 auto_increment_increment = 2
#奇数ID
#masterB自增加ID auto_increment_offset = 2 auto_increment_increment = 2
#偶数ID
然后部署服务,步骤和部署单服务完全一致,部署四个除了配置文件完全一致的容器。
这里需要注意的是,因为我们的端口映射使用的是NodePort随机端口,所以主机调度中指定的一台主机可以运行多个mysql容器。
然后我们通过ip加上工作负载中映射的端口就可以使用Navicat连接数据库了,因为我们是使用NodePort方式进行端口映射的,这种方式的话可以使用所有主机的端口来访问,所以ip可以直接用主机ip即可。
我的四个库分别是:
master1:172.40.20.126:30633
master2:172.40.20.126:31200
slave1:172.40.20.126:31210
slave2:172.40.20.126:30677
然后我们需要通过mysql自带的心跳日志功能实现主从复制。
下面使用Navicat执行sql语句:
master1:
GRANT REPLICATION SLAVE ON . TO ‘root’@’%’; #执行一次即可
flush privileges;
show master status;
master2和slave1:
stop slave; #如果之前已经作为子节点启动过,需要先停止
# stop后再次使用show slave status查看,可以看到slave_io_state字段为空了
CHANGE MASTER TO
MASTER_HOST=‘172.40.20.126’,
MASTER_PORT=30633,
MASTER_USER=‘root’,
MASTER_PASSWORD=‘123456’,
MASTER_LOG_FILE=‘mysql-bin.000008’,
MASTER_LOG_POS=154;
#这里的MASTER_LOG_FILE和MASTER_LOG_POS是上面show master status命令查出来的
start slave;
show slave status;
上述操作就是实现将master1作为主库,将master2和slave1作为master1的从库。
然后需要实现将master2作为主库,将master1和slave2作为master2的从库,语句同上,修改端口等。
都执行完后,双主双从的mysql集群就部署完成了。
然后我们在master1中添加数据库,如ha_edu_test。这时,应该所有mysql服务中都会有该数据库了。
然后分别在master1和master2中写数据,测试数据是否同步。
扩展:为了提升查询的性能,有人创新的设计了一种MySQL主从复制的模式,主节点为InnoDB引擎,读节点为MyISAM引擎,经过实践,发现查询性能提升不少。(本人没有尝试,建议反复测试后使用)
1、MyCat简单介绍
基于阿里开源的Cobar产品而研发,Cobar的稳定性、可靠性、优秀的架构和性能以及众多成熟的使用案例使得MYCAT一开始就拥有一个很好的起点。一个彻底开源的,面向企业应用开发的大数据库集群。
MyCat是一个开源的分布式数据库系统,是一个实现了MySQL协议的服务器,前端用户可以把它看作是一个数据库代理**(类似于Mysql Proxy)**,用MySQL客户端工具和命令行访问,而其后端可以用MySQL原生协议与多个MySQL服务器通信,也可以用JDBC协议与大多数主流数据库服务器通信,其核心功能是分表分库,即将一个大表水平分割为N个小表,存储在后端MySQL服务器里或者其他数据库里。
MyCat发展到目前的版本,已经不是一个单纯的MySQL代理了,它的后端可以支持MySQL、SQL Server、Oracle、DB2、PostgreSQL等主流数据库,也支持MongoDB这种新型NoSQL方式的存储,未来还会支持更多类型的存储。而在最终用户看来,无论是那种存储方式,在MyCat里,都是一个传统的数据库表,支持标准的SQL语句进行数据的操作,这样一来,对前端业务系统来说,可以大幅降低开发难度,提升开发速度。
2、Mycat可以简单概括为
- 一个彻底开源的,面向企业应用开发的大数据库集群
- 支持事务、ACID、可以替代MySQL的加强版数据库
- 一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
- 一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
- 结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
- 一个新颖的数据库中间件产品
3、Mycat关键特性
- 支持SQL92标准
- 遵守Mysql原生协议,跨语言,跨平台,跨数据库的通用中间件代理
- 基于心跳的自动故障切换,支持读写分离,支持MySQL主从,以及galera cluster集群
- 支持Galera for MySQL集群,Percona Cluster或者MariaDB cluster
- 基于Nio实现,有效管理线程,高并发问题
- 支持数据的多片自动路由与聚合,支持sum,count,max等常用的聚合函数,支持跨库分页
- 支持单库内部任意join,支持跨库2表join,甚至基于caltlet的多表join
- 支持通过全局表,ER关系的分片策略,实现了高效的多表join查询
- 支持多租户方案
- 支持分布式事务(弱xa)
- 支持全局序列号,解决分布式下的主键生成问题
- 分片规则丰富,插件化开发,易于扩展
- 强大的web,命令行监控
- 支持前端作为mysq通用代理,后端JDBC方式支持Oracle、DB2、SQL Server 、 mongodb 、巨杉
- 支持密码加密
- 支持服务降级
- 支持IP白名单
- 支持SQL黑名单、sql注入攻击拦截
- 支持分表(1.6)
- 集群基于ZooKeeper管理,在线升级,扩容,智能优化,大数据处理(2.0开发版)
MYCAT监控
1.支持对Mycat、Mysql性能监控
2.支持对Mycat的JVM内存提供监控服务
3.支持对线程的监控
4.支持对操作系统的CPU、内存、磁盘、网络的监控
4、优点
Mycat作为主数据库中间件,是与代码弱关联的,所以代码是不用修改的,使用Mycat后,连接数据库是不变的,默认端口是8066。连接方式和普通数据库一样,如:jdbc:mysql://192.168.0.2:8066/
自带监控,提供较全面的监控服务
可实现数据库的读写分离,在后端的主从复制数据库集群中,通过MYCAT配置,将前台的写操作路由到主数据库中,将读操作路由到从数据库上。
MYCAT可以实现读写分离下的读操作负载均衡,将大量的读操作均衡到不同的从库上,主要出现在一主多从情形下。
MYCAT可实现数据库的高可用,在数据库主节点可用的情况下,配置一台可写从节点,这两个节点都配置在MYCAT中,当主节点宕机时,MyCAT会自动将写操作路由到备用节点上,但并不支持在切换之后的继续主从同步。
当读写分离已经不能满足持续增加的访问量时,MYCAT可实现数据库的垂直拆分,将所有的数据库表按照模块划分,不同类型的表拆分到不同的数据库服务器。
随着业务量的增长,垂直拆分之后如果又出现了数据库性能问题,则需要进行水平切分,这就是俗称的分库分表。将数据量很大的表数据切分到不同的服务器库中,表结构是一样的,而使用MYCAT实现水平切分,对前端应用是完全透明的,不用调整前台逻辑。
5、为什么要用MyCat
这里要先搞清楚Mycat和MySQL的区别(Mycat的核心作用)。我们可以把上层看作是对下层的抽象,例如操作系统是对各类计算机硬件的抽象。那么我们什么时候需要抽象?假如只有一种硬件的时候,我们需要开发一个操作系统吗?再比如一个项目只需要一个人完成的时候不需要leader,但是当需要几十人完成时,就应该有一个管理者,发挥沟通协调等作用,而这个管理者对于他的上层来说就是对项目组的抽象。
同样的,当我们的应用只需要一台数据库服务器的时候我们并不需要Mycat,而如果你需要分库甚至分表,这时候应用要面对很多个数据库的时候,这个时候就需要对数据库层做一个抽象,来管理这些数据库,而最上面的应用只需要面对一个数据库层的抽象或者说数据库中间件就好了,这就是Mycat的核心作用。所以可以这样理解:数据库是对底层存储文件的抽象,而Mycat是对数据库的抽象。
6、Mycat工作原理
Mycat的原理并不复杂,复杂的是代码。Mycat的原理中最重要的一个动词是“拦截”,它拦截了用户发送过来的SQL语句,首先对SQL语句做了一些特定的分析:如分片分析、路由分析、读写分离分析、缓存分析等,然后将此SQL发往后端的真实数据库,并将返回的结果做适当的处理,最终再返回给用户。
上述图片里,Orders表被分为三个分片datanode(简称dn),这三个分片是分布在两台MySQL Server上(DataHost),即datanode=database@datahost方式,因此你可以用一台到N台服务器来分片,分片规则为(sharding rule)典型的字符串枚举分片规则,一个规则的定义是分片字段(sharding column)+分片函数(rule function),这里的分片字段为prov而分片函数为字符串枚举方式。
当Mycat收到一个SQL时,会先解析这个SQL,查找涉及到的表,然后看此表的定义,如果有分片规则,则获取到SQL里分片字段的值,并匹配分片函数,得到该SQL对应的分片列表,然后将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引擎等十八般武艺的解决办法,从而成为目前业界最强大的方案,这就是开源的力量!
7、Mycat应用场景
Mycat发展到现在,适用的场景已经很丰富,而且不断有新用户给出新的创新性的方案,以下是几个典型的应用场景:
- 单纯的读写分离,此时配置最为简单,支持读写分离,主从切换;
- 分表分库,对于超过1000万的表进行分片,最大支持1000亿的单表分片;
- 多租户应用,每个应用一个库,但应用程序只连接Mycat,从而不改造程序本身,实现多租户化;
- 报表系统,借助于Mycat的分表能力,处理大规模报表的统计;
- 替代Hbase,分析大数据;
- 作为海量数据实时查询的一种简单有效方案,比如100亿条频繁查询的记录需要在3秒内查询出来结果,除了基于主键的查询,还可能存在范围查询或其他属性查询,此时Mycat可能是最简单有效的选择;
- Mycat长期路线图;
- 强化分布式数据库中间件的方面的功能,使之具备丰富的插件、强大的数据库智能优化功能、全面的系统监控能力、以及方便的数据运维工具,实现在线数据扩容、迁移等高级功能;
- 进一步挺进大数据计算领域,深度结合Spark Stream和Storm等分布式实时流引擎,能够完成快速的巨表关联、排序、分组聚合等 OLAP方向的能力,并集成一些热门常用的实时分析算法,让工程师以及DBA们更容易用Mycat实现一些高级数据分析处理功能。
- 不断强化Mycat开源社区的技术水平,吸引更多的IT技术专家,使得Mycat社区成为中国的Apache,并将Mycat推到Apache
基金会,成为国内顶尖开源项目,最终能够让一部分志愿者成为专职的Mycat开发者,荣耀跟实力一起提升。
8、Mycat不适合的应用场景
- 设计使用Mycat时有非分片字段查询,请慎重使用Mycat,可以考虑放弃!
- 设计使用Mycat时有分页排序,请慎重使用Mycat,可以考虑放弃!
- 设计使用Mycat时如果要进行表JOIN操作,要确保两个表的关联字段具有相同的数据分布,否则请慎重使用Mycat,可以考虑放弃!
- 设计使用Mycat时如果有分布式事务,得先看是否得保证事务得强一致性,否则请慎重使用Mycat,可以考虑放弃!
需要注意: 在生产环境中, Mycat节点最好使用双节点, 即双机热备环境, 防止Mycat这一层出现单点故障. 可以使用的高可用集群方式有: Keepalived+Mycat+Mysql, Keepalived+LVS+Mycat+Mysql, Keepalived+Haproxy+Mycat+Mysql
9、利用MyCAT实现MySQL的读写分离、主从切换、分库分表的操作记录
Mycat实现Mysql主从复制,其中写操作在master主节点上执行,包括insert,delete,update 语句操作;读操作在slave节点上执行,只有select语句操作,其他操作均由主master的二进制文件决定;MyCat支持双主多从,多主多从情况需要配置多个writeHost兄弟节点,多个readHost节点即可!
Mycat的架构其实很好理解,Mycat是数据库代理中间件,Mycat后面就是物理数据库。和Web服务器的Nginx类似。对于使用者来说,访问的都是Mycat,不会接触到后端的数据库。
10、Mycat安装场景
实现Mycat读写分离(负载均衡)、主从自动切换
目前有大量Mycat的生产实践案例是属于简单的读写分离类型的,此案例主要用到Mycat的以下特性:
- 读写分离支持
- 高可用
大多数读写分离的案例是同时支持高可用性的,即Mycat+MySQL主从复制的集群,并开启Mycat的读写分离功能,这种场景需求下,Mycat是最为简单并且功能最为
丰富的一类Proxy,正常情况下,配置文件也最为简单,不用每个表配置,只需要在schema.xml中的元素上增加dataNode=“defaultDN”属性,并配置此dataNode
对应的真实物理数据库的database,然后dataHost开启读写分离功能即可。
也可以有多台MySQL服务器,或者SQL Server、Oracle等,配置多个dataHost节点就可以。
需要注意的是:
Mycat主从分离只是在读的时候做了处理,写入数据的时候,只会写入到writehost,需要通过mycat的主从复制将数据复制到readhost!这个问题需要弄明白!!
如果没有提前做mysql主从复制,会发现Mycat读写分离配置后,数据写入writehost后,readhost一直没有数据!因为Mycat就没有实现主从复制的功能,毕竟数据库本身自带的这个功能才是最高效稳定的。
11、部署mycat
首先添加mycat的配置映射
填写名称和选择命名空间,后续不可更改。然后配置映射的键和值,键就是文件名,值就是配置文件的内容,如果这个服务还需要改其他的配置文件,点击添加配置映射值就可以添加多个了。
改动内容:
log4j2.xml:(详细日志级别请参考笔记:设置log4j2 console 日志打印的级别)
中的level从info改为debug,这个配置是为了看到更详细的日志,不改也没关系。
schema.xml:(mycat具体的配置代表的含义请参考笔记:Mycat 读写分离、主从切换、分库分表的操作记录)
dataHost是配置整个读写分离内容的,name随意写个唯一的,后面会用到,balance填1,writeType填0,switchType填2。heartbeat标签内填show slave status。
writeHost标签就是写入的节点,这里的url我们填入master1的ip和端口,host为名称,随意填个唯一的。
readHost是writeHost这个写入节点的读节点,这里的url我们填入master2和slave1的ip和端口,host为名称,随意填个唯一的。
然后再用master2配置一个写入的节点,这样第一个写入节点挂了会自动切换第二个写入的节点。
每个dataNode对应一个数据库,多个database写多个dataNode,database对应database名称,dataHost填写dataHost的name,name随便写个唯一的,后面会用到。
每个schema对应一个dataNode,多个dataNode写多个schema,name对应database名称,dataNode对应dataNode的name。
如果针对的是mysql的多个库,比如mysql的真实库名是kevin、grace、shanshan,那么schema.xml文件里应该指明多个库名,如:
<schema name="mycat" checkSQLschema="false" sqlMaxLimit="100" dataNode="haha,heihei,hengheng">
schema>
<dataNode name="haha" dataHost="Mycat-node" database="kevin" />
<dataNode name="heihei" dataHost="Mycat-node" database="grace" />
<dataNode name="hengheng" dataHost="Mycat-node" database="shanshan" />
........
修改mycat的schema.xml:
balance为1:让全部的readHost及备用的writeHost参与select的负载均衡。
switchType为2:基于MySQL主从同步的状态决定是否切换。
heartbeat:主从切换的心跳语句必须为show slave status。
server.xml:(添加多个用户请参考笔记:MyCat用户和访问权限配置)
主要改user标签,name就是登陆名,property标签为password的就是密码,property标签为schemas内填入所有需要映射的数据库名,多个用逗号分隔
如果需要多个用户来配置不同的数据库权限,则添加多个user标签,配置自定义的用户名和密码,然后指定需要的schemas即可。
映射配置完后,开始部署服务,点击部署服务按钮。
名称随意填,后续不可修改。
工作负载类型选择Deployment,后续不可更改,StatefulSet重新部署的时候会先remove,然后create;而Deployment则会先启动一个pod,新的pod启动成功后,才会remove老的pod,这样不会有断掉的状态。
选择命名空间,后续不可修改。
Docker镜像从dockerHub找就可以了,看需要哪个版本。
点击添加规则来端口映射,mycat需要监听两个端口,分别是8066和9066。8066是类似mysql的3306的端口,用来连接数据库服务,命令和mysql一致,用Navicat连接即可。9066是mycat的管理端口,提供了mycat自身的命令,也可以直接用Navicat连接。
常用的mycat命令:
show @@help; – 报告所有命令
show @@version – 报告Mycat服务器版本
show @@datasource – 报表数据源
show @@connection – 报告连接状态
show @@sql – SQL报告列表
show @@heartbeat – 心跳状态报告
show @@sysparam – 报告系统参数
reload @@config – 从文件中重新加载基本配置
reload @@config_all – 从文件中重新加载所有配置
环境变量添加TZ,值为Asia/Shanghai,使用中国时区。
主机调度就是指定这个服务在哪个主机上面运行,我们可以看到一开始我们有3台主机,为了自己区分方便,且为了给mysql指定一台性能较好的主机,我们手动指定一台,当然,随机也没问题。
健康检查可以通过TCP端口或HTTP等来进行检查容器的健康状态。添加8066端口即可
添加卷,选择使用现有的pvc。
添加这个配置的原因是为了将日志文件映射到容器外部,能够更方便的看到日志,如果不想看日志,这整个pvc的配置可以去掉。
然后添加卷,选择配置映射卷。
默认模式使用644,可选选择是,然后配置映射名选择刚添加的配置映射,项目不要选择所有键,而是选择特定的键,
然后点击下方的添加项目,将配置文件中的三个键全部添加进来,路径直接使用键的名称即可,这样可以指定对应的配置文件。
然后点击下方添加映射按钮,在容器路径内填上所有的配置文件对应的容器内路径,子路径填写文件名称即可。这样可以分别指派不同路径下的不同配置文件。
都配置完成后,点击最下方启动即可。可以去我们的pv路径下,也就是/data/nfs/rancher/mysql下查看自动生成的文件,是否和容器内路径下的文件一致。
mycat启动成功后,可以使用Navicat分别连接上8066映射出来的端口和9066映射出来的端口。
能连上说明启动成功了。
然后我们在master1中新建一个数据库,如nacos。这时所有的mysql库中都有这个数据库了,但是mycat不会有,因为mycat添加库需要修改配置。
我们打开rancher中的配置映射页面。修改mycat的配置映射文件。
修改scheme.xml,添加:
<schema name="nacos" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn2">schema>
<dataNode name="dn2" dataHost="localhost1" database="nacos" />
修改server.xml,修改name为schemas的property标签,添加nacos:
<property name="schemas">hhhh,nacos,ha_edu_testproperty>
然后在mycat的9066端口的连接中,执行reload @@config_all刷新所有配置就能在mycat中看到nacos这个数据库了。
然后分别将master1服务或master2服务中的pods去掉,再使用另一个写入节点添加数据,测试数据是否同步。
12、Mycat相关配置
Mycat的配置文件都在conf目录里面,这里介绍几个常用的文件:
server.xml Mycat的配置文件,设置账号、参数等
schema.xml Mycat对应的物理数据库和数据库表的配置
rule.xml Mycat分片(分库分表)规则
server.xml文件其实跟读写分离策略关系不大,但是需要用此文件来配置连接MyCat的用户及权限等,因此在这里简单说明。
重点关注上面这段配置,其他默认即可。
=======================================
参数 | 说明 |
---|---|
user | 用户配置节点 |
name | 登录的用户名,也就是连接Mycat的用户名。 |
password | 登录的密码,也就是连接Mycat的密码 |
schemas | 数据库名,这里会和schema.xml中的配置关联,多个用逗号分开,例如需要这个用户需要管理两个数据库db1,db2,则配置db1,dbs |
privileges | 配置用户针对表的增删改查的权限 |
readOnly | mycat逻辑库所具有的权限。true为只读,false为读写都有,默认为false。 |
=======================================
我这里配置了一个账号boo,密码为bo@123,逻辑数据库为mycat,这些信息都可以自己随意定义,读写权限都有,没有针对表做任何特殊的权限。
注意:
- server.xml文件里登录mycat的用户名和密码可以任意定义,这个账号和密码是为客户机登录mycat时使用的账号信息。
- 逻辑库名(如上面的mycat,也就是登录mycat后显示的库名,切换这个库之后,显示的就是代理的真实mysql数据库的表)要在schema.xml里面也定义,否则会导致mycat服务启动失败!
- 这里只定义了一个标签,所以把多余的都注释了。如果定义多个标签,即设置多个连接mycat的用户名和密码,那么就需要在schema.xml文件中定义多个对应的库!
user 标签:
这个标签主要用于定义登录 mycat 的用户和权限。
<user name="test">
<property name="password">testproperty>
<property name="schemas">TESTDBproperty>
<property name="readOnly">trueproperty>
<property name="benchmark">11111property>
<property name="usingDecrypt">1property>
<privileges check="false">
<schema name="TESTDB" dml="0010" showTables="custome/mysql">
<table name="tbl_user" dml="0110">table>
<table name="tbl_dynamic" dml="1111">table>
schema>
privileges>
user>
例如上面的例子中,我定义了一个用户:
用户名为 test
密码也为 test
可访问的 schema 也只有 TESTDB 一个。
如果我在 schema.xml 中定义有多个 schema,这里这个用户是无法访问其他的 schema的。在 mysql 客户端看来则是无法使用 use 切换到这个其他的数据库。如果使用了 use 命令,则 mycat 会报出这样的错误提示:
ERROR 1044 (HY000): Access denied for user ‘test’ to database ‘xxx’
property 标签:
用于具体声明的属性值。
password属性:
声明密码
readOnly属性:
声明限制用户是否只是可读; 为 true 或 false
schemas属性:
声明用户可访问的 schema;修改 schemas 内的文本来控制用户可访问的 schema,同时访问多个 schema 的话使用","隔开
<property name="schemas">TESTDB,db1,db2property>
Benchmark属性:
声明该用户最大连接数;当前端的整体 connection 数达到(benchmark)基准值时,对来自该账户的请求开始拒绝连接,0 或不设表示不限制
<property name="benchmark">1000property>
usingDecrypt属性:
声明是否对密码加密默认 0 否 如需要开启配置 1,同时使用加密程序对密码加密,
加密命令为:
执行 mycat jar 程序:
java -cp Mycat-server-1.4.1-dev.jar org.opencloudb.util.DecryptUtil 0:user:password
Mycat-server-1.4.1-dev.jar 为 mycat download 下载目录的 jar
1:host:user:password 中 0 为前端加密标志
privileges 子节点
对用户的 schema 及 下级的 table 进行精细化的 DML 权限控制,privileges 节点中的 check 属性是用于标识是否开启 DML 权限检查, 默认 false 标识不检查,当然 privileges 节点不配置,等同 check=false;
由于 Mycat 一个用户的 schemas 属性可配置多个 schema ,所以 privileges 的下级节点 schema 节点同样可配置多个,对多库多表进行细粒度的 DML 权限控制。
<user name="zhuam">
<property name="password">111111property>
<property name="schemas">TESTDB,TESTDB1property>
<privileges check="true">
<schema name="TESTDB" dml="0110" >
<table name="table01" dml="0111">table>
<table name="table02" dml="1111">table>
schema>
<schema name="TESTDB1" dml="0110">
<table name="table03" dml="1110">table>
<table name="table04" dml="1010">table>
schema>
privileges>
user>
schema.xml是最主要的配置项,此文件关联mysql读写分离策略!读写分离、分库分表策略、分片节点都是在此文件中配置的!
MyCat作为中间件,它只是一个代理,本身并不进行数据存储,需要连接后端的MySQL物理服务器,此文件就是用来连接MySQL服务器的!
schemaxml文件中配置的参数解释
参数 | 说明 |
---|---|
schema | 数据库设置,此数据库为逻辑数据库,name与server.xml中schema对应 |
dataNode | 分片信息,也就是分库相关配置 |
dataHost | 物理数据库,真正存储数据的数据库 |
配置 | 说明 |
---|---|
name | 属性唯一标识dataHost标签,供上层的标签使用。 |
maxCon | 属性指定每个读写实例连接池的最大连接。也就是说,标签内嵌套的 |
writeHost、readHost | 标签都会使用这个属性的值来实例化出连接池的最大连接数。 |
minCon | 属性指定每个读写实例连接池的最小连接,初始化连接池的大小。 |
每个节点的属性逐一说明
schema:
属性 | 说明 |
---|---|
name | 逻辑数据库名,与server.xml中的schema对应 |
checkSQLschema | 数据库前缀相关设置,建议看文档,这里暂时设为false |
sqlMaxLimit | select 时默认的limit,避免查询全表 |
Table
属性 | 说明 |
---|---|
name | 表名,物理数据库中表名 |
dataNode | 表存储到哪些节点,多个节点用逗号分隔。节点为下文dataNode设置的name |
primaryKey | 主键字段名,自动生成主键时需要设置 |
autoIncrement | 是否自增 |
rule | 分片规则名,具体规则下文rule详细介绍 |
dataNode
属性 | 说明 |
---|---|
name | 节点名,与table中dataNode对应 |
datahost | 物理数据库名,与datahost中name对应 |
database | 物理数据库中数据库名 |
dataHost
属性 | 说明 |
---|---|
name | 物理数据库名,与dataNode中dataHost对应 |
balance | 均衡负载的方式 |
writeType | 写入方式 |
dbType | 数据库类型 |
heartbeat | 心跳检测语句,注意语句结尾的分号要加 |
schema.xml文件中有三点需要注意:balance=“1”,writeType=“0” ,switchType="1"
schema.xml中的balance的取值决定了负载均衡对非事务内的读操作的处理。balance 属性负载均衡类型,目前的取值有 4 种:
balance=“0”: 不开启读写分离机制,所有读操作都发送到当前可用的writeHost 上,即读请求仅发送到writeHost上。
balance=“1”: 读请求随机分发到当前writeHost对应的readHost和standby的writeHost上。即全部的readHost与stand by writeHost 参与select 语句的负载均衡,简单的说,当双主双从模式(M1 ->S1 , M2->S2,并且 M1 与 M2 互为主备),正常情况下, M2,S1,S2 都参与 select 语句的负载均衡
balance=“2”: 读请求随机分发到当前dataHost内所有的writeHost和readHost上。即所有读操作都随机的在writeHost、 readhost 上分发。
balance=“3”: 读请求随机分发到当前writeHost对应的readHost上。即所有读请求随机的分发到 wiriterHost 对应的 readhost 执行, writerHost 不负担读压力,注意 balance=3 只在 1.4 及其以后版本有,1.3 没有。
writeType 属性,负载均衡类型,目前的取值有 3 种
writeType=“0” 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties .
writeType=“1” 所有写操作都随机的发送到配置的 writeHost。
writeType=“2” 没实现。
对于事务内的SQL默认走写节点
以 /balance/ 开头,可以指定SQL使用特定负载均衡方案。例如在大环境开启读写分离的情况下,特定强一致性的SQL查询需求;
slaveThreshold:近似的主从延迟时间(秒)Seconds_Behind_Master < slaveThreshold ,读请求才会分发到该Slave,确保读到的数据相对较新。
schema.xml中的writeType的取值决定了负载均衡对写操作的处理:
writeType=“0”:所有的写操作都发送到配置文件中的第一个write host。(第一个write host故障切换到第二个后,即使之后修复了仍然维持第二个为写库)。推荐取0值,不建议修改.
主从切换(双主failover):switchType 属性
如果细心观察schem.xml文件的话,会发现有一个参数:switchType,如下配置:
参数解读
switchType="-1": 不自动切换
switchType=“1”: 默认值,自动切换
switchType=“2”: 基于MySQL主从同步的状态来决定是否切换。需修改heartbeat语句(即心跳语句):show slave status
switchType=“3”: 基于Mysql Galera Cluster(集群多节点复制)的切换机制。需修改heartbeat语句(即心跳语句):show status like ‘wsrep%’
dbType属性
指定后端连接的数据库类型,目前支持二进制的mysql协议,还有其他使用JDBC连接的数据库。例如:mongodb、oracle、spark等。
dbDriver属性指定连接后端数据库使用的
Driver,目前可选的值有native和JDBC。
使用native的话,因为这个值执行的是二进制的mysql协议,所以可以使用mysql和maridb。
其他类型的数据库则需要使用JDBC驱动来支持。从1.6版本开始支持postgresql的native原始协议。
如果使用JDBC的话需要将符合JDBC 4标准的驱动JAR包放到MYCAT\lib目录下,并检查驱动JAR包中包括如下目录结构的文件:
META-INF\services\java.sql.Driver。在这个文件内写上具体的Driver类名,例如:com.mysql.jdbc.Driver。
heartbeat标签
这个标签内指明用于和后端数据库进行心跳检查的语句。例如,MYSQL可以使用select user(),Oracle可以使用select 1 from dual等。
这个标签还有一个connectionInitSql属性,主要是当使用Oracla数据库时,需要执行的初始化SQL
语句就这个放到这里面来。例如:altersession set nls_date_format=‘yyyy-mm-dd hh24:mi:ss’
1.4主从切换的语句必须是:show slave status
writeHost标签、readHost标签
这两个标签都指定后端数据库的相关配置给mycat,用于实例化后端连接池。
唯一不同的是:writeHost指定写实例、readHost指定读实例,组着这些读写实例来满足系统的要求。
在一个dataHost内可以定义多个writeHost和readHost。但是,如果writeHost指定的后端数据库宕机,那么这个writeHost绑定的所有readHost都将不可用。
另一方面,由于这个writeHost宕机系统会自动的检测到,并切换到备用的writeHost上去。
13、注意事项
- 查询语句不要加事务,否则读操作会被分发到写服务器上。
- 主从复制是mysql自己实现的,mycat只是代理插件,它本身不能实现主从复制,只能实现了读写分离、主从切换、分库分表功能。
为了提升查询的性能,有人创新的设计了一种MySQL主从复制的模式,主节点为InnoDB引擎,读节点为MyISAM引擎,经过实践,发现查询性能提升不少。
此外,为了减少主从复制的时延,也建议采用MySQL 5.6+的版本,用GTID同步复制方式减少复制的时延,可以将一个Database中的表,根据写频率的不同,
分割成几个Database,用Mycat虚拟为一个Database,这样就满足了多库并发复制的优势,需要注意的是,要将有Join关系的表放在同一个库中。
对于某些表,要求不能有复制时延,则可以考虑这些表放到Gluster集群里,消除同步复制的时延问题,前提是这些表的修改操作并不很频繁,需要做性能测试,
以确保能满足业务高峰。
总结一下,Mycat做读写分离和高可用,可能的方案很灵活,只有你没想到的,没有做不到的。
14、Mycat常见问题及注意点
1)Mycat自动切换需要人工处理么?
Mycat通过心跳检测,自主切换数据库,保证高可用性,无须手动切换。
2)Mycat支持集群么?
目前Mycat没有实现对多Mycat集群的支持,可以暂时使用haproxy来做负载,或者统计硬件负载。
3)Mycat目前有生产案例了么?
目前Mycat初步统计大概600家公司使用。
4)Mycat稳定性与Cobar如何?
目前Mycat稳定性优于Cobar,而且一直在更新,Cobar已经停止维护,可以放心使用。
5)Mycat除了Mysql还支持哪些数据库?
mongodb、oracle、sqlserver 、hive 、db2 、 postgresql。
6)Mycat如何配置字符集?
在配置文件server.xml配置,默认配置为utf8。
7)Mycat后台管理监控如何使用?
9066端口可以用JDBC方式执行命令,在界面上进行管理维护,也可以通过命令行查看命令行操作。
命令行操作是:mysql -h127.0.0.1 -utest -ptest -P9066 登陆,然后执行相应命令。
8)Mycat主键插入后应用如何获取?
获得自增主键,插入记录后执行select last_insert_id()获取。
9)Mycat运行sql时经常阻塞或卡死是什么原因?
如果出现执行sql语句长时间未返回,或卡死,请检查是否是虚机下运行或cpu为单核。如果仍旧无法解决,可以暂时跳过,目前有些环境阻塞卡死原因未知。
10)Mycat中,旧系统数据如何迁移到Mycat中?
旧数据迁移目前可以手工导入,在mycat中提取配置好分配规则及后端分片数据库,然后通过dump或loaddata方式导入,后续Mycat就做旧数据自动数据迁移工具。
11)Mycat如何对旧分片数据迁移或扩容,支持自动扩容么?
目前除了一致性hash规则分片外其他数据迁移比较困难,目前暂时可以手工迁移,未提供自动迁移方案,具体迁移方案情况Mycat权威指南对应章节。
12)Mycat支持批量插入吗?
目前Mycat1.3.0.3以后支持多values的批量插入,如insert into(xxx) values(xxx),(xxx) 。
13)Mycat支持多表Join吗?
Mycat目前支持2个表Join,后续会支持多表Join,具体Join请看Mycat权威指南对应章节。
14)Mycat 启动报主机不存在的问题?
需要添加ip跟主机的映射。
15)Mycat连接会报无效数据源(Invalid datasource)?
例如报错:mysql> select * from company;
ERROR 3009 (HY000): java.lang.IllegalArgumentException: Invalid DataSource:0
这类错误最常见是一些配置问题例如schema.xml中的dataNode的配置和实际不符合,请先仔细检查配置项,确保配置没有问题。
如果不是配置问题,分析具体日志看出错原因,常见的有:
- 如果是应用连:在某些版本的Mysql驱动下连接Mycat会报错,可升级最新的驱动包试下。
- 如果是服务端控制台连,确认mysql是否开启远程连接权限,或防火墙是否设置正确,或者数据库database是否配置,或用户名密码是否正确。
16)Mycat支持的或者不支持的语句有哪些?
insert into,复杂子查询,3表及其以上跨库join等不支持。
17)MycatJDBC连接报 PacketTooBigException异常
检查mysqljdbc驱动的版本,在使用mycat1.3和mycat1.4版本情况下,不要使用jdbc5.1.37和38版本的驱动,会出现如下异常报错:
com.mysql.jdbc.PacketTooBigException: Packet for query is too large (60 > -1). You can change this value on the server by setting the max_allowed_packet’ variable。
建议使用jdbc5.1.35或者36的版本。
18)Mycat中文乱码的问题
答:如果在使用mycat出现中文插入或者查询出现乱码,请检查三个环节的字符集设置:
a)客户端环节(应用程序、mysql命令或图形终端工具)连接mycat字符集
b)mycat连接数据库的字符集
c)数据库(mysql,oracle)字符集。这三个环节的字符集如果配置一致,则不会出现中文乱码,其中尤其需要注意的是客户端连接mycat时使用的连接字符集,
通常的中文乱码问题一般都由此处设置不当引出。其中mycat内部默认使用utf8字符集,在最初启动连接数据库时,mycat会默认使用utf8去连接数据库,当客户
端真正连接mycat访问数据库时,mycat会使用客户端连接使用的字符集修改它连接数据库的字符集,在mycat环境的管理9066端口,可以通过"show @@backend"命令
查看后端数据库的连接字符集,通过show @@connection命令查看前端客户端的连接字符集。客户端的连接可以通过指定字符集编码或者发送SET命令指定连接mycat
时connection使用的字符集,常见客户端连接指定字符集写法如下:
- jdbcUrl=jdbc:mysql://localhost:8066/databaseName? characterEncoding=iso_1
- SET character_set_client = utf8;用来指定解析客户端传递数据的编码
SET character_set_results = utf8;用来指定数据库内部处理时使用的编码
SET character_set_connection = utf8;用来指定数据返回给客户端的编码方式
- mysql –utest –ptest –P8066 –default-character-set=gbk
19)Mycat无法登陆Access denied
Mycat正常安装配置完成,登陆mycat出现以下错误:
[mysql@master ~]$ mysql -utest -ptest -P8066
ERROR 1045 (28000): Access denied for user 'test’@’localhost’ (using password: YES)
请检查在schema.xml中的相关dataHost的mysql主机的登陆权限,一般都是因为配置的mysql的用户登陆权限不符合,mysql用户权限管理不熟悉的请自己度娘。
只有一种情况例外,mycat和mysql主机都部署在同一台设备,其中主机localhost的权限配置正确,使用-hlocalhost能正确登陆mysql但是无法登陆mycat的情况,
请使用-h127.0.0.1登陆,或者本地网络实际地址,不要使用-hlocalhost,很多使用者反馈此问题,原因未明。
20)Mycat的分片数据插入报异常IndexOutofBoundException
在一些配置了分片策略的表进行数据插入时报错,常见的报错信息如下:java.lang.IndexOutOfBoundsException:Index:4,size:3
这类报错通常由于分片策略配置不对引起,请仔细检查并理解分片策略的配置,例如:使用固定分片hash算法,PartitionByLong策略,如果schema.xml里面设置
的分片数量dataNode和rule.xml配置的partitionCount 分片个数不一致,尤其是出现分片数量dataNode小于partitionCount数量的情况,插入数据就可能会报错。
很多使用者都没有仔细理解文档中对分片策略的说明,用默认rule.xml配置的值,没有和自己实际使用环境进行参数核实就进行分片策略使用造成这类问题居多。
21)Mycat ER分片子表数据插入报错
一般都是插入子表时出现不能找到父节点的报错。报错信息如: [Err] 1064 - can’t find (root) parent sharding node for sql:。
此类ER表的插入操作不能做为一个事务进行数据提交,如果父子表在一个事务中进行提交,显然在事务没有提交前子表是无法查到父表的数据的,因此就无法确定
sharding node。如果是ER关系的表在插入数据时不能在同一个事务中提交数据,只能分开提交。
22)Mycat最大内存无法调整至4G以上
mycat1.4的JVM使用最大内存调整如果超过4G大小,不能使用wrapper.java.maxmemory参数,需要使用wrapper.java.additional的写法,注意将
wrapper.java.maxmemory参数注释,例如增加最大内存至8G:wrapper.java.additional.10=-Xmx8G。
23)Mycat使用过程中报错怎么办
记住无论什么时候遇到报错,如果不能第一时间理解报错的原因,首先就去看日志,无论是启动(wrapper.log)还是运行过程中(mycat.log),请相信良好的
日志是编程查错的终极必杀技。日志如果记录信息不够,可以调整conf/log4j.xml中的level级别至debug,所有的详细信息均会记录。另外如果在群里面提问,
尽量将环境配置信息和报错日志提供清楚,这样别人才能快速帮你定位问题。
1、HAProxy介绍
HAProxy官网:http://www.haproxy.org/
HAProxy各版本的官方文档:http://cbonte.github.io/haproxy-dconv/index.html
HAProxy 是一款提供高可用性、负载均衡以及基于TCP(第四层)和HTTP(第七层)应用的代理软件,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。
HAProxy目前主要有三个版本:1.4、1.5、1.6、1.7,CentOS6.6自带的RPM包为1.5的。
HAProxy1.5版开始,支持SSL、DDoS防护等功能,可看官网说明:
version 1.5 : the most featureful version, supports SSL, IPv6, keep-alive, DDoS protection, etc…
Mycat官方推荐使用HAProxy做MyCat的高可用负载均衡代理。
2、HAProxy的安装
部署HAProxy实现mycat集群
mycat是没有自带的集群功能的,官方推荐使用Haproxy。
首先添加haproxy的配置映射
填写名称和选择命名空间,后续不可更改。然后配置映射的键和值,键就是文件名,值就是配置文件的内容,如果这个服务还需要改其他的配置文件,点击添加配置映射值就可以添加多个了。
改动内容:
haproxy.cfg:将需要监听的服务添加到这里即可。
######## 监控界面配置 #################
listen admin_stats
#监控界面的访问的IP和端口
bind 0.0.0.0:1080
#访问协议
mode http
#URI相对地址
stats uri /dbs
#统计报告格式
stats realm Global\ statistics
#登陆帐户信息
stats auth admin:admin
########frontend配置##############
#mycat负载均衡
listen proxy-mycat
#访问的IP和端口
bind 0.0.0.0:8443
#网络协议
mode tcp
#负载均衡算法(轮询算法)
#轮询算法:roundrobin
#权重算法:static-rr
#最少连接算法:leastconn
#请求源IP算法:source
balance roundrobin
# 这里是容器中的IP地址,由于配置的是轮询roundrobin,weight 权重其实没有生效
server mycat_01 172.40.20.124:32408 check weight 1 maxconn 2000
server mycat_02 172.40.20.125:32408 check weight 1 maxconn 2000
映射配置完后,开始部署服务,点击部署服务按钮。
名称随意填,后续不可修改。
工作负载类型选择Deployment,后续不可更改,StatefulSet重新部署的时候会先remove,然后create;而Deployment则会先启动一个pod,新的pod启动成功后,才会remove老的pod,这样不会有断掉的状态。
选择命名空间,后续不可修改。
Docker镜像从dockerHub找就可以了,看需要哪个版本,一般使用官方的haproxy:lts即可。
LTS版本:一般是长期支持的版本,会定时发布系统更新。
点击添加规则来端口映射,由于haproxy.cfg中使用了1080和8443端口,所以这里需要添加两个监听端口。
如果不需要指定端口的话,网络模式一般选择NodePort即可。
主机调度就是指定这个服务在哪个主机上面运行,我们可以看到一开始我们有3台主机,为了自己区分方便,且为了给haproxy指定一台性能较好的主机,我们手动指定一台,当然,随机也没问题。
然后添加卷,选择配置映射卷。
默认模式使用444,可选默认否,然后配置映射名选择刚添加的配置映射,项目使用默认所有键。
容器路径就填到配置文件所在的容器内部路径,从DockerHub中可以看到,haproxy的配置文件就是/usr/local/etc/haproxy/haproxy.cfg,子路径不用填,因为不会关联到容器外部的路径;其他都使用默认即可。
都配置完成后,点击最下方启动即可。
haproxy启动成功后,可以使用启动服务的ip加上admin_stats配置的端口的映射来访问页面端。用户名和密码也在admin_stats配置中。
3、登录HAProxy的状态信息统计页面
http://192.168.209.135:48800/admin-status
用户名和密码都是admin,对应的haproxy.cfg配置片段
##HAProxy的状态信息统计页面
listen admin_stats bind :48800 ##绑定端口
stats uri /admin-status ##统计页面
stats auth admin:admin ##设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可
mode http option httplog ##启用日志记录HTTP请求
统计页面如下图所示:
然后可以使用proxy-mycat配置的端口的映射来连接mycat集群,能连上说明启动成功了。
4、HAProxy配置Mycat负载均衡集群
HAProxy支持TCP(第四层)和HTTP(第七层)应用的代理,本节课程我们使用HAProxy来做MyCat的负载均衡代理使用的是TCP模式。在4层模式下HAProxy仅在客户端和服务器之间转发双向流量。HAProxy配置简单,拥有非常不错的服务器健康检查功能,当其代理的后端服务器出现故障,HAProxy会自动将该服务器摘除,故障恢复后会自动将该服务器加入进来。
1、修改haproxy.cfg 配置文件
具体参数说明可参考官方配置文档 /usr/local/haproxy/doc/haproxy/configuration.txt
或GitHub连接:http://cbonte.github.io/haproxy-dconv/configuration-1.5.html
# vi /usr/local/haproxy/conf/haproxy.cfg
## global配置中的参数为进程级别的参数,通常与其运行的操作系统有关
global
log 127.0.0.1 local0 info ## 定义全局的syslog服务器,最多可以定义2个
### local0是日志设备,对应于/etc/rsyslog.conf中的配置,默认回收info的日志级别
#log 127.0.0.1 local1 info
chroot /usr/share/haproxy ## 修改HAProxy的工作目录至指定的目录并在放弃权限之前执行
### chroot() 操作,可以提升 haproxy 的安全级别
group haproxy ## 同gid,不过这里为指定的用户组名
user haproxy ## 同uid,但这里使用的为用户名
daemon ## 设置haproxy后台守护进程形式运行
nbproc 1 ## 指定启动的haproxy进程个数,
### 只能用于守护进程模式的haproxy;默认为止启动1个进程,
### 一般只在单进程仅能打开少数文件描述符的场中中才使用多进程模式
maxconn 4096 ## 设定每个haproxy进程所接受的最大并发连接数,
### 其等同于命令行选项"-n","ulimit-n"自动计算的结果正式参照从参数设定的
# pidfile /var/run/haproxy.pid ## 进程文件(默认路径 /var/run/haproxy.pid)
node liuyazhuang135 ## 定义当前节点的名称,用于HA场景中多haproxy进程共享同一个IP地址时
description liuyazhuang135 ## 当前实例的描述信息
## defaults:用于为所有其他配置段提供默认参数,这默认配置参数可由下一个"defaults"所重新设定
defaults
log global ## 继承global中log的定义
mode http ## mode:所处理的模式 (tcp:四层 , http:七层 , health:状态检查,只会返回OK)
### tcp: 实例运行于纯tcp模式,在客户端和服务器端之间将建立一个全双工的连接,
#### 且不会对7层报文做任何类型的检查,此为默认模式
### http:实例运行于http模式,客户端请求在转发至后端服务器之前将被深度分析,
#### 所有不与RFC模式兼容的请求都会被拒绝
### health:实例运行于health模式,其对入站请求仅响应“OK”信息并关闭连接,
#### 且不会记录任何日志信息 ,此模式将用于相应外部组件的监控状态检测请求
option httplog
retries 3
option redispatch ## serverId对应的服务器挂掉后,强制定向到其他健康的服务器
maxconn 2000 ## 前端的最大并发连接数(默认为2000)
### 其不能用于backend区段,对于大型站点来说,可以尽可能提高此值以便让haproxy管理连接队列,
### 从而避免无法应答用户请求。当然,此最大值不能超过“global”段中的定义。
### 此外,需要留心的是,haproxy会为每个连接维持两个缓冲,每个缓存的大小为8KB,
### 再加上其他的数据,每个连接将大约占用17KB的RAM空间,这意味着经过适当优化后 ,
### 有着1GB的可用RAM空间时将维护40000-50000并发连接。
### 如果指定了一个过大值,极端场景中,其最终所占据的空间可能会超过当前主机的可用内存,
### 这可能会带来意想不到的结果,因此,将其设定一个可接受值放为明智绝对,其默认为2000
timeout connect 5000ms ## 连接超时(默认是毫秒,单位可以设置us,ms,s,m,h,d)
timeout client 50000ms ## 客户端超时
timeout server 50000ms ## 服务器超时
## HAProxy的状态信息统计页面
listen admin_stats
bind :48800 ## 绑定端口
stats uri /admin-status ##统计页面
stats auth admin:admin ## 设置统计页面认证的用户和密码,如果要设置多个,另起一行写入即可
mode http
option httplog ## 启用日志记录HTTP请求
## listen: 用于定义通过关联“前端”和“后端”一个完整的代理,通常只对TCP流量有用
listen mycat_servers
bind :3307 ## 绑定端口
mode tcp
option tcplog ## 记录TCP请求日志
option tcpka ## 是否允许向server和client发送keepalive
option httpchk OPTIONS * HTTP/1.1\r\nHost:\ www ## 后端服务状态检测
### 向后端服务器的48700端口(端口值在后端服务器上通过xinetd配置)发送 OPTIONS 请求
### (原理请参考HTTP协议) ,HAProxy会根据返回内容来判断后端服务是否可用.
### 2xx 和 3xx 的响应码表示健康状态,其他响应码或无响应表示服务器故障。
balance roundrobin ## 定义负载均衡算法,可用于"defaults"、"listen"和"backend"中,默认为轮询方式
server mycat_01 192.168.209.133:8066 check port 48700 inter 2000ms rise 2 fall 3 weight 10
server mycat_02 192.168.209.134:8066 check port 48700 inter 2000ms rise 2 fall 3 weight 10
## 格式:server [:[port]] [param*]
### serser 在后端声明一个server,只能用于listen和backend区段。
### 为此服务器指定的内部名称,其将会出现在日志及警告信息中
### 此服务器的IPv4地址,也支持使用可解析的主机名,但要在启动时需要解析主机名至响应的IPV4地址
### [:[port]]指定将客户端连接请求发往此服务器时的目标端口,此为可选项
### [param*]为此server设定的一系列参数,均为可选项,参数比较多,下面仅说明几个常用的参数:
#### weight:权重,默认为1,最大值为256,0表示不参与负载均衡
#### backup:设定为备用服务器,仅在负载均衡场景中的其他server均不可以启用此server
#### check:启动对此server执行监控状态检查,其可以借助于额外的其他参数完成更精细的设定
#### inter:设定监控状态检查的时间间隔,单位为毫秒,默认为2000,
##### 也可以使用fastinter和downinter来根据服务器端专题优化此事件延迟
#### rise:设置server从离线状态转换至正常状态需要检查的次数(不设置的情况下,默认值为2)
#### fall:设置server从正常状态转换至离线状态需要检查的次数(不设置的情况下,默认值为3)
#### cookie:为指定server设定cookie值,此处指定的值将会在请求入站时被检查,
##### 第一次为此值挑选的server将会被后续的请求所选中,其目的在于实现持久连接的功能
#### maxconn:指定此服务器接受的最大并发连接数,如果发往此服务器的连接数目高于此处指定的值,
#####其将被放置于请求队列,以等待其他连接被释放
注意:多节点部署时node 、 description的值要做相应调整。
部署haproxy负载均衡
Keepalived在这的主要用作mycat服务的健康状态检查以及Master主机和BackUP主机之间failover的实现,也就是故障自动切换功能。
1、普通实现方式:Keepalived+Haproxy+Xinetd
未实现原因:
如果不是docker部署,那么可以通过Keepalived+Haproxy+Xinetd负载均衡来监听mycat存活状态,实现多个mycat集群功能。
理论上MyCat服务主机上需要增加mycat服务的状态检测脚本,并开放相应的检测端口,以提供给HAProxy对MyCat的服务状态进行检测判断。可以使用xinetd来实现,通过xinetd,HAProxy可以用httpchk来检测MyCat的存活状态。
由于需要在mycat服务的主机上安装Xinetd来监听mycat服务状态,但是这里是通过镜像的方式来启动mycat的,xinetd无法监听到某个容器内部的mycat_status,所以无法实现。
2、docker实现方式:宿主机Keepalived+容器Keepalived+Haproxy
未实现原因:
由于需要在宿主机上安装Keepalived,所以如果Keepalived的宿主机挂了,那么整个Keepalived+HAProxy的负载均衡就失效了,所以还是无法实现集群的效果。
所以本文暂时没有实现,就不赘述了。