Mysql读写分离是为了提高网站的访问速度,提高数据库的并发负载能力。
但在实际的生产环境中,由单台Mysql作为独立的数据库是完全不能满足实际需求的,无论是在安全性,高可用性以及高并发等各个方面。
因此,一般来说都是通过 主从复制(Master-Slave)的方式来同步数据,再通过读写分离来提升数据库的并发负载能力, 这样的方案来进行部署与实施的。
先做主从复制,再做读写分离。
MySQL主从复制结构是基于mysql bin-log日志基础上,从库通过打开IO进程收到主库的bin-log日志增量信息,并保存到本地relay log,而后再通过打开MYSQL进程从relay log上获取的增量信息并翻译成SQL语句后写到从数据库。
先在主服务器和从服务器分别安装mysql,最简单的就是用yum安装:
yum -y install mysql mysql-server
service mysqld start
可以给mysql的root用户改一个密码,默认为空。
mysqladmin -u root -p password 123456 (#设置root密码)
敲完上面命令会出现enter password: 这里应该直接敲回车,应为mysql默认密码为空。
然后登陆:mysql -u root –p123456
现在mysql的root 用户的密码已经改为123456了。
主数据库服务器:192.168.28.185,MySQL已经安装,并且无应用数据。
从数据库服务器:192.168.28.123,MySQL已经安装,并且无应用数据。
先配置主服务器
修改主数据库的配置文件,即/etc/my.cnf,开启二进制日志并修改server_id。然后重启mysqld。
修改完之后可以用这个命令查看一下是否修改 grep -E "server_id|log_bin" /etc/my.cnf (这一步不用写,建议养成这个习惯)
MySQL复制基于主服务器在二进制日志中跟踪所有对数据库的更改(更新、删除等等)。因此,要进行复制,必须在主服务器上启用二进制日志。
然后登陆主数据库进行操作:
- mysql -uroot –p123456
- 可以查看此时登录账号 select user(); (这一步不用写)
- mysql>grant replication slave on *.* to 'zxq'@'192.168.28.123' identified by 'zxqzxq';
(在master上为slave添加同步帐号并授权)
说明: *.* 为所有的库和所有的表,可以自己定义某一个库里的某一个表。
授权之后可以在slave用授权用户登录验证 mysql -u zxq -h 192.168.28.185 -pzxqzxq
4 mysql>flush privileges; (使授权命令生效)
检查刚才创建的用户 select user,host from mysql.user;(这步不用写,建议养成这个习惯)
还可以加password : select user, host, password from mysql.user;
也可以查看权限 : show grants for 'zxq'@'192.168.28.123'; 下图显示与刚才操作的无误,并且密码加密了。(这一步也可不用写)
主从开始工作需要保证这两台服务器数据库信息一致 ,需要将master的数据库表全部备份导出,并传送到slave服务器上。有时还需要进行锁表只读的操作。但是因为我是刚创建的数据库,里面什么都没有,也就是说信息一样了。所以这一步就不用做了。
(2)查询主数据库的状态
1 mysql> show master status;
记下File以及Position的值,在后面进行从服务器操作的时候需要使用。
现在配置从服务器
(1)修改从服务器的配置文件/etc/my.cnf
修改server_id,并关闭bin_log日志。从库默认不开启bin-log日志功能,除非做下级从库级联同步,才需开启从库的bin-log日志。我修改的从数据库的“server-id=2”不能和主数据库的id一样。
从数据库配置文件里如果不写下面这两行则会复制主数据库账号信息,下面这两个库是专门存放mysql的系统账户的信息,。
binlog-ignore-db=mysql
binlog-ignore-db=information_schema (忽略mysql系统库复制)
从数据库里的中继日志是默认开启的,不需要单独添加。
mysql从库中需在my.cnf配置文件中加入 read-only参数,保证从库只读。
(2)启动mysql服务 并登陆到mysql
现在配置从服务器slave
mysql> change master to master_host='192.168.28.185',master_user='zxq',master_password='zxqzxq',master_log_file='mysql-bin.000002',master_log_pos=98;
然后开启slave,用命令start slave;
检查从服务器复制功能状态: show slave status\G (其实不加\G也行,只不过加上了容易观看,直观。如果不加的话后面要加一个分号。)
Slave_IO_Running 和 slave_sql_Running 必须都是Yes . 有一个是NO都不行,这两个线程非常重要。IO线程负责接收读写主服务器发来的二进制日志,将该数据拷贝到从服务器数据目录中的本地文件中,即中继日志。而sql线程是从服务器创建用于读取中继日志并执行日志中包含的更新。
(如果出错有可能是防火墙的问题,把防火墙关掉还出错就去查看日志,看看日志里报的什么错。日志位置在/etc/my.cnf里有写。如果/etc/my.cnf配置文件里没有日志路径就用命令 find / -name 主机名.err 查。
主从服务器测试:
先看一下主从服务器里面有什么数据库,是否一样。
主:
从:
现在主从数据库里信息一样。然后在主数据库上创建一个库,
mysql> create database zhangxiaoqiang;
先在主数据库上查看一下:
然后在从数据库看一下
到这里,主从复制就做完了,两个数据库的数据同步了。接下来就做读写分离。
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
读写分离
(amoeba是根据存储引擎来定义是否支持事务的,现在新版本的存储引擎默认应该都是innodb,都是支持事物的,如果你的是5.5以前的版本可能默认是MyISAM,把它改成innodb就行了,vi /etc/my.cnf 然后添加:default-storage-engine=INNODB可以参考这个文档 http://blog.youkuaiyun.com/iamduoluo/article/details/7847448 )
我这次用amoeba 做 的读写分离。
Master :192.168.28.185
Slave :192.168.28.123
Amoeba:192.168.28.95
一: 先安装jdk环境, Amoeba 框架是基于JDK1.5开发的,采用了JDK1.5的特性
(JDK现在是一个开源、免费的工具。JDK是其它Java开发工具的基础,也就是说,在安装其它开发工具以前,必须首先安装JDK)
1:先查看服务器自带的jdk版本号( java -version ),
再查看java信息,(卸载jdk用)用命令 rpm -qa | grep java
现在卸载java文件 (其实就是卸载自带的jdk)
yum -y remove java-1.6.0-openjdk-1.6.0.0-1.7.b09.el5
yum -y remove java-1.4.2-gcj-compat-1.4.2.0-40jpp.115
2:现在安装自己所需的jdk。
前提是已经准备好自己要安装的jdk,我在网上下载好了。 我下载的是: jdk-6u15-linux-i586-rpm.bin
先创建/usr/java文件夹,将刚才下载的jdk拷贝这个目录下
然后赋予jdk文件权限
chmod 755 jdk-6u15-linux-i586-rpm.bin
然后安装jdk
./ jdk-6u15-linux-i586-rpm.bin
然后配置环境变量。
vi /etc/profile
在配置文件的最后面加下面2条语句。
export JAVA_HOME=/usr/java/jdk1.6.0_15
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
reboot重启使配置生效,或者使用source /etc/profile也可以是配置生效。
现在再看一下java信息。
到此,jdk环境就安装完了,现在开始安装amoeba
二: 配置amoeba
1:首先还是先到网上下载amoeba,我事先已经下载好了。
创建amoeba文件夹,并且把下载好的压缩包解压到该文件夹里。
mkdir /usr/local/amoeba
tar -xzvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
解压之后可以验证amoeba能否开启成功:/usr/local/amoeba/bin/amoeba start ( 我是进入到那个目录里开启的)
:2:参数配置
cd /usr/local/amoeba/conf/
Amoeba.xml:主配置文件,配置数据源和amoeba的自身参数
dbServer.xml:需要至少配置一个dbServer,每个dbServer将是物理数据库Server的衍射
log4j.xml:日志文件
rule.xml:配置所有Query路由规则的信息
functionMap.xml:配置用于解析Query中的函数所对应的Java实现类
rullFunctionMap.xml:配置路由规则中需要使用到的特定函数的实现类
这里我们通过修改amoeba.xml和dbServer.xml来实现读写分离,修改log4j.xml来节约服务器资源。
3:修改dbServer.xml
修改 amoeba.xml
注意<!-- -->表示的是注释<>里面的信息。我们用到哪个就要把哪个注释去掉。
上图中我在readpool那里写一个虚拟节点virtualSlave,这个是在前面的dbServer里我定义的。因为我要让主从都可以读,如果你只让从库读的话就不用定义这个了,还有就是有多个slave的时候也可以定义这个。
配置完成之后开启amoeba ,并检查是否成功开启。下图显示成功开启。
特别注意,现在要在主从数据库上分别给amoeba授权一个用户,和之前master给slave授权的意思一样。
grant all privileges on *.* to 'root'@'192.168.28.95' identified by '123456' with grant option;
flush privileges; (使授权命令生效)
特别注意:上面授权的用户是从amoeba上链接主从数据库的用户,也就是dbServer里设置的用户,而amoeba.xml里面的用户只是用来链接amoeba数据库的。
(授权之后可以在amoeba上分别验证mysql -uroot -p123456 -h192.168.28.185 和mysql -uroot -p123456 -h192.168.28.123 ,登陆amoeba上的数据库则是 mysql -uzhangxq -pzhangxq -h192.168.28.95 -P8066 ,这个必须开启amoeba才可以连接)
三:测试读写分离。
测试思路: 先把主从复制停掉,使命令用mysql -uzhangxq -pzhangxq -h192.168.28.95 -P8066 登录到amoeba上,然后执行写和读操作,查看写的是哪台服务器,读的是哪台服务器,实验结果显示:写只在主上进行,读在主和从都进行。
测试步骤:
没有停掉从同步之前,在主数据库上test库里创建一个表:
create table zhang (id int(10) ,name varchar(10),address varchar(20));
那么从数据库也会复制这个表,现在到从上执行stop slave; 停止主从复制。
然后在主从上各插入一条不同数据(供测试读的时候用)。
在主上插入:insert into zhang values('1','zhang','this_is_master');
在从上插入:insert into zhang values('2','zhang','this_is_slave');
接下来通过登录amoeba-mysql上来测试读写 :
mysql -uzhangxq -pzhangxq -h192.168.28.95 -P8066
(因为前面dbServer 里面我设置的是主从都可以读,选择的轮询方法,比例是1:1,并且只有主库可以执行写操作,从库不可以。)
现在在amoeba上面插入数据,然后再查询,发现只在主数据库上出现了写的操作。
上图中写操作只在主库中有,从库没有写操作。
还可以利用下图的工具测试,和上面的道理一样,就不演示了。
到底为止,amoeba读写分离就完成了。
简单主从权重配置:
前面我有提到过,我的读操作的比例是1:1,而写操作又全部在主上进行,这样主的压力就很大了,所以如果能让主和从的读操作设置权重,比如设置成1:3, 这样就可以很好的缓解主数据库的压力问题!
配置就是将上面的读的池的配置更改一下:
将<property name="poolNames">master,slave</property>
更改成
<property name="poolNames">master,slave,slave,slave</property>
这样做就可以给主数据库服务器减压了!
mysql+mycat实现数据库分片(分库分表)
什么是MYCAT:
一个彻底开源的,面向企业应用开发的大数据库集群
支持事务、ACID、可以替代MySQL的加强版数据库
一个可以视为MySQL集群的企业级数据库,用来替代昂贵的Oracle集群
一个融合内存缓存技术、NoSQL技术、HDFS大数据的新型SQL Server
结合传统数据库和新型分布式数据仓库的新一代企业级数据库产品
一个新颖的数据库中间件产品