您的位置:首页 > 运维架构 > Linux

mysql读写分离的完整配置【centos6.5-mini版操作系统中mysql数据库的操作日志以及创建的数据库和表均在/var/lib/mysql此目录下,yum源在/var/lib/yum下】

2015-07-30 12:23 1076 查看
参考文章:

文章一【仅供参考】:

构建高性能web之路------mysql读写分离实战【按照里面配置主从mysql同步失败,并且按照他的my.cnf配置,给我的虚拟机搞坏了,重新弄了一个】
http://blog.csdn.net/cutesource/article/details/5710645
文章二【仅供参考,主要参考这个】:

mysql主从配置,实现读写分离【他这个是把主mysql中的所有数据库都要进行同步】
http://www.cnblogs.com/alvin_xp/p/4162249.html
---------------------------------------------------------------------一[b]一、搭建mysql的master-slave环境[/b]---------------------------------------------------------------------

大型网站为了软解大量的并发访问,除了在网站实现分布式负载均衡,远远不够。到了数据业务层、数据访问层,如果还是传统的数据结构,或者只是单单靠一台服务器扛,如此多的数据库连接操作,数据库必然会崩溃,数据丢失的话,后果更是 不堪设想。这时候,我们会考虑如何减少数据库的联接,一方面采用优秀的代码框架,进行代码的优化,采用优秀的数据缓存技术如:memcached,如果资金丰厚的话,必然会想到假设服务器群,来分担主数据库的压力。Ok切入今天微博主题,利用MySQL主从配置,实现读写分离,减轻数据库压力。这种方式,在如今很多网站里都有使用,也不是什么新鲜事情,今天总结一下,方便大家学习参考一下。

【以下内容参考此文章:http://blog.csdn.net/cutesource/article/details/5710645】

一个完整的mysql读写分离环境包括以下几个部分:

应用程序client
database proxy
database集群

在本次实战中,应用程序client基于c3p0连接后端的database proxy。database proxy负责管理client实际访问database的路由策略,采用开源框架amoeba。database集群采用mysql的master-slave的replication方案。整个环境的结构图如下所示:



【以下内容参考文章:http://bbs.linuxtone.org/thread-24935-1-1.html】

概述:搭设一台Master服务器(虚拟机------一台centos6.5-mini ip:192.168.1.145),搭设两台Slave服务器(虚拟机——两台centos6.5-mini ip:192.168.1.152和ip:192.168.1.160)

原理:主服务器(Master)负责网站NonQuery操作,从服务器负责Query操作,用户可以根据网站功能模特性块固定访问Slave服务器,或者自己写个池或队列,自由为请求分配从服务器连接。主从服务器利用MySQL的二进制日志文件,实现数据同步。二进制日志由主服务器产生,从服务器响应获取同步数据库。

具体实现:

1、在主从服务器上都装上MySQL数据库,windows系统鄙人安装的是mysql_5.5.25.msi版本,Ubuntu安装的是mysql-5.6.22-linux-glibc2.5-i686.tar

windows安装mysql就不谈了,一般地球人都应该会。鄙人稍微说一下Ubuntu的MySQL安装,我建议不要在线下载安装,还是离线安装的好。大家可以参考 http://www.linuxidc.com/Linux/2013-01/78716.htm 这位不知道大哥还是姐妹,写的挺好按照这个就能装上。在安装的时候可能会出现几种现象,大家可以参考解决一下:

(1)如果您不是使用root用户登录,建议 su - root 切换到Root用户安装,那就不用老是 sudo 了。

(2)存放解压的mysql 文件夹,文件夹名字最好改成mysql

(3)在./support-files/mysql.server start 启动MySQL的时候,可能会出现一个警告,中文意思是启动服务运行读文件时,忽略了my.cnf文件,那是因为my.cnf的文件权限有问题,mysql会认为该文件有危险不会执行。但是mysql还会启动成功,但如果下面配置从服务器参数修改my.cnf文件的时候,你会发现文件改过了,但是重启服务时,修改过后的配置没有执行,而且您 list一下mysql的文件夹下会发现很多.my.cnf.swp等中间文件。这都是因为MySQL启动时没有读取my.cnf的原因。这时只要将my.cnf的文件权限改成my_new.cnf的权限一样就Ok,命令:chmod
644 my.cnf就Ok



(4)Ubuntu中修改文档内容没有Vim,最好把Vim 装上,apt-get install vim,不然估计会抓狂。

这时候我相信MySQL应该安装上去了。

【以上不是重点,mysql本机访问和远程访问都不可以的,自己查资料一定要弄好!!!!!否则后面无法进行】

2、配置Master主服务器

(1)在Master MySQL上创建一个用户‘repl’,并允许其他Slave服务器可以通过远程访问Master,通过该用户读取二进制日志,实现数据同步。

创建用于读取日志的数据库用户:
1 mysql>create user repl; //创建新用户
2 //repl用户必须具有REPLICATION SLAVE权限,除此之外没有必要添加不必要的权限,密码为mysql。
//说明一下192.168.0.%,这个配置是指明repl用户所在服务器,这 里%是通配符,表示192.168.0.0-192.168.0.255的Server都可以以repl用户登陆主服务器。当然你也可以指定固定Ip。
3 mysql> GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.0.%' IDENTIFIED BY 'mysql';


(2)找到MySQL安装文件夹修改my.Ini文件。mysql中有好几种日志方式,这不是今天的重点。我们只要启动二进制日志log-bin就ok。

在[mysqld]下面增加下面几行代码

my.cnf配置:
1 server-id=1   //给数据库服务的唯一标识,一般为大家设置服务器Ip的末尾号
2 log-bin=master-bin
3 log-bin-index=master-bin.index

缺东西:
3 binlog-do-db=amoeba_study #用于master-slave的具体数据库#设置二进制日志记录的库
4 binlog-ignore-db=mysql        ##设置二进制日志不记录的库
5 sync_binlog=1      作用:

【备注】:1和2的顺序颠倒后,centos6.5 bash下的某些命令不能用了!


(3)查看日志

mysql> SHOW MASTER STATUS;

+-------------------+----------+--------------+------------------+

| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |

+-------------------+----------+--------------+------------------+

| master-bin.000001 | 1285 | | |

+-------------------+----------+--------------+------------------+

1 row in set (0.00 sec)

重启MySQL服务

3、配置Slave从服务器(windows和centos6.5-mini配置一样)

(1)找到MySQL安装文件夹修改my.ini【windows】,centos6.5-mini修改/etc/my.cnf文件,在[mysqld]下面增加下面几行代码

1 [mysqld]
2 server-id=2 #slave的标示
3 relay-log=slave-relay-bin
4 relay-log-index=slave-relay-bin.index

缺东西:
5 replicate-do-db=amoeba_study #用于master-slave的具体数据库#设置二进制日志记录的库
6 replicate-ignore-db=mysql        ##设置二进制日志不记录的库
7 sync_binlog=1      作用:

重启MySQL服务

(2)连接Master

执行下面的命令连接到master
mysql> change master to
-> master_host='192.168.1.145',
-> master_user='repl',
-> master_password='mysql',
-> master_log_file='master-bin.000001',//Master服务器产生的日志
-> master_log_pos=0;


(3)启动Slave

mysql>start slave;
(4)验证master-slave搭建生效

可以在当前窗口中输入

mysql>show slave status;

查看slave的状态信息。

或者



通过查看slave机的log(/var/log/mysqld.log):

100703 10:51:42 [Note] Slave I/O thread: connected to master 'repl@10.20.147.110:3306', replication started in log 'mysql-bin.000003' at position 161261

如看到以上信息则证明搭建成功,如果有问题也可通过此log找原因



OK所有配置都完成了,这时候大家可以在Master Mysql 中进行测试了,因为我们监视的时Master mysql 所有操作日志,所以,你的任何改变主服务器数据库的操作,都会同步到从服务器上。创建个数据库,表试试吧。。。

【备注】本实例只对database数据库amoeba_study进行同步。好啦,到此master-slave主从mysql数据库同步已经可以了!赶紧试试吧~

==============================================二.搭建database proxy=================================================

参考文章:

文章一【仅供参考】:

构建高性能web之路------mysql读写分离实战
http://blog.csdn.net/cutesource/article/details/5710645
文章二【仅供参考,主要参考这个】:
amoeba for mysql的读写分离配置
http://bbs.linuxtone.org/thread-24935-1-1.html
-----------------------------------------------------------------------------------

此次实战中database proxy采用amoeba,它的相关信息可以查阅官方文档,不在此详述

1)安装amoeba

下载amoeba-mysql-binary-2.1.0-RC5 后解压到本地(D:/openSource/amoeba-mysql-binary-2.1.0-RC5),即完成安装

2) 配置Amoeba for MySQL:

Amoeba for MySQL的使用是很简单的,主要是通过xml文件来实现的。

1. 配置文件介绍:

(1.) dbServers.xml 想象Amoeba作为数据库代理层,它一定会和很多数据库保持通信,因此它必须知道由它代理的数据库如何连接,比如最基础的:主机IP、端口、Amoeba使用的用户名和密码等等。这些信息存储在$AMOEBA_HOME/conf/dbServers.xml中。

(2.) rule.xml Amoeba为了完成数据切分提供了完善的切分规则配置,为了了解如何分片数据、如何将数据库返回的数据整合,它必须知道切分规则。与切分规则相关的信息存储在$AMOEBA_HOME/conf/rule.xml中。

(3.) functionMap.xml 当我们书写SQL来操作数据库的时候,常常会用到很多不同的数据库函数,比如:UNIX_TIMESTAMP()、SYSDATE()等等。这些函数如何被Amoeba解析呢?$AMOEBA_HOME/conf/functionMap.xml描述了函数名和函数处理的关系。

(4.) ruleFunctionMap.xml 对$AMOEBA_HOME/conf/rule.xml进行配置时,会用到一些我们自己定义的函数,比如我们需要对用户ID求HASH值来切分数据,这些函数在$AMOEBA_HOME/conf/ruleFunctionMap.xml中定义。

(5.) access_list.conf Amoeba可以制定一些可访问以及拒绝访问的主机IP地址,这部分配置在$AMOEBA_HOME/conf/access_list.conf中。

(6.) log4j.xml Amoeba允许用户配置输出日志级别以及方式,配置方法使用log4j的文件格式,文件是$AMOEBA_HOME/conf/log4j.xml。

先配置proxy连接和与各后端mysql服务器连接信息其中,

我们主要用到dbServers.xml 和 amoeba.xml 。

【dbServers.xml 的配置:】

<dbServer name=”abstractServer” abstractive=”true”>
3306<!—代理连接数据库使用的端口号-->
amoeba_study<!—代理连接数据库所使用的数据库-->
root<!—代理连接数据库使用的用户名-->
000000asd<!—代理连接数据库使用的密码-->
</dbServer>
<!--- 配置真实的数据库的地址-->
<!--- 配置主从服务器及服务器连接池-->
<dbServer name="<span style="color:#FF0000;">server1</span>"  parent="<span style="color:#FF0000;">abstractServer</span>">
<factoryConfig>
<!-- mysql ip -->
<property name="<span style="color:#FF0000;">ipAddress</span>">192.168.0.162</property>
<!--必须有以下配置,否则会查询或者插入数据的时候,失败!!!!!!!!!!!!!!-->
<property name="<span style="color:#FF0000;">user</span>">root</property>
<property name="<span style="color:#FF0000;">password</span>">000000asd</property>
</factoryConfig>
</dbServer>

<dbServer name=”<span style="color:#FF0000;">server2</span>”  parent=”<span style="color:#FF0000;">abstractServer</span>”>
<factoryConfig>
<!—mysql ip -->
<property name=”<span style="color:#FF0000;">ipAddress</span>”>192.168.0.171</property>
<!--必须有以下配置,否则会查询或者插入数据的时候,失败!!!!!!!!!!!!!!-->
<property name="<span style="color:#FF0000;">user</span>">root</property>
<property name="<span style="color:#FF0000;">password</span>">000000asd</property>
</factoryConfig>
</dbServer>

<dbServer name=”<span style="color:#FF0000;">master</span>” virtual=”<span style="color:#FF0000;">true</span>”>
<poolConfig class=”com.meidusa.amoeba.server.MultipleServerPool”>
<!—Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name=”<span style="color:#FF0000;">loadbalance</span>”>1</property>
<!—Separated by commas,such as: server1,server2,server1 -->
<property name=”<span style="color:#FF0000;">poolNames</span>”>server1</property>
</poolConfig>
</dbServer>
<dbServer name=”<span style="color:#FF0000;">slave</span>” virtual=”<span style="color:#FF0000;">true</span>”>
<poolConfig class=”com.meidusa.amoeba.server.MultipleServerPool”>
<!—Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name=”<span style="color:#FF0000;">loadbalance</span>”>1</property>
<!—Separated by commas,such as: server1,server2,server1 -->
<property name=”<span style="color:#FF0000;">poolNames</span>”>server2</property>
</poolConfig>
</dbServer>


【amoeba.xml 配置:】

客户端连接Amoeba时所绑定的IP地址、端口、用户名和密码。及IP访问限制。
<service name="Amoeba for Mysql" >
<!-- port -->
<property name="port">8066</property>
<!-- bind ipAddress -->
<!--
<property name="ipAddress">127.0.0.1</property>
-->
<property name="ipAddress"><span style="color:#FF0000;">192.168.1.145</span></property>
 <property name="connectionFactory">
<bean >
<property name="sendBufferSize">128</property>
<property name="receiveBufferSize">64</property>
</bean>
</property>
<property name="authenticateProvider">
<bean >
<property name="<span style="color:#FF0000;">user</span>">root</property>
<property name="<span style="color:#FF0000;">password</span>">000000asd</property>
<property name="filter">
<bean>
<property name="ipFile">${amoeba.home}/conf/access_list.conf</property>
</bean>
</property>
</bean>
</property>
</service>

以下内容是定义读写分离:

<queryRouter >
<property name="ruleLoader">
<bean >
<property name="ruleFile">${amoeba.home}/conf/rule.xml</property>
<property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property>
</bean>
</property>
<property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
<property name="LRUMapSize">1500</property>
<property name="<span style="color:#FF0000;">defaultPool</span>">master</property>
<property name="<span style="color:#FF0000;">writePool</span>">master</property>
<property name="<span style="color:#FF0000;">readPool</span>">slave</property>
<property name="<span style="color:#FF0000;">needParse</span>">true</property>
</queryRouter>


===============================

amoeba配置完成后:

3)Amoeba启动:sh amoeba start

启动成功后信息如下:

[root@mmyr3 bin]# sh amoeba start
log4j:WARN log4j config load completed from file:/usr/amoeba-mysql-binary-2.1.0-RC5/conf/log4j.xml
2015-07-30 00:34:46,888 INFO  context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.1.0-RC5
log4j:WARN ip access config load completed from file:/usr/amoeba-mysql-binary-2.1.0-RC5/conf/access_list.conf
2015-07-30 00:34:47,357 INFO  net.ServerableConnectionManager - Amoeba for Mysql listening on /192.168.1.145:8066.


【备注:由于我把主从数据库代理amoeba绑定到ip192.168.1.145上所有此处是这样子!!!!】

启动成功后,在客户端连接Amoeba测试::

mysql -u root -p000000asd -h 192.168.1.145 --port 8066

【备注:上面的一条命令修改对应的用户名和密码,是没有问题的,如果连接不上,检查一下要连接的master机上的mysqld服务是否已经启动】

mysql> CREATE DATABASE minunix; \\ 创建数据库,之后在主从库分别查看

通过Amoeba登录,进行数据的查询及插入更新等操作,并查看mysql-log日志,可发现所执行的INSERT 、UPDATE、DELETE等操作在主库server1上操作,SELECT查询语句在从库server2上执行。

mysql数据库的操作日志在哪里【】

这个你可以看配置文件 启用了才有这样的记录默认是没有的
/etc/my.conf
log-bin = mysqlbin
一般放在/var/lib/mysql
比如上面的设置重启数据库会生成mysqlbin.000001文件


/var/log/mysqld.log

/var/lib/mysql/mysql_log.log

/var/lib/mysql/master-bin.000003

======================================搭建amoeba主从数据库代理过程中遇到的错误=============================================

一:这个估计是验证失败,网上有的说是需要设置主主同步【参考网址:http://blog.sina.com.cn/s/blog_73164f5f0101958x.html】

java.lang.Exception: poolName=master, no valid pools

at com.meidusa.amoeba.net.poolable.MultipleLoadBalanceObjectPool.borrowObject(MultipleLoadBalanceObjectPool.java:183)

at com.meidusa.amoeba.mysql.handler.CommandMessageHandler.startSession(CommandMessageHandler.java:629)

at com.meidusa.amoeba.mysql.handler.MySqlCommandDispatcher.handleMessage(MySqlCommandDispatcher.java:123)

at com.meidusa.amoeba.mysql.net.MysqlClientConnection$2.run(MysqlClientConnection.java:291)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

at java.lang.Thread.run(Thread.java:745)

二:这个是第二个pool没有配置用户名和密码导致的貌似

java.util.NoSuchElementException: Could not create a validated object, cause: ValidateObject failed

at org.apache.commons.pool.impl.GenericObjectPool.borrowObject(GenericObjectPool.java:1191)

at com.meidusa.amoeba.net.poolable.GenericObjectPool.borrowObject(GenericObjectPool.java:381)

at com.meidusa.amoeba.mysql.handler.CommandMessageHandler.startSession(CommandMessageHandler.java:629)

at com.meidusa.amoeba.mysql.handler.MySqlCommandDispatcher.handleMessage(MySqlCommandDispatcher.java:123)

at com.meidusa.amoeba.mysql.net.MysqlClientConnection$2.run(MysqlClientConnection.java:291)

at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)

at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)

at java.lang.Thread.run(Thread.java:745)

==============================================三.client端调用与测试=================================================

参考文章:
http://blog.csdn.net/cutesource/article/details/5710645
1)编写client调用程序

具体程序细节就不详述了,只是一个最普通的基于mysql driver的jdbc的数据库操作程序

2)配置数据库连接

本client基于c3p0,具体数据源配置如下:

[xhtml]
view plaincopy

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://localhost:8066/amoeba_study" />
<property name="user" value="root" />
<property name="password" value="root" />
<property name="minPoolSize" value="1" />
<property name="maxPoolSize" value="1" />
<property name="maxIdleTime" value="1800" />
<property name="acquireIncrement" value="1" />
<property name="maxStatements" value="0" />
<property name="initialPoolSize" value="1" />
<property name="idleConnectionTestPeriod" value="1800" />
<property name="acquireRetryAttempts" value="6" />
<property name="acquireRetryDelay" value="1000" />
<property name="breakAfterAcquireFailure" value="false" />
<property name="testConnectionOnCheckout" value="true" />
<property name="testConnectionOnCheckin" value="false" />
</bean>

值得注意是,client端只需连到proxy,与实际的数据库没有任何关系,因此jdbcUrl、user、password配置都对应于amoeba暴露出来的配置信息

3)调用与测试

首先插入一条数据:insert into zone_by_id(id,name) values(20003,'name_20003')

通过查看master机上的日志/var/lib/mysql/mysql_log.log:

100703 11:58:42 1 Query set names latin1

1 Query SET NAMES latin1

1 Query SET character_set_results = NULL

1 Query SHOW VARIABLES

1 Query SHOW COLLATION

1 Query SET autocommit=1

1 Query SET sql_mode='STRICT_TRANS_TABLES'

1 Query SHOW VARIABLES LIKE 'tx_isolation'

1 Query SHOW FULL TABLES FROM `amoeba_study` LIKE 'PROBABLYNOT'

1 Prepare [1] insert into zone_by_id(id,name) values(?,?)

1 Prepare [2] insert into zone_by_id(id,name) values(?,?)

1 Execute [2] insert into zone_by_id(id,name) values(20003,'name_20003')

得知写操作发生在master机上

通过查看slave机上的日志/var/lib/mysql/mysql_log.log:

100703 11:58:42 2 Query insert into zone_by_id(id,name) values(20003,'name_20003')

得知slave同步执行了这条语句

然后查一条数据:select t.name from zone_by_id t where t.id = 20003

通过查看slave机上的日志/var/lib/mysql/mysql_log.log:

100703 12:02:00 33 Query set names latin1

33 Prepare [1] select t.name from zone_by_id t where t.id = ?

33 Prepare [2] select t.name from zone_by_id t where t.id = ?

33 Execute [2] select t.name from zone_by_id t where t.id = 20003

得知读操作发生在slave机上

并且通过查看slave机上的日志/var/lib/mysql/mysql_log.log发现这条语句没在master上执行

通过以上验证得知简单的master-slave搭建和实战得以生效

----------------自己:简单测试一下,看DAO是否能连接到主从数据库代理amoeba,代码如下:------------

package amoeba_test;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;

public class SQLHelper {
public static void main(String[] args) {
try {
// 加载MySql的驱动类
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.out.println("找不到驱动程序类 ,加载驱动失败!");
e.printStackTrace();
}

//连接152上的mysql数据库:
//		jdbc:mysql://192.168.1.152:3306/test
String url = "jdbc:mysql://192.168.1.145:8066/amoeba_study";
String username = "root";
String password = "000000asd";
try{
Connection con =DriverManager.getConnection(url , username , password ) ;
if(con!=null){
System.out.println("successfully connected");
}
}catch(SQLException se){
System.out.println("数据库连接失败!");
se.printStackTrace() ;
}

}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: