#phalapi-進階篇5(數據庫讀寫分離以及多庫使用)#

##前言##
***先在這里感謝phalapi框架創始人@dogstar,為我們提供了這樣一個優秀的開源框架.***
讀寫分離是我們常用的一種解決方案,它可以解決大量讀操作的時候數據庫瓶頸的問題,我們在真正開發一個項目的過程中可能會遇一個接口或者一個操作中需要用到多個數據庫操作的時候怎么辦,今天的教程就從這個兩個問題出來,來聊聊使用phalapi怎么解決這個問題.
附上:
喵了個咪的博客:[w-blog.cn](w-blog.cn)
官網地址:[http://www.phalapi.net/](http://www.phalapi.net/ "PhalApi官網")
開源中國Git地址:[http://git.oschina.net/dogstar/PhalApi/tree/release](http://git.oschina.net/dogstar/PhalApi/tree/release "開源中國Git地址")
##1. 讀寫分離##
在我們的生活中無時無刻不面臨著并發的問題,比如下班高峰交通問題,人們用了紅綠燈來解決的一部分問題**(但是很痛苦這個就和查詢的時候阻塞一樣的,10秒做update操作,10秒做select操作一樣的)**,那么人們有想到了一個方法高架,高架的路線是和正常的路線一致的**(數據相同)** ,高架分兩條路而且一條路上的車不能到另外一條路上**(讀寫分離)** 這樣就解決了我們這類常規并發的問題
其實看起來上面這種解決方案是比較好的其實并不是這樣的,有兩條路但是其實它的寬度是不一樣的,我們這里把一個叫做寫路,一個叫做讀路,我們如果要做一個讀路并且把他成倍的變寬是一件很簡單的事情(也就是多從庫),但是我們要建立一條寫路可以,但是我們要把這條寫路變寬是比較困難的,我們一般不這樣做.
###1.1 mysql主從配置###
我是使用了阿里云的多讀庫服務,這里引用一下**百度經驗**的mysql主從處理
**----------------------------------------------------------------------------------------------------**
MYSQL【一臺主機多個實例的主從配置】
1、建立賬號
進入mysql數據庫,創建一個用于從庫備份的賬號
mysql>GRANT REPLICATION SLAVE ON *.* TO 'slave_test'@'10.19.194.57' IDENTIFIED BY 'Password@123456';
mysql>FLUSH PRIVILEGES; ---刷新
該命令詳情參考grant創建用戶命令
2、如果已經有一個實例在運行(因為開始已經安裝了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 這個為另外一個目錄,該步驟意味初始化目錄,并創建一個實例
3、配置/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,文件就會自動創建
4、重啟,然后可以使用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表示啟動1、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語句要用到,用于設置從庫
5、進入從庫,并設置從庫的一些參數
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數值
6、設置好后,運行start slave,如果下圖紅線地方是YES,則成功,否則,查看配置文件是否有錯或有誤。
slave_io_running :yes
slave_sql_running :yes
7、可以查看從庫下mysql進程信息
mysql>show processlist;
8、測試
在主庫上面建新的數據庫,然后在從庫中查看是否有同步~
**----------------------------------------------------------------------------------------------------**
###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 歡迎大家的加入!**
####[上一章](/wikis/%5b7.10%5d-phalapi-%e8%bf%9b%e9%98%b6%e7%af%874(notorm%e8%bf%9b%e9%98%b6%e4%bb%a5%e5%8f%8a%e4%ba%8b%e5%8a%a1%e6%93%8d%e4%bd%9c).html) [文檔首頁](/wikis/) [下一章](/wikis/%5b7.12%5d-phalapi-%e8%bf%9b%e9%98%b6%e7%af%876(%e8%a7%a3%e5%86%b3%e5%a4%a7%e9%87%8f%e6%95%b0%e6%8d%ae%e5%ad%98%e5%82%a8%e6%95%b0%e6%8d%ae%e5%ba%93%e5%88%86%e8%a1%a8%e5%88%86%e5%ba%93%e6%8b%93%e5%b1%95).html)
- 空白目錄
- [7.1]-phalapi-入門篇1(簡單介紹以及環境搭建)
- [7.2]-phalapi-入門篇2(把它玩起來)
- [7.3]-phalapi-入門篇3(請求和返回)
- [7.4]-phalapi-入門篇4(國際化高可用和自動生成文檔)
- [7.5]-phalapi-入門篇5(數據庫操作和Model層)
- [7.6]-phalapi-入門篇6(小技巧和淺談API適用范圍以及入門篇總結)
- [7.7]-phalapi-進階篇1(三層結構Api,Domain,和Model)
- [7.8]-phalapi-進階篇2(DI依賴注入和單例模式)
- [7.9]-phalapi-進階篇3(自動加載和攔截器)
- [7.10]-phalapi-進階篇4(notorm進階以及事務操作)
- [7.11]-phalapi-進階篇5(數據庫讀寫分離)
- [7.12]-phalapi-進階篇6(解決大量數據存儲數據庫分表分庫拓展)
- [7.13]-phalapi-進階篇7(使用緩存以及用redis拓展解決實際問題)
- [7.14]-phalapi-進階篇8(PhalApi能帶來什么和進階篇總結)