MySQL读写分离的概述
Mysql作为目前世界上使用最广泛的免费数据库,相信所有从事系统运维的工程师都一定接触过。但在实际的生产环境中,由单台Mysql作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面。
因此,一般来说都是通过 主从复制(Master-Slave)的方式来同步数据,再通过读写分离(MySQL-Proxy/Amoeba)来提升数据库的并发负载能力 这样的方案来进行部署与实施的。
读写分离工作原理:
基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
数据内部交换过程:
为什么要读写分离:
面对越来越大的访问压力,单台的服务器的性能成为瓶颈,需要分担负载
1、主从只负责各自的写和读,极大程度的缓解X锁和S锁争用
2、从库可配置myisam引擎,提升查询性能以及节约系统开销
3、增加冗余,提高可用性
实现读写分离的方式:
一般有两种方式实现
应用程序层实现,网站的程序实现
应用程序层实现指的是在应用程序内部及连接器中实现读写分离
优点:
A:应用程序内部实现读写分离,安装既可以使用
B:减少一定部署难度
C:访问压力在一定级别以下,性能很好
缺点:
A:架构一旦调整,代码要跟着变
B:难以实现高级应用,如自动分库,分表
C:无法适用大型应用场景
中间件层实现
中间件层实现是指在外部中间件程序实现读写分离
常见的中间件程序:
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
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品
环境
10.10.100.22主库
10.10.100.28从库
10.10.100.30mycat
在这主要写mycat中间件的搭建与配置,mysql的安装以及主从的配置就不重复的写了
mycat是java开发,所以需要安装jdk
Mycat 需要安装JDK 1.7 或者以上版本
第一步:下载
官网下载地址
https://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
jdk-8u131-linux-x64.tar.gz文件 http://haixi.sfkcn.com:8080/201704/tools/jdk-linux-x64.tar.gz
第二步:新建/usr/java文件夹,将jdk-8u131-linux-x64.tar.gz放到该文件夹中,并解压到当前目录下
第三步:配置环境变量 在/etc/profile底部加入如下内容:
JAVA_HOME=/usr/java/jdk1.8.0_131
PATH=$JAVA_HOME/bin:$PATH CLASSPATH=$JAVA_HOME/jre/lib/ext:$JAVA_HOME/lib/tools.jar
export PATH JAVA_HOME CLASSPATH
[root@localhost java]# source /etc/profile #使环境变量生效
查看版本
[root@localhost ~]#java –version
也可以用yuman安装
用yum安装JDK(CentOS)
查看yum库中都有哪些jdk版本
[root@localhost ~]# yum search java|grep jdk
选择版本,进行安装
[root@localhost ~]# yum -y install java-1.8.0-openjdk
安装完之后,默认的安装目录是在: /usr/lib/jvm/java-1.8.0/
设置环境变量
[root@localhost ~]# vim /etc/profile
添加如下内容:
#set java environment
JAVA_HOME=/usr/lib/jvm/java-1.8.0
JRE_HOME=$JAVA_HOME/jre
CLASS_PATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar:$JRE_HOME/lib
PATH=$PATH:$JAVA_HOME/bin:$JRE_HOME/bin
export JAVA_HOME JRE_HOME CLASS_PATH PATH
让修改生效
[root@localhost ~]# source /etc/profile
验证版本
[root@localhost ~]# java -version
openjdk version "1.8.0_232"
OpenJDK Runtime Environment (build 1.8.0_232-b09)
OpenJDK 64-Bit Server VM (build 25.232-b09, mixed mode)
服务安装与配置
下载
进入官网下载,可以根据需求选择版本
官方下载主页http://www.mycat.io
MyCAT有提供编译好的安装包,支持windows、Linux、Mac、Solaris等系统上安装与运行。
linux下可以下载Mycat-server-xxxxx.linux.tar.gz 解压在某个目录下,注意目录不能有空格,在Linux(Unix)下,建议放在usr/local/Mycat目录下,如下:
解压到指定目录
[root@localhost ~]# tar -zxvf Mycat-server-1.5.1-RELEASE-20161130213509-linux.tar.gz -C /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或者通过9066端口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的时候会提示找不到表的错误!
version.txt 是版本的信息
服务启动与启动设置
MyCAT在Linux中部署启动时,首先需要在Linux系统的环境变量中配置MYCAT_HOME,操作方式如下:
1)vim /etc/profile,在系统环境变量文件中增加
MYCAT_HOME=/usr/local/mycat PATH=
M
Y
C
A
T
H
O
M
E
/
b
i
n
:
MYCAT_HOME/bin:
MYCATHOME/bin:PATH
2) 执行 source /etc/profile 命令,使环境变量生效。
如果是在多台Linux系统中组建的MyCAT集群,那需要在MyCAT Server所在的服务器上配置对其他ip和主机名的映射,配置方式如下:
[root@localhost ~]#vim /etc/hosts
将集群的IP和主机名添加进去,编辑完后,保存文件
修改mycat的配置文件
mycat的用户账号和授权信息是在conf/server.xml文件中配置
修改配置文件之前先备份一下
[root@localhost conf]# cp -rp server.xml server.xml.bak
选项说明
-p 保持源文件属性
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mycat:server SYSTEM "server.dtd">
<mycat:server xmlns:mycat="http://org.opencloudb/">
<system>
<property name="defaultSqlParser">druidparser</property>
</system>
<user name="root"> #登录mycat的用户
<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:server>
编辑MyCAT的配置文件schema.xml,关于dataHost的配置信息如下
[root@localhost conf]# cp -p schema.xml schema.xml.bak
[root@localhost conf]# vim schema.xml
<?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="localhost.localdomain" url="10.10.100.22:3306" user="mycat" password="123456">
</writeHost>
<writeHost host="localhost.localdomain" url="10.10.100.28:3306" user="mycat" password="123456" />
</dataHost>
</mycat:schema>
注意:在主库和从库需要创建一个mycat用户
mysql> grant all on *.* to mycat@'10.10.100.30' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
有两个参数需要注意,balance和 switchType。
其中,balance指的负载均衡类型,目前的取值有4种:
- balance=“0”, 不开启读写分离机制,所有读操作都发送到当前可用的writeHost上。
- balance=“1”,全部的readHost与stand by writeHost参与select语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且M1与 M2互为主备),正常情况下,M2,S1,S2都参与select语句的负载均衡。
- balance=“2”,所有读操作都随机的在writeHost、readhost上分发。
- balance=“3”,所有读请求随机的分发到wiriterHost对应的readhost执行,writerHost不负担读压力
switchType指的是切换的模式,目前的取值也有4种: - switchType=’-1’ 表示不自动切换
- switchType=‘1’ 默认值,表示自动切换
- switchType=‘2’ 基于MySQL主从同步的状态决定是否切换,心跳语句为 show slave status
- switchType='3’基于MySQL galary cluster的切换机制(适合集群)(1.4.1),心跳语句为 show status like ‘wsrep%’。
经过以上两个步骤的配置,就可以到/usr/local/mycat/bin 目录下执行:
[root@localhost bin]# ./mycat start
启动查看日志
[root@localhost logs]# cat wrapper.log
STATUS | wrapper | 2019/10/26 03:11:10 | --> Wrapper Started as Daemon
STATUS | wrapper | 2019/10/26 03:11:10 | Launching a JVM...
INFO | jvm 1 | 2019/10/26 03:11:11 | OpenJDK 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0
INFO | jvm 1 | 2019/10/26 03:11:11 | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org
INFO | jvm 1 | 2019/10/26 03:11:11 | Copyright 1999-2006 Tanuki Software, Inc. All Rights Reserved.
INFO | jvm 1 | 2019/10/26 03:11:11 |
INFO | jvm 1 | 2019/10/26 03:11:11 | log4j 2019-10-26 03:11:11 [./conf/log4j.xml] load completed.
INFO | jvm 1 | 2019/10/26 03:11:12 | MyCAT Server startup successfully. see logs in logs/mycat.log
看到这个信息 MyCAT Server startup successfully. see logs in logs/mycat.log说明已经启动成功。
查看监听端口8066
修改mycat服务器的日志级别,调试模式
[root@localhost ~]# vim /usr/local/mycat/conf/log4j.xml
<root>
<level value="info" /> 修改前
<appender-ref ref="FILE" />
<!--<appender-ref ref="FILE" />-->
</root>
修改后
<root>
<level value="debug" />
<appender-ref ref="FILE" />
<!--<appender-ref ref="FILE" />-->
</root>
</log4j:configuration>
[root@localhost logs]# netstat -luntp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 6804/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 6891/master
tcp 0 0 127.0.0.1:32000 0.0.0.0:* LISTEN 14865/java
tcp6 0 0 :::9066 :::* LISTEN 14865/java
tcp6 0 0 :::39787 :::* LISTEN 14865/java
tcp6 0 0 :::22 :::* LISTEN 6804/sshd
tcp6 0 0 ::1:25 :::* LISTEN 6891/master
tcp6 0 0 :::1984 :::* LISTEN 14865/java
tcp6 0 0 :::8066 :::* LISTEN 14865/java
tcp6 0 0 :::40132 :::* LISTEN 14865/java
udp 0 0 0.0.0.0:68 0.0.0.0:* 6608/dhclient
udp 0 0 127.0.0.1:323 0.0.0.0:* 6275/chronyd
udp6 0 0 ::1:323 :::* 6275/chronyd
mycat 这台服务器需要安装mysql客服端
[root@localhost logs]# yum -y install mysql
登录mycat
[root@localhost bin]# mysql -uroot -p123456 -h10.10.100.30 -P8066
Welcome to the MariaDB 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, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MySQL [(none)]>
root是配置文件里面填写的root
ip写的是mycat服务器的IP
端口8066
登录上来就可以正常操作数据库
MySQL [(none)]> show databases;
+----------+
| DATABASE |
+----------+
| test |
+----------+
1 row in set (0.00 sec)
测试读写分离
写入数据查看macat的日志
查询数据再看看
读写分离已经实现
模拟从库挂掉看看
在从库执行
[root@localhost ~]# systemctl stop mysqld
当从服务器挂了的时候,不影响读的操作。mycat日志会一直报错拒绝连接
在模拟一个故障,当主库挂掉的时候会怎样?
先把主库停掉,再进行测试
[root@localhost ~]# systemctl stop mysqld
mycat就会马上报错
查询,可以正常查询
写条数据看看
当主库挂了,不影响查询的操作,就是不能对数据库进行写的操作。