實現方式
首先說明這種方式一般分爲兩種:
1.採用代碼形式,就是在代碼中判斷我是否要進行查詢還是更新或增加,對應的去不同服務器的從庫或主庫進行操作
2.使用MySQL proxy 來進行這樣可以不用從代碼來直接區分是增刪改查的語句,直接去MySQL proxy去執行操作,然後MySQL proxy回去對應的主庫或者從庫執行操作。一般稱這樣的方式爲中間件,除了有MySQL proxy之外還有HAproxy(付費)等。
這兩種方式各有其適用的場景,不能片面的指出那種方式比較好,只能是根據自己的業務需求去決定。
關於 MySQL的主從複製的配置以及MySQL proxy的配置
在以下這篇文章當中會詳細講到:
http://www.cnblogs.com/DavidYan/articles/2531181.html
或者可以參考這個
http://www.jianshu.com/p/8528072cba9a
接下來我們要說的是在Yii2中是如何實現這個代碼層級的讀寫分離.
Yii2中主從複製和讀寫分離
這裏主要圍繞最新的Yii2英文文檔中的一小節“主從複製與讀寫分離”展開進行介紹。爲什麼是英文文檔?目前中文翻譯的文檔不是最新的。
首先我們需要在 web.php中配置一下在component(組件)數組中按照下文進行配置,或者是直接覆蓋到config文件夾當中的db.php文件。
[
'class' => 'yii\db\Connection',
// configuration for the master
//dsn=>’mysql:host=localhost;dbname=xxx’
'dsn' => 'dsn for master server',
'username' => 'master',
'password' => '',
// common configuration for slaves
'slaveConfig' => [
'username' => 'slave',
'password' => '',
'attributes' => [
// use a smaller connection timeout
PDO::ATTR_TIMEOUT => 10,
],
],
// list of slave configurations
'slaves' => [
['dsn' => 'dsn for slave server 1'],
['dsn' => 'dsn for slave server 2'],
['dsn' => 'dsn for slave server 3'],
['dsn' => 'dsn for slave server 4'],
],
]
這個配置項都比較清楚,沒有太難的點去解釋slaves 的每個dsn分別對應的是每個從庫的地址。
在這裏需要注意的是通過yii\db\Command::execute()都會被當做寫操作,也就意味着這樣的命令會在主庫中執行。你也許會createCommand(’select * from users’)->excute(),這樣執行但是這樣的語句都會在主庫中執行。在其他所有的情況下,包含查詢的語句會在從庫中進行查詢。Yii2在支持負載均衡以及故障轉移。當第一次執行查詢時,連接組件隨機選取一個從庫去連接它,如果失敗則連接下一個從庫,直到沒有一個從庫可用纔會去連接主庫。在上述的配置文件中的一項PDO::ATTR_TIMEOUT的值對於每一個從庫都生效。
其他:
我們有可能需要從主庫讀取數據:
$rows = Yii::$app->db->useMaster(function ($db) {
return $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
});
我們也可以通過Yii::$app->db->slave獲取當前連接並可用的從庫。
結語
本文總結了一下MySQL的讀寫分離以及如何在Yii2中的實現,Yii2也提供了多主多從的配置方案,在這裏不做贅述有興趣的可以http://www.yiiframework.com/doc-2.0/guide-db-dao.html 查照Replication and Read-Write Splitting這一節。如果有什麼意見或者建議歡迎提出。