MySQL-mycat读写分离
指尖二进制 • 1 年前 • 863 次点击 • MYSQL
mysql读写分离的概述
Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过。但在实际的生产环境中,由单台Mysql作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面。
因此,一般来说都是通过 主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy/Amoeba)来提升数据库的并发负载能力,这样的方案来进行部署与实施的。
读写分离工作原理:
基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
数据内部交换过程:
数据库集群,如果slave-1查询过多,后面进来的连接全自动切换slave-2,以此类推。
为什么要读写分离:
面对越来越大的访问压力,单台的服务器的性能成为瓶颈,需要分担负载
1:主从只负责各自的写和读,极大程度的缓解X锁和S锁争用
2:从库可配置myisam引擎,提升查询性能以及节约系统开销
3:增加冗余,提高可用性
实现读写分离一般有两种方式实现
应用程序层实现,网站的程序实现
应用程序层实现指的是在应用程序内部及连接器中实现读写分离,直接在app里面写死。没运维什么事儿了。
优点:
A:应用程序内部实现读写分离,安装既可以使用
B:减少一定部署难度
C:访问压力在一定级别以下,性能很好
缺点:
A:架构一旦调整,代码要跟着变
B:难以实现高级应用,如自动分库,分表
C:无法适用大型应用场景
D:扩容架构需要修改代码
E:无法实现自动分库分表
中间件层实现
中间件层实现是指在外部中间件程序实现读写分离
常见的中间件程序:
Cobar:
阿里巴巴B2B开发的关系型分布式系统,管理将近3000个MySQL实例。在阿里经受住了考验,后面由于作者的走开的原因cobar没有人维护了,阿里也开发了tddl替代cobar。
MyCAT:
社区爱好者在阿里cobar基础上进行二次开发,解决了cobar当时存在的一些问题,并且加入了许多新的功能在其中。目前MyCAT社区活跃度很高,目前已经有一些公司在使用MyCAT。总体来说支持度比较高,也会一直维护下去。
OneProxy:
数据库界大牛,前支付宝数据库团队领导楼总开发,基于mysql官方的proxy思想利用c进行开发的,OneProxy是一款商业收费的中间件,楼总舍去了一些功能点,专注在性能和稳定性上。有朋友测试过说在高并发下很稳定。但是收费。
Vitess:
这个中间件是Youtube生产在使用的,但是架构很复杂。与以往中间件不同,使用Vitess应用改动比较大,要使用他提供语言的API接口,我们可以借鉴他其中的一些设计思想。
Kingshard:
Kingshard是前360Atlas中间件开发团队的陈菲利用业务时间用go语言开发的,目前参与开发的人员有3个左右,目前来看还不是成熟可以使用的产品,需要在不断完善。
Atlas:
360团队基于mysql proxy把lua用C改写。原有版本是支持分表,目前已经放出了分库分表版本。在网上看到一些朋友经常说在高并发下会经常挂掉,如果大家要使用需要提前做好测试。
MaxScale与MySQL Route:
这两个中间件都算是官方的吧,MaxScale是mariadb(MySQL原作者维护的一个版本)研发的,目前版本不支持分库分表。MySQL Route是现在MySQL官方Oracle公司发布出来的一个中间件。
优点:
A:架构设计更灵活
B:可以在程序上实现一些高级控制,如:透明化水平拆分,failover(故障切换),监控
C:可以依靠些技术手段提高mysql性能。
D:对业务代码的影响小,同时也安全。
缺点:
需要一定的开发运维团队的支持,(对于个人运维来说是优点,运维人员得上班,需要挣钱养家啊。)
什么是MYCAT?
•一个彻底开源的,面向企业应用开发的大数据库集群
•支持事务、ACID、可以替代MySQL的加强版数据库
•一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
•一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
•结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
•一个新颖的数据库中间件产品
前端连接macat,直接操作。
服务安装与配置:
MyCAT有提供编译好的安装包,支持windows、Linux、Mac、Solaris等系统上安装与运行。官方下载主页http://www.mycat.io
linux下可以下载Mycat-server-xxxxx.linux.tar.gz 解压在某个目录下,注意目录不能有空格,在Linux(Unix)下,建议放在usr/local/Mycat目录下。
目录解释如下:
bin 程序目录,存放了window版本和linux版本,除了提供封装成服务的版本之外,也提供了nowrap的shell脚本命令,方便选择和修改,进入到bin目录:
Linux下运行:./mycat console,首先要chmod +x *
注:mycat支持的命令{ console | start | stop | restart | status | dump }
conf目录下存放配置文件,server.xml是Mycat服务器参数调整和用户授权的配置文件,schema.xml是逻辑库定义和表以及分片定义的配置文件,rule.xml是分片规则的配置文件,分片规则的具体一些参数信息单独存放为文件,也在这个目录下,配置文件修改,需要重启Mycat或者通过8066端口reload.
lib目录下主要存放mycat依赖的一些jar文件。
日志存放在logs/mycat.log中,每天一个文件,日志的配置是在conf/log4j.xml中,根据自己的需要,可以调整输出级别为debug,debug级别下,会输出更多的信息,方便排查问题。
注意:Linux下部署安装MySQL,默认不忽略表名大小写,需要手动到/etc/my.cnf 下配置 lower_case_table_names=1 使Linux环境下MySQL忽略表名大小写,否则使用MyCAT的时候会提示找不到表的错误!
实验环境:
主机名 | IP | 系统/MySQL版本 | 角色 |
---|---|---|---|
jz_130 | 192.168.111.130 | CentOS7.4/5.7.24 | client |
jz_131 | 192.168.111.131 | CentOS7.4/5.7.24 | mycat |
jz_132 | 192.168.111.132 | CentOS7.4/5.7.24 | masterx写 |
jz_133 | 192.168.111.133 | CentOS7.4/5.7.24 | slave读 |
[root@jz_131 ~]# tar fx Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz -C /usr/local/
[root@jz_131 ~]# ls /usr/local/mycat/ -lh
total 12K
drwxr-xr-x. 2 root root 190 Dec 4 03:09 bin
drwxrwxrwx. 2 root root 6 Dec 13 2015 catlet
drwxrwxrwx. 2 root root 4.0K Dec 4 03:09 conf
drwxr-xr-x. 2 root root 4.0K Dec 4 03:09 lib
drwxrwxrwx. 2 root root 6 Dec 13 2015 logs
-rwxrwxrwx. 1 root root 219 Nov 30 2016 version.txt
安装java环境。首先卸载
[root@jz_131 ~]# rpm -qa | grep jdk
[root@jz_131 ~]# rpm -e --nodeps 查询出来回显的全名
[root@jz_131 ~]# mkdir -p /usr/java
[root@jz_131 ~]# tar fx java-jdk-8u152-linux-x64.tar.gz -C /usr/java/
配置java环境变量个mycat环境变量
[root@jz_131 ~]# vim /etc/profile
#set java environment
JAVA_HOME=/usr/java/jdk1.8.0_152
CLASSPATH=$JAVA_HOME/lib/
PATH=$PATH:$JAVA_HOME/bin
export PATH JAVA_HOME CLASSPATH
#MyCAT在Linux中部署启动时,首先需要在Linux系统的环境变量中配置MYCAT_HOME。加入到环境变量。
MYCAT_HOME=/usr/local/mycat PATH=$MYCAT_HOME/bin:$PATH
刷新环境变量生效并查看
[root@jz_131 ~]# source /etc/profile
[root@jz_131 ~]# java -version
java version "1.8.0_152"
Java(TM) SE Runtime Environment (build 1.8.0_152-b16)
Java HotSpot(TM) 64-Bit Server VM (build 25.152-b16, mixed mode)
[root@jz_131 ~]# mycat
Usage: /usr/local/mycat/bin/mycat { console | start | stop | restart | status | dump }
如果是在多台Linux系统中组建的MyCAT集群,那需要在MyCAT Server所在的服务器上配置对其他ip和主机名的映射,配置方式如下:
vim /etc/hosts
192.168.111.130 jz_130
192.168.111.131 jz_131
192.168.111.132 jz_132
192.168.111.133 jz_133
配置mycat(mycat的用户账号和授权信息是在conf/server.xml文件中配置
[root@jz_131 ~]# cd /usr/local/mycat/conf/
[root@jz_131 conf]# ls
[root@jz_131 conf]# vim server.xml
<!--配置文件里面的账号密码是给前端的,告诉前端能用那些账号连接数据库。也就是图上的mysql-cilent。-->
<!--此处需要注意的是:是在34行到43行修改文件。(千万不要全部删除替换)-->
</system>
<user name="root">
<property name="password">123456</property>
<property name="schemas">test</property>
</user>
<user name="user">
<property name="password">user</property>
<property name="schemas">test</property>
<property name="readOnly">true</property>
</user>
编辑MyCAT的配置文件schema.xml,关于dataHost的配置信息如下:
[root@jz_131 conf]# cp schema.xml schema.xml.bak
[root@jz_131 conf]# >schema.xml
[root@jz_131 conf]# vim schema.xml
<!--配置文件里面的账号密码是什么意思?-->
<!--是mycat这台服务器去操作数据库用到的账号,这个账号必须在数据库创建好。-->
<?xml version="1.0"?>
<!DOCTYPE mycat:schema SYSTEM "schema.dtd">
<mycat:schema xmlns:mycat="http://org.opencloudb/">
<schema name="test" checkSQLschema="false" sqlMaxLimit="100" dataNode='dn1'>
</schema>
<dataNode name="dn1" dataHost="dthost" database="test"/>
<dataHost name="dthost" maxCon="500" minCon="10" balance="1" writeType="0" dbType="mysql" dbDriver="native" switchType="-1" slaveThreshold="100">
<heartbeat>select user()</heartbeat>
<writeHost host="jz_132" url="192.168.111.132:3306" user="mycat" password="123456">
</writeHost>
<writeHost host="jz_133" url="192.168.111.133:3306" user="mycat" password="123456" />
</dataHost>
</mycat:schema>
有两个参数需要注意,balance和 switchType。
其中,balance指的负载均衡类型,目前的取值有4种:
1:balance="0" :不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
2:balance="1" :全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
3:balance="2" :所有读操作都随机的在writeHost、readhost上分发。
4:balance="3" :所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力
switchType指的是切换的模式,目前的取值也有4种
1:switchType='-1' :表示不自动切换
2:switchType='1' :默认值,表示自动切换
3:switchType='2' :基于MySQL主从同步的状态决定是否切换,心跳语句为 show slave status
4:switchType='3' :基于MySQL galary cluster的切换机制(适合集群)(1.4.1),心跳语句为 show status like 'wsrep%'。
在主从两台服务器都创建mycat账号。用于mycat服务器登录数据库使用。
[root@jz_132、jz_132 ~]# mysql -uroot -p123456
mysql> grant all on *.* to mycat@'192.168.111.131' identified by '123456';
mysql> flush privileges;
经过以上两个步骤的配置就可以启动mycat
[root@jz_131 conf]# mycat start
Starting Mycat-server...
查看启动日志(当看到MyCAT Server startup successfully.为成功)
[root@jz_131 conf]# cat /usr/local/mycat/logs/wrapper.log
STATUS | wrapper | 2018/12/04 03:46:00 | --> Wrapper Started as Daemon
STATUS | wrapper | 2018/12/04 03:46:00 | Launching a JVM...
INFO | jvm 1 | 2018/12/04 03:46:00 | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
INFO | jvm 1 | 2018/12/04 03:46:01 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO | jvm 1 | 2018/12/04 03:46:01 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
INFO | jvm 1 | 2018/12/04 03:46:01 |
INFO | jvm 1 | 2018/12/04 03:46:02 | log4j 2018-12-04 03:46:02 [./conf/log4j.xml] load completed.
INFO | jvm 1 | 2018/12/04 03:46:02 | MyCAT Server startup successfully. see logs in logs/mycat.log
查看监听端口(mycat端口8066)
[root@jz_131 conf]# netstat -antlp|grep 8066
tcp6 0 0 :::8066 :::* LISTEN 8524/java
在mysql-client测试(登录mycat) #注意第四行回显。为mycat-1.5.1。
[root@jz_130 ~]# mysql -uroot -p123456 -h 192.168.111.131 -P8066
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.8-mycat-1.5.1-RELEASE-20161130213509 MyCat Server (OpenCloundDB)
Copyright (c) 2000, 2018, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> show databases;
+----------+
| DATABASE |
+----------+
| test |
+----------+
1 row in set (0.01 sec)
mysql> use test
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select * from emp;
+-------+-------+----------+------+---------------------+---------+--------+--------+
| empno | ename | job | mgr | hiredate | sal | comm | deptno |
+-------+-------+----------+------+---------------------+---------+--------+--------+
| 7369 | SMITH | CLERK | 7902 | 1980-12-17 00:00:00 | 800.00 | NULL | 20 |
| 7499 | ALLEN | SALESMAN | 7698 | 1981-02-20 00:00:00 | 1600.00 | 300.00 | 30 |
+-------+-------+----------+------+---------------------+---------+--------+--------+
2 rows in set (0.00 sec)
在mycat服务器修改日志输出模式。(测试读写是否分离)
[root@jz_131 ~]# vim /usr/local/mycat/conf/log4j.xml
37行info修改成debug模式
<level value="info" /> <level value="debug" />
debug是调试模式
客户端进行写入或者查询数据
实时监测mycat日志进行测试读写分离
[root@jz_131 ~]# tail -f /usr/local/mycat/logs/mycat.log
测试查询是否为192.168.111.133 mysql-slave-server服务器
测试查询是否为192.168.111.132 mysql-master-server服务器