ホームページ >バックエンド開発 >PHPチュートリアル >phalapi でデータベースの読み取りと書き込みを分離する方法
読み取りと書き込みの分離は、多くの大規模プロジェクトで一般的に使用されるソリューションであり、大量の読み取り操作が発生した場合のデータベースのボトルネックの問題を解決できます。では、読み取りと書き込みを分離したデータベースディストリビューションをどのように構築するか、また端末はどのように読み取りと書き込みの分離を実行するのでしょうか?この記事では、phalapi に基づいた読み書き分離の実装を例から説明します。
1. 読み取りと書き込みの分離
私たちは、仕事後のラッシュアワーの交通問題など、常に同時実行の問題に直面しています (しかし、これは非常に苦痛です。 (クエリ中のブロックと同じです)、更新操作には 10 秒かかり、選択操作には 10 秒かかります。) そこで人々は、高架ルートのルートを通常のルートと一致させる方法を考え出しました。データは同じです)。高架ルートは 2 つの道路に分割され、一方の道路にある車は別の道路に移動できません (読み取りと書き込みが分離される)。これにより、通常の同時実行の問題が解決されます
。解決策はより良いですが、これはそうではありません。2つの道がありますが、実際にはその幅が異なります。ここでは、読み取りパスを作成したい場合、一方を書き込みパスと呼びます。指数関数的に広くなるのは非常に簡単な問題 (つまり、複数のスレーブ ライブラリ) ですが、書き込みパスを確立することは可能ですが、この書き込みパスを広げることは困難です
。 1.1 mysql マスター/スレーブ構成
私は Alibaba Cloud のマルチリード ライブラリ サービスを使用しています。ここでは mysql マスター/スレーブ処理における Baidu の経験を引用しています
----------------- --------------------------------- ------------------- ------------------------------- --------------
MYSQL [1 つのホストの複数インスタンスのマスター/スレーブ構成]
1. アカウントを作成します
mysql データベースに入り、スレーブ データベースのバックアップ アカウントを作成します
mysql>GRANT REPLICATION SLAVE ON *.* TO 'slave_test'@'10.19.194.57' IDENTIFIED BY 'Password@123456'; mysql>FLUSH PRIVILEGES; ---刷新
このコマンドの詳細については、grant create user コマンドを参照してください。
2. すでに実行中のインスタンスがある場合 (mysql が最初にインストールされているため、デフォルトのインスタンスがあります)、次のように別のインスタンスを起動します:
(1) shell>cd /usr /local/mysql/
(2) シェル>mkdir -pv /data/mysql2
(3) シェル>chown -R mysql.mysql /data/mysql2
(4) シェル>./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。インスタンスを起動し、マスター メイン データベースのステータスを確認します。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 smileを実行します。それ以外の場合は、設定ファイルが正しいかどうかを確認してください。
slave_io_running :yes slave_sql_running :yes
7. スレーブライブラリ配下のmysqlプロセス情報を確認できます
8. メインライブラリに新しいデータベースを作成し、スレーブライブラリに同期があるかどうかを確認します~
--- ------ -------------------------------------------- ------ --------------------------------------
1.2の実装が始まりました
考え方の説明は終わり、皆さんも多かれ少なかれ理解できたと思いますが、phalapiで読み書きの分離をどのように実装するのでしょうか? まず、aを初期化する必要があります。 dbs.php と同様に、php はこの読み取りライブラリの設定項目を接続して登録するだけです
mysql>show processlist;
2. PhalApi_Model_NotORM ファイル内の getORM を変更します
//读库 DI()->read = function (){ $debug = !empty($_GET['__sql__']) ? true : false; return new PhalApi_DB_NotORM(DI()->config->get('read'), $debug); };
3. $this->getORM('モデル層で読み取る') を使用すると、読み取りライブラリが使用され、$this->getORM() はデフォルトで書き込みライブラリを使用します
/** * 快速获取ORM实例,注意每次获取都是新的实例 */ protected function getORM($id = NULL){ $table = $this->getTableName($id); if($id == 'read'){ return DI()->read->$table; } return DI()->notorm->$table; }
2。
なぜマルチライブラリ処理が必要なのかと疑問に思う人もいるでしょう。すべてのテーブルが配置されているのですが、すぐにライブラリが必要ですか? 他の人のアウトソーシングプロジェクトをリファクタリングしていたときに、100 個を超えるテーブルがあり、メモがないライブラリに遭遇しました。比較的大きなプロジェクトに取り組んでいたときは、ドキュメントがまったくなく、ほとんど読むことができませんでした。また、ビジネスに基づいてライブラリをサブライブラリに分解することも検討しました。これにより、テーブルが多すぎて混乱するという問題を十分に回避できます。 MySQL に大きな負荷がかかっている場合は、mysql 上のサブライブラリを複数の mysql に分解して、負荷の軽減を実現できます 上記の概要を読んだ後、そうすることの利点は誰もが理解していると思いますが、それを実装する方法は賢明です。上記のようにすぐに追加のデータベース接続を登録すると考えているかもしれません。実際、接続を登録する必要があります。このタイプの操作を使用するための統一仕様1. データベース接続を初期化し、開発者ライブラリに接続するように dbs.php をコピーします
//select操作 $this->getORM('read')->select('*')->where('aId', $aId)->fetchAll(); //insert,update,delete操作 $this->getORM()->insert();
2. PhalApi_Model_NotORM の getORM を変更します。ファイル
//开发者库 DI()->developers = function (){ $debug = !empty($_GET['__sql__']) ? true : false; return new PhalApi_DB_NotORM(DI()->config->get('developers'), $debug); };3. 以前にこのような構造を構築している一般ファイルを作成しましたよね?
--General //公用目录 --developers //通用项目库目录 --Domain //项目库Domain层 --Model //项目库Model层
然后我们在这里的Model进行的操作都是使用$this->getORM('developers')进行操作
这样规范的好处就是在与共享和模块化 让正常的一个Model层不会使用到任何不同库的操作,我们多个项目用到其他的一个库可以进行代码复用,
相关推荐:
以上がphalapi でデータベースの読み取りと書き込みを分離する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。