#phalapi-进阶篇5(数据库读写分离以及多库使用)#php
##前言## 先在这里感谢phalapi框架创始人@dogstar,为咱们提供了这样一个优秀的开源框架.mysql
读写分离是咱们经常使用的一种解决方案,它能够解决大量读操做的时候数据库瓶颈的问题,咱们在真正开发一个项目的过程当中可能会遇一个接口或者一个操做中须要用到多个数据库操做的时候怎么办,今天的教程就从这个两个问题出来,来聊聊使用phalapi怎么解决这个问题.git
附上:redis
官网地址:http://www.phalapi.net/sql
开源中国Git地址:http://git.oschina.net/dogstar/PhalApi/tree/releaseshell
##1. 读写分离##数据库
在咱们的生活中无时无刻不面临这并发的问题,好比下班高峰交通问题,人们用了红绿灯来解决的一部分问题**(可是很痛苦这个就和查询的时候阻塞同样的,10秒作update操做,10秒作select操做同样的),那么人们有想到了一个方法高架,高架的路线是和正常的路线一致的(数据相同)** ,高架分两条路并且一条路上的车不能到另一条路上**(读写分离)** 这样就解决了咱们这类常规并发的问题api
其实看起来上面这种解决方案是比较好的其实并非这样的,有两条路可是其实它的宽度是不同的,咱们这里把一个叫作写路,一个叫作读路,咱们若是要作一个读路而且把他成倍的变宽是一件很简单的事情(也就是多从库),可是咱们要创建一条写路能够,可是咱们要把这条写路变宽是比较困难的,咱们通常不这样作.并发
###1.1 mysql主从配置###框架
我是使用了阿里云的多读库服务,这里引用一下百度经验的mysql主从处理
----------------------------------------------------------------------------------------------------
MYSQL【一台主机多个实例的主从配置】
一、创建帐号
进入mysql数据库,建立一个用于从库备份的帐号
mysql>GRANT REPLICATION SLAVE ON *.* TO 'slave_test'@'10.19.194.57' IDENTIFIED BY 'Password@123456'; mysql>FLUSH PRIVILEGES; ---刷新
该命令详情参考grant建立用户命令
二、若是已经有一个实例在运行(由于开始已经安装了mysql,因此有一个默认的),那么再启动一个实例,方法以下:
(1)shell>cd /usr/local/mysql/ (2)shell>mkdir -pv /data/mysql2 (3)shell>chown -R mysql.mysql /data/mysql2 (4)shell>./scripts/mysql_install_db --user=mysql --datadir=/data/mysql2 这个为另一个目录,该步骤意味初始化目录,并建立一个实例
三、配置/etc/my.cnf,配置方法以下
[mysqld_multi] mysqld = /usr/local/mysql/bin/mysqld_safe mysqladmin = /usr/local/mysql/bin/mysqladmin user = root [mysqld] ## 原本mysql配置 server-id = 1 port = 3306 socket = /data/mysql/mysql.sock datadir = /data/mysql pid-file = /data/mysql/wzj.pid log-error = /data/mysql/wzj.err log-bin = /data/mysql/log/bin-log log-bin-index = /data/mysql/log/mysql-bin.index user = mysql [mysqld2] ##建立实例配置 server-id = 2 port = 3307 socket = /tmp/mysql2.sock datadir = /data/mysql2/ //mysql2存储数据库的地方,也就是实例 pid-file = /data/mysql2/mysql2.pid //mysql2的pid文件记录 log-error = /data/mysql2/mysql2.err //为错误日志文件的地方 user = mysql #master-host =10.19.194.57 #master-user ='wzj_slave_test' #master-pass ='Password@123456' #master-port =3306 #master_connect_retry=60 #replicate-do-db =mysql_wzj #replicate-ignore-db=mysql--------该段已注释,由于新版本中,须要用CHANGE MASTER TO 命令去设置
【注意】:以上文件的目录,皆为系统建立,并不是手动去建立,设置配置文件后,重启mysql,文件就会自动建立
四、重启,而后可使用msyql_multi命令启动实例,再查看一下master主库的状态,其中Binlog_Do_DB表示要备份的数据库,Binlog_Ignore_DB表示不备份的数据库
shell>/etc/rc.d/init.d/mysqld start/stop/restart shell>/usr/local/mysql/bin/mysqld_multi start 1-2 启动实例 (1-2表示启动一、2两个实例) shell>mysql master: mysql -P 3306 -u root -p -S /data/mysql/mysql.sock (密码:1) mysql>show master status; or show master status \G; 显示主库的状态,其中File 和Position 数值要记住,下面的mysql语句要用到,用于设置从库
五、进入从库,并设置从库的一些参数
shell>slave:mysql -P 3307 -u root -p -S /tmp/mysql2.sock (密码:回车) ---另外开个远程 mysql>CHANGE MASTER TO mysql> MASTER_HOST='10.19.194.57', ---主库的地址 mysql>MASTER_USER='wzj_slave_test', ---主库用户 mysql>MASTER_PASSWORD='Password@123456', ---主库的密码 mysql>MASTER_LOG_FILE='bin-log.000013' , ---此参数为master status中的File值 mysql>MASTER_LOG_POS=120; ---此数值为Position数值
六、设置好后,运行start slave,若是下图红线地方是YES,则成功,不然,查看配置文件是否有错或有误。
slave_io_running :yes slave_sql_running :yes
七、能够查看从库下mysql进程信息
mysql>show processlist;
八、测试
在主库上面建新的数据库,而后在从库中查看是否有同步~
----------------------------------------------------------------------------------------------------
###1.2 开始实现###
思想咱们已经讲完了相信你们已经多多少少的理解了,可是咱们要如何在phalapi去实现读写分离的操做
1.首先咱们要在初始化一个数据库链接,咱们须要创建一个配置文件read.php和dbs.php同样只是链接这读库的配置项,而且注册
//读库 DI()->read = function (){ $debug = !empty($_GET['__sql__']) ? true : false; return new PhalApi_DB_NotORM(DI()->config->get('read'), $debug); };
2.对PhalApi_Model_NotORM文件中的getORM进行修改
/** * 快速获取ORM实例,注意每次获取都是新的实例 */ protected function getORM($id = NULL){ $table = $this->getTableName($id); if($id == 'read'){ return DI()->read->$table; } return DI()->notorm->$table; }
3.当咱们在model层使用**$this->getORM('read')** 的时候就会使用读库,使用**$this->getORM()** 会默认使用写库
//select操做 $this->getORM('read')->select('*')->where('aId', $aId)->fetchAll(); //insert,update,delete操做 $this->getORM()->insert();
##2. 多库处理##
有些人会问,为何须要进行多库处理,全部的表放到一个库不久好了吗?
在原来重构别人外包项目是遇到过一个库100来张表,没有备注没有文档,几乎无法看,在我本身作一个比较大的项目的时候我也是作了一些考虑把库根据业务分解成一个一个子库,能够很好的避免表太多结构混乱的问题,并且咱们能够随时把任何一个子库移植出去,当我一个mysql承载了不少压力,我能够把这个mysql上面的子库分解到多个mysql上面来实现压力分流.
看了上面的这一段介绍相信你们不言而喻的了解了这样作的好处,可是如何实现呢,聪明的你们可能在想不久和上面同样在多注册一个数据库链接嘛,其实你们说对了一半,咱们是须要注册一个链接,可是咱们须要一种统一的规范来使用这类操做
1.初始化数据库链接,同样的复制一份dbs.php为developers.php配置链接开发者库
//开发者库 DI()->developers = function (){ $debug = !empty($_GET['__sql__']) ? true : false; return new PhalApi_DB_NotORM(DI()->config->get('developers'), $debug); };
2.对PhalApi_Model_NotORM文件中的getORM进行修改
/** * 快速获取ORM实例,注意每次获取都是新的实例 */ protected function getORM($id = NULL){ $table = $this->getTableName($id); if($id == 'developers'){ return DI()->developers->$table; } return DI()->notorm->$table; }
3.在以前咱们不是创建了咱们的公用General文件咱们在构建这样的结构
--General //公用目录 --developers //通用项目库目录 --Domain //项目库Domain层 --Model //项目库Model层
而后咱们在这里的Model进行的操做都是使用**$this->getORM('developers')**进行操做
这样规范的好处就是在与共享和模块化 让正常的一个Model层不会使用到任何不一样库的操做,咱们多个项目用到其余的一个库能够进行代码复用,
##3. 总结##
其实实现今天介绍的两种解决问题的方案还有不少不少,不一样的业务可能需求不一样实现也就不同但愿今天的介绍对你们有帮助,后面两篇教程将基于我写的两个拓展分别介绍分表分库操做和redis实际的使用,但愿你们进一步关注!
注:笔者能力有限有说的不对的地方但愿你们可以指出,也但愿多多交流!
官网QQ交流群:421032344 欢迎你们的加入!