W3Cschool
恭喜您成為首批注冊用戶
獲得88經(jīng)驗值獎勵
先在這里感謝phalapi框架創(chuàng)始人@dogstar,為我們提供了這樣一個優(yōu)秀的開源框架.
讀寫分離是我們常用的一種解決方案,它可以解決大量讀操作的時候數(shù)據(jù)庫瓶頸的問題,我們在真正開發(fā)一個項目的過程中可能會遇一個接口或者一個操作中需要用到多個數(shù)據(jù)庫操作的時候怎么辦,今天的教程就從這個兩個問題出來,來聊聊使用phalapi怎么解決這個問題.
附上:
喵了個咪的博客:w-blog.cn
官網(wǎng)地址:http://www.phalapi.net/
開源中國Git地址:http://git.oschina.net/dogstar/PhalApi/tree/release
在我們的生活中無時無刻不面臨著并發(fā)的問題,比如下班高峰交通問題,人們用了紅綠燈來解決的一部分問題(但是很痛苦這個就和查詢的時候阻塞一樣的,10秒做update操作,10秒做select操作一樣的),那么人們有想到了一個方法高架,高架的路線是和正常的路線一致的(數(shù)據(jù)相同) ,高架分兩條路而且一條路上的車不能到另外一條路上(讀寫分離) 這樣就解決了我們這類常規(guī)并發(fā)的問題
其實看起來上面這種解決方案是比較好的其實并不是這樣的,有兩條路但是其實它的寬度是不一樣的,我們這里把一個叫做寫路,一個叫做讀路,我們?nèi)绻鲆粋€讀路并且把他成倍的變寬是一件很簡單的事情(也就是多從庫),但是我們要建立一條寫路可以,但是我們要把這條寫路變寬是比較困難的,我們一般不這樣做.
我是使用了阿里云的多讀庫服務,這里引用一下百度經(jīng)驗的mysql主從處理
----------------------------------------------------------------------------------------------------
MYSQL【一臺主機多個實例的主從配置】
1、建立賬號
進入mysql數(shù)據(jù)庫,創(chuàng)建一個用于從庫備份的賬號
mysql>GRANT REPLICATION SLAVE ON *.* TO 'slave_test'@'10.19.194.57' IDENTIFIED BY 'Password@123456';
mysql>FLUSH PRIVILEGES; ---刷新
該命令詳情參考grant創(chuàng)建用戶命令
2、如果已經(jīng)有一個實例在運行(因為開始已經(jīng)安裝了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 這個為另外一個目錄,該步驟意味初始化目錄,并創(chuàng)建一個實例
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] ##創(chuàng)建實例配置
server-id = 2
port = 3307
socket = /tmp/mysql2.sock
datadir = /data/mysql2/ //mysql2存儲數(shù)據(jù)庫的地方,也就是實例
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 命令去設置
【注意】:以上文件的目錄,皆為系統(tǒng)創(chuàng)建,并非手動去創(chuàng)建,設置配置文件后,重啟mysql,文件就會自動創(chuàng)建
4、重啟,然后可以使用msyql_multi命令啟動實例,再查看一下master主庫的狀態(tài),其中Binlog_Do_DB表示要備份的數(shù)據(jù)庫,Binlog_Ignore_DB表示不備份的數(shù)據(jù)庫
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; 顯示主庫的狀態(tài),其中File 和Position 數(shù)值要記住,下面的mysql語句要用到,用于設置從庫
5、進入從庫,并設置從庫的一些參數(shù)
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' , ---此參數(shù)為master status中的File值
mysql>MASTER_LOG_POS=120; ---此數(shù)值為Position數(shù)值
6、設置好后,運行start slave,如果下圖紅線地方是YES,則成功,否則,查看配置文件是否有錯或有誤。
slave_io_running :yes
slave_sql_running :yes
7、可以查看從庫下mysql進程信息
mysql>show processlist;
8、測試
在主庫上面建新的數(shù)據(jù)庫,然后在從庫中查看是否有同步~
----------------------------------------------------------------------------------------------------
思想我們已經(jīng)講完了相信大家已經(jīng)多多少少的理解了,但是我們要如何在phalapi去實現(xiàn)讀寫分離的操作
1.首先我們要在初始化一個數(shù)據(jù)庫連接,我們需要建立一個配置文件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();
有些人會問,為什么需要進行多庫處理,所有的表放到一個庫不就好了嗎?
在原來重構別人外包項目是遇到過一個庫100來張表,沒有備注沒有文檔,幾乎沒法看,在我自己做一個比較大的項目的時候我也是做了一些考慮把庫根據(jù)業(yè)務分解成一個一個子庫,可以很好的避免表太多結(jié)構混亂的問題,而且我們可以隨時把任何一個子庫移植出去,當我一個mysql承載了很多壓力,我可以把這個mysql上面的子庫分解到多個mysql上面來實現(xiàn)壓力分流.
看了上面的這一段介紹相信大家不言而喻的了解了這樣做的好處,但是如何實現(xiàn)呢,聰明的大家可能在想不久和上面一樣在多注冊一個數(shù)據(jù)庫連接嘛,其實大家說對了一半,我們是需要注冊一個連接,但是我們需要一種統(tǒng)一的規(guī)范來使用這類操作
1.初始化數(shù)據(jù)庫連接,一樣的復制一份dbs.php為developers.php配置連接開發(fā)者庫
//開發(fā)者庫
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文件我們在構建這樣的結(jié)構
--General //公用目錄
--developers //通用項目庫目錄
--Domain //項目庫Domain層
--Model //項目庫Model層
然后我們在這里的Model進行的操作都是使用$this->getORM('developers')進行操作
這樣規(guī)范的好處就是在與共享和模塊化 讓正常的一個Model層不會使用到任何不同庫的操作,我們多個項目用到其他的一個庫可以進行代碼復用,
其實實現(xiàn)今天介紹的兩種解決問題的方案還有很多很多,不同的業(yè)務可能需求不同實現(xiàn)也就不一樣希望今天的介紹對大家有幫助,后面兩篇教程將基于我寫的兩個拓展分別介紹分表分庫操作和redis實際的使用,希望大家進一步關注!
注:筆者能力有限有說的不對的地方希望大家能夠指出,也希望多多交流!
官網(wǎng)QQ交流群:421032344 歡迎大家的加入!
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網(wǎng)安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: