MySQL集群:主从数据库配置 实现查询负载
在做web应用系统中,如果数据库出现了性能瓶颈,而你又是使用的MySQL数据库,那么就可以考虑采用数据库集群的方式来实现查询负载了。因为一般来讲任何一个系统中数据库的查询操作比更新操作要多的多,因此通过多台查询服务器将数据库的查询分担到不同的查询数据库从而提高数据库的查询效率。
?? ? ?MySQL数据库支持数据库的主从复制功能,使用主数据库进行数据的插入、删除与更新操作,而从数据库则专门用来进行数据库查询,这样就可以将更新操作与查询操作分离到不同的数据库上,从而提高查询的效率。
1、主数据库配置?? ? ?MySQL任何一台数据库服务器都可以作为主数据库服务器,我们只需要简单的修改配置文件就可以使之成为主数据库服务器。我们打开MySQL的配置文件(对于windows就是MySQL安装目录下的my.ini文件,对于linux通常就是/etc/my.cnf文件),我们在配置文件中加入如下两行:
- server-id = 1
- log-bin=mysql-bin
?? ? ?注意,MySQL进行主从复制是通过二进制的日志文件来进行,所以我们必须开启MySQL的日志功能,即我们上面的log-bin,同时每一台数据库服务器都需要指定一个唯一的server-id,通常主数据库服务器我们指定为1。主数据库服务器的配置就是如此了,然后我们还需要给主数据库授予一个可以进行复制的用户,命令如下:
- GRANT replication slave ON *.* TO 'repuser'@'%' IDENTIFIED BY '123456';
?? ? ?replication slave是MySQL数据库中表示复制的权限名称,repuser则是表示从数据库服务器登陆到主数据库服务器时用到的用户名称,123456表示登陆密码。这样,我们就在主数据库服务器上创建了一个可以进行复制的用户账号了。然后我们启动主数据库服务器就可以了。
2、从数据库配置?? ? ?从数据库服务器的配置稍微多一点,主要也是修改MySQL的配置文件,加入如下行:
- server-id=2
- log-bin=mysql-bin --在从服务器上启动日志记录,不是必须,但是官方建议
- master-host=主机 --主数据库服务器的IP地址
- master-user=用户名 --执行复制的用户名称,就是grant的用户
- master-password=密码 --复制用户的密码,就是grant的用户密码
- master-port=端口 --主数据库服务器的端口,默认是3306
?? ? ?相关的配置参数意义已做了说明,主要就是多了配置主数据库服务器上的复制账号的信息。然后我们启动从数据库服务器,注意启动从数据库服务器后,并没有启动复制线程,我们需要在命令行中执行如下命令来启动复制功能:
- slave start
?? ? ?启动后,我们就可以通过如下命令来查看复制的状态了:
- show slave status;
?? ? ?然后我们就可以看到系统的输出,第一个就是Slave_IO_State,它的值通常就是Waiting for master to send event,然后我们也还可以看到我们刚才配置的主数据库服务器的IP地址、复制账号等信息。
?? ? ?我们还可以在从数据库服务器上动态的改变对主数据库的配置信息,通过如下命令来进行:
3、启动与监控
- CHANGE MASTER TO MASTER_HOST=’主数据库服务器的IP地址’, MASTER_PORT=3306,MASTER_USER=’主数据库上的复制帐号’, MASTER_PASSWORD=’密码’;
?? ? ?监控主数据库服务器的状态,我们可以通过showmaster status来查看主数据库服务器的状态,它的输出如下:
- +------------------+----------+--------------+------------------+
- | File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
- +------------------+----------+--------------+------------------+
- | mysql-bin.000003 | 370558 | | |
- +------------------+----------+--------------+------------------+
- 1 row IN SET (0.00 sec)
?? ? ?其中File是表示日志记录的文件,而Position则是表示当前日志在文件中的位置,这个也是从数据库服务器上执行复制操作必须的标识,后面的两个字段分别表示要记录的数据库名称和不需要记录的数据库名称,我们也可以在配置文件中进行配置。
?? ? ?监控从数据库服务器的状态,我们可以通过show slave status来查看从数据库服务器的状态,它的基本输出如下:
- +----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+
- | Slave_IO_State | Master_Host | Master_User | Master_Port | Connect_Retry | Master_Log_File | Read_Master_Log_Pos | Relay_Log_File | Relay_Log_Pos | Relay_Master_Log_File | Slave_IO_Running | Slave_SQL_Running | Replicate_Do_DB | Replicate_Ignore_DB | Replicate_Do_Table | Replicate_Ignore_Table | Replicate_Wild_Do_Table | Replicate_Wild_Ignore_Table | Last_Errno | Last_Error | Skip_Counter | Exec_Master_Log_Pos | Relay_Log_Space | Until_Condition | Until_Log_File | Until_Log_Pos | Master_SSL_Allowed | Master_SSL_CA_File | Master_SSL_CA_Path | Master_SSL_Cert | Master_SSL_Cipher | Master_SSL_Key | Seconds_Behind_Master |
- +----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+
- | Waiting FOR master TO send event | 172.16.11.221 | repuser | 3306 | 60 | mysql-bin.000003 | 370558 | WEB2-relay-bin.000206 | 12251 | mysql-bin.000003 | Yes | Yes | | | | | | | 0 | | 0 | 370558 | 12251 | None | | 0 | No | | | | | | 0 |
- +----------------------------------+---------------+-------------+-------------+---------------+------------------+---------------------+-----------------------+---------------+-----------------------+------------------+-------------------+-----------------+---------------------+--------------------+------------------------+-------------------------+-----------------------------+------------+------------+--------------+---------------------+-----------------+-----------------+----------------+---------------+--------------------+--------------------+--------------------+-----------------+-------------------+----------------+-----------------------+
- 1 row IN SET (0.00 sec)
?? ? ?上面显示的结果中的mysql-bin.000003和370558分别表示的是Master_Log_File和Read_Master_Log_Pos,即主数据库服务器上的日志文件和要读取的主数据库服务器上的日志的位置,通常这个Read_Master_Log_Pos是和主数据库服务器上的Position是一致的,当然这个是指同步以后的,如果从数据库服务器还没有同步完毕,那么这个值通常比主数据库服务器上的要小。
?? ? ?如果从数据库服务器在同步的过程中出现了问题,那么我们可以通过reset slave来重置从数据库服务器的复制线程,从数据库服务器上的通常操作命令有:
- Slave start; --启动复制线程
- Slave stop; --停止复制线程
- Reset slave; --重置复制线程
- Show slave status; --显示复制线程的状态
- Change master to; --动态改变到主数据库的配置
?? ? ?至此,我们就完成了mysql的主从数据库的配置,这也也为我们的应用在集群中的使用打下了一个基础。
?
主从数据库ThinkPHP的模型支持主从式数据库的连接,配置DB_DEPLOY_TYPE?为1?可以采用分布式数据库支持。如果采用分布式数据库,定义数据库配置信息的方式如下:
//?在项目配置文件里面定义
return?array(
'DB_TYPE'=>?'mysql',?//?分布式数据库的类型必须相同
'DB_HOST'=>?'192.168.0.1,192.168.0.2',
'DB_NAME'=>'thinkphp',?//?如果相同可以不用定义多个
'DB_USER'=>'user1,user2',?
'DB_PWD'=>'pwd1,pwd2',?
'DB_PORT'=>'3306',
'DB_PREFIX'=>'think_',
……?其它项目配置参数
);
连接的数据库个数取决于DB_HOST定义的数量,所以即使是两个相同的IP也需要重复定义,但是其他的参数如果存在相同的可以不用重复定义,例如:
'DB_PORT'=>'3306,3306'?和?'DB_PORT'=>'3306'?等效
'DB_USER'=>'user1',?
'DB_PWD'=>'pwd1',?
和
'DB_USER'=>'user1,user1',?
'DB_PWD'=>'pwd1,pwd1',
等效。
还可以设置分布式数据库的读写是否分离,默认的情况下读写不分离,也就是每台服务器都可以进行读写操作,对于主从式数据库而言,需要设置读写分离,通过下面的设置就可以:
'DB_RW_SEPARATE'=>true,
在读写分离的情况下,第一个数据库配置是主服务器的配置信息,负责写入数据,其它的都是从数据库的配置信息,负责读取数据,数量不限制。每次连接从服务器并且进行读取操作的时候,系统会随机进行在从服务器中选择。
注意事项:主从数据库的数据同步工作不在框架实现,需要数据库考虑自身的同步或者复制机制。