mycat

什么是读写分离html

  在数据库集群架构中,让主库负责处理事务性查询,而从库只负责处理select查询,让二者分工明确达到提升数据库总体读写性能。固然,主数据库另一个功能就是负责将事务性查询致使的数据变动同步到从库中,也就是写操做。java

读写分离的好处mysql

  1)分摊服务器压力,提升机器的系统处理效率
    读写分离适用于读远比写的场景,若是有一台服务器,当select不少时,update和delete会被这些select访问中的数据堵塞,等待select结束,并发性能并不高,而主从只负责各自的写和读,极大程度的缓解X锁和S锁争用;
  假如咱们有1主3从,不考虑上述1中提到的从库单方面设置,假设如今1分钟内有10条写入,150条读取。那么,1主3从至关于共计40条写入,而读取总数没变,所以平均下来每台服务器承担了10条写入和50条读取(主库不承担读取操做)。所以,虽然写入没变,可是读取大大分摊了,提升了系统性能。另外,当读取被分摊后,又间接提升了写入的性能。因此,整体性能提升了,说白了就是拿机器和带宽换性能;
  2)增长冗余,提升服务可用性,当一台数据库服务器宕机后能够调整另一台从库以最快速度恢复服务linux

Mycat原理
  Mycat是一个开源的分布式数据库系统,可是由于数据库通常都有本身的数据库引擎,而Mycat并无属于本身的独有数据库引擎,全部严格意义上说并不能算是一个完整的数据库系统,只能说是一个在应用和数据库之间起桥梁做用的中间件。git

在Mycat中间件出现以前,MySQL主从复制集群,若是要实现读写分离,通常是在程序段实现,这样就带来了一个问题,即数据段和程序的耦合度过高,若是数据库的地址发生了改变,那么个人程序也要进行相应的修改,若是数据库不当心挂掉了,则同时也意味着程序的不可用,而对于不少应用来讲,并不能接受;github

引入Mycat中间件能很好地对程序和数据库进行解耦,这样,程序只需关注数据库中间件的地址,而无需知晓底层数据库是如何提供服务的,大量的通用数据聚合、事务、数据源切换等工做都由中间件来处理;
Mycat中间件的原理是对数据进行分片处理,从原有的一个库,被切分为多个分片数据库,全部的分片数据库集群构成完成的数据库存储,有点相似磁盘阵列中的RAID0.web

Mycat配置安装sql

环境准备:保证多实例/data/3306/和/data/3307已经实现简单异步主从复制
1)安装JDK
http://www.oracle.com/technetwork/java/javase/downloads/jdk7-downloads-1880260.html  
#注意版本必须JDK7或者更高版本数据库

[root@db02 tools]# rpm -ivh jdk-8u91-linux-x64.rpm  
Preparing...                ########################################### [100%] 
  1:jdk1.8.0_91            ########################################### [100%] 
#我这里下载的rpm包,安装比较方便vim

2)下载Mycat
https://github.com/MyCATApache/Mycat-download
# 这里测试用的是Mycat-server-1.4-release版本 
解压拷贝到/application/mycat目录

3)建立用户
主库,web用户有增删改查权限
mysql> grant select,update,delete,insert on lilongzi.* to web@'172.16.2.%' identified 
by'123456';

从库因为只负责读数据,全部web只有select权限
mysql> grant select on lilongzi.* to web@'172.16.2.%' identified by '123456';

4)修改配置文件

[root@db02 conf]# vim /application/mycat/conf/server.xml #MyCAT对外的“虚拟数据库”配置文件 
s">32</property> --> 
        </system> 
        <user name="web"> #web为主库和分库刚创建的用户 
                <property name="password">123456</property> #用户密码 
                <property name="schemas">lilongzi</property> #数据库名称 
        </user> 
        <user name="web_r"> #web_r表示只给读权限 
                <property name="password">123456</property> 
                <property name="schemas">lilongzi</property> 
                <property name="readOnly">true</property> 
        </user>

[root@db02 conf]# vim /application/mycat/conf/server.xml #详细主库及读写分离模式配置文件 
        <schema name="lilongzi" checkSQLschema="false" sqlMaxLimit="100" 
        dataNode="dn1"> 
        #name=你的数据库名 ,添加dataNode="dn1" 表示数据库只在dn1上,没有分库 
        <table name="test" primaryKey="ID" type="global" dataNode="dn1,dn2,dn3" /> 
        #table修改成你的表名,若是有多张表,能够按照这个格式添加 
      </schema> 
        <!-- <dataNode name="dn1$0-743" dataHost="localhost1" database="db$0-743" 
                /> --> 
        <dataNode name="dn1" dataHost="localhost1" database="lilongzi" /> 
        <dataNode name="dn2" dataHost="localhost1" database="lilongzi" /> 
        <dataNode name="dn3" dataHost="localhost1" database="lilongzi" /> 
        <dataHost name="localhost1" maxCon="1000" minCon="10" balance="1"
                writeType="0" dbType="mysql" dbDriver="native" switchType="1"
                slaveThreshold="100"> 
                <heartbeat>select user()</heartbeat> 
                <!-- can have multi write hosts --> 
                <writeHost host="hostM1" url="172.16.2.10:3306" user="web"
                        password="123456"> 
                        <!-- can have multi read hosts --> 
                <readHost host="hostS1" url="172.16.2.10:3307" user="web"
                        password="123456" /> 
                </writeHost> 
                <!-- <writeHost host="hostM2" url="localhost:3316" user="root"
                password="123456"/> --> 
        </dataHost>

这里面,有两个参数须要注意,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不负担读压力
writeType表示写模式
writeType="0",全部的操做发送到配置的第一个writehost
writeType="1",随机发送到配置的全部writehost
writeType="2",不执行写操做
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%'。

5)启动Mycat
[root@db02 bin]# ./mycat console & 
Running Mycat-server... 
wrapper  | --> Wrapper Started as Console 
wrapper  | Launching a JVM... 
jvm 1    | Java HotSpot(TM) 64-Bit Server VM warning: ignoring option MaxPermSize=64M; support was removed in 8.0 
jvm 1    | Wrapper (Version 3.2.3) http://wrapper.tanukisoftware.org 
jvm 1    |  Copyright 1999-2006 Tanuki Software, Inc.  All Rights Reserved. 
jvm 1    |  
jvm 1    | log4j 2016-07-09 06:04:28 [./conf/log4j.xml] load completed. 
jvm 1    | MyCAT Server startup successfully. see logs in logs/mycat.log 
[root@db02 bin]# lsof -i:{8066,9066} 
COMMAND  PID USER  FD  TYPE DEVICE SIZE/OFF NODE NAME 
java    87340 root  46u  IPv6 212352      0t0  TCP *:9066 (LISTEN) #虚拟schema管理端口 
java    87340 root  50u  IPv6 212354      0t0  TCP *:8066 (LISTEN) #虚拟schema登录端口 
#能看到这个说明我们的Mycat已经启动成功了

6)接下来咱们就要验证一下否真的已经实现读写分离...
方法:
停掉从库的SQL线程,让从库虽然读取到了主库的binlog,可是不能发起SQL线程写入到本身的数据库中,这样咱们模拟访问,插入一条数据,在主库中应该能看到新插入的数据,可是模拟访问的客户端却看不到,就说明读写分离成功。
咱们在其余主机A上模拟web用户访问登录查看数据
[root@m01 ~]# mysql -uweb -p123456 -h172.16.2.10 -P8066 #注意这里使用虚拟schema的登录端口8066 
mysql> show databases; 
+----------+ 
| DATABASE | 
+----------+ 
| lilongzi | 
+----------+ 
1 row in set (0.00 sec) 
mysql> use lilongzi; 
Database changed 
mysql> show tables; 
+--------------------+ 
| Tables in lilongzi | 
+--------------------+ 
| customer          | 
| customer_addr      | 
| employee          | 
| goods              | 
| hotnews            | 
| orders            | 
| order_items        | 
| test              | #test为咱们改过的表 
| travelrecord      | 
+--------------------+ 
9 rows in set (0.00 sec) 
mysql> select * from test; 
+----+--------+ 
| id | name  | 
+----+--------+ 
|  1 | 小明  | 
+----+--------+ 
1 row in set (0.00 sec)

咱们停掉从库3307的SQL线程
mysql> stop slave sql_thread; 
Query OK, 0 rows affected (0.00 sec)

在主机A远程插入一条数据test
mysql> insert into test values(2,'test2'); 
ERROR 1105 (HY000): Duplicate entry '2' for key 'PRIMARY'
mysql> select * from test; 
+----+--------+ 
| id | name  | 
+----+--------+ 
|  1 | 小明  | #立马查一下发现是看不到的 
+----+--------+ 
1 row in set (0.01 sec)

可是在主库上面
mysql> select * from test; 
+----+--------+ 
| id | name  | 
+----+--------+ 
|  1 | 小明  | 
|  2 | test2  | #显示已经写入成功 
+----+--------+ 
2 rows in set (0.00 sec)

从库这边
mysql> select * from test; 
+----+--------+ 
| id | name  | 
+----+--------+ 
|  1 | 小明  | #一样看不到 
+----+--------+ 
1 row in set (0.00 sec)

MyCAT实现MySQL读写分离实践  http://www.linuxidc.com/Linux/2016-01/127957.htm

MyCAT实现MySQL的读写分离  http://www.linuxidc.com/Linux/2016-01/127555.htm

MyCAT ER分片的验证 http://www.linuxidc.com/Linux/2016-02/128636.htm

LVS+Keepalived搭建MyCAT高可用负载均衡集群 http://www.linuxidc.com/Linux/2016-03/129231.htm

本文永久更新连接地址http://www.linuxidc.com/Linux/2016-07/133518.htm

相关文章
相关标签/搜索