ホームページ >データベース >mysql チュートリアル >MySQL はどのように応答速度を向上させることができるか
MySQL 自体の制限により、多くのサイトが MySQL Memcached の古典的なアーキテクチャを採用しており、中には MySQL を放棄して NoSQL 製品を採用したサイトもあります。いくつかの単純なクエリ (特に PK クエリ) を実行する場合、多くの NoSQL 製品が MySQL よりもはるかに高速であることは否定できません。
HandlerSocket は MySQL Daemon Plugin の形で存在するため、MySQL をアプリケーション内で NoSQL として使用できます。その最大の機能は、SQL 初期化のオーバーヘッドなしで InnoDB などのストレージ エンジンとの対話を可能にすることです。 MySQL の TABLE にアクセスするときは、もちろんテーブルの開閉も必要ですが、以前にアクセスしたテーブルのキャッシュを再利用のために保存するため、毎回テーブルを開閉する必要はありませんが、テーブルの開閉は最も重要です。リソースを消費するため、ミューテックスの競合が容易に発生する可能性がありますが、これはパフォーマンスの向上に非常に効果的です。トラフィックが少なくなると、HandlerSocket はテーブルを閉じるため、通常は DDL をブロックしません。
HandlerSocket と MySQL Memcached の違いは何ですか?図 1-2 と図 1-3 を比較すると、違いがわかります 図 1-3 は、典型的な MySQL Memecached アプリケーション アーキテクチャを示しています。 Memcached の get 操作は、メモリまたはディスク上での MySQL の主キー クエリよりもはるかに高速であるため、Memcached はデータベース レコードのキャッシュに使用されます。 HandlerSocket のクエリ速度と応答時間が Memcached に匹敵する場合は、Memcached のキャッシュ レコードのアーキテクチャ層を置き換えることを検討できます。
1) 複数のクエリ モードをサポート
HandlerSocket現在、インデックス クエリ (主キー インデックスと非主キーの通常のインデックスの両方)、インデックス範囲スキャン、および LIMIT 句をサポートしています。つまり、追加、削除、変更、クエリのすべての機能がサポートされていますが、まだサポートされていません。インデックスを使用できない操作。さらに、execute_multi() は、複数の Query リクエストをネットワーク上で一度に送信するためにサポートされており、ネットワーク送信時間を節約します。
2) 多数の同時接続を処理します
HandlerSocket は epoll() とワーカー スレッド/スレッド プーリング アーキテクチャを使用し、MySQL 内部スレッドの数が制限されているため、HandlerSocket 接続は軽量です。 (my.cnf の handlersocket_threads/handlersocket_threads_wr パラメーターで制御できます) そのため、たとえ HandlerSocket への数千万のネットワーク接続が確立されたとしても、大量のメモリを消費せず、その安定性はいかなる形でも影響を受けません (メモリを消費しすぎると、大規模な相互排他競合やその他の問題 (バグ #26590、バグ #33948、バグ #49169 など) が発生します。
3) 優れたパフォーマンス
HandlerSocket のパフォーマンスは、HandlerSocket のパフォーマンス テスト レポートの記事で説明されていますが、他の NoSQL 製品と比較しても、パフォーマンスはまったく劣っていません。 SQL 関連の機能、およびネットワーク/同時実行関連の問題も最適化します:
ネットワーク パケットの縮小: 従来の MySQL プロトコルと比較して、HandlerSocket プロトコルは短いため、ネットワーク トラフィック全体が小さい。
限られた数の MySQL 内部スレッドを実行します。上記を参照してください。
クライアント リクエストのグループ化: 多数の同時リクエストが HandlerSocket に到着すると、各ワーカー スレッドはできるだけ多くのリクエストを集約し、集約されたリクエストを実行して同時に結果を返します。時間。このようにして、応答時間を少し犠牲にすることでパフォーマンスが大幅に向上します。たとえば、fsync() 呼び出しの数を減らし、コピーの待ち時間を短縮できます。
4) 重複キャッシュなし
Memcached を使用して MySQL/InnoDB レコードをキャッシュする場合、これらのレコードは Memcached と InnoDB バッファ プールの両方にキャッシュされるため、効率が非常に高くなります。 low (実際にはデータが 2 つあり、Memcached 自体が HA サポートを必要とする場合があります) HandlerSocket プラグインを使用すると、InnoDB ストレージ エンジンに直接アクセスし、レコードが InnoDB バッファ プールにキャッシュされるため、他の SQL ステートメントでキャッシュデータ。
5) データの不整合なし
Memcached を使用する場合とは異なり、データは 1 か所 (InnoDB ストレージ エンジンのキャッシュ領域内) にのみ保存されるため、Memcached との間でデータを維持する必要があります。 MySQL の一貫性。
6) クラッシュ セーフティ
バックエンド ストレージは InnoDB エンジンであり、トランザクションの ACID 特性をサポートし、トランザクションのセキュリティを保証します。データベース サーバーがクラッシュすると、1 秒以下のデータのみが失われます。
7) SQL/NOSQL の共存
多くの場合、依然として SQL (複雑なレポート クエリなど) を使用したいのですが、ほとんどの NoSQL 製品は SQL インターフェイスをサポートしていません。HandlerSocket は単なる SQL インターフェイスです。 MySQL プラグインでは、引き続き MySQL クライアント経由で SQL ステートメントを送信できますが、高スループットと高速応答が必要な場合は、HandlerSocket が使用されます。
8) MySQL 機能の継承
HandlerSocket は MySQL 上で実行されるため、SQL、オンライン バックアップ、レプリケーション、HA、モニタリングなどのすべての MySQL 機能が引き続きサポートされます。
9) MySQL を変更/再構築する必要はありません
HandlerSocket はプラグインでオープン ソースであるため、サードパーティ バージョン (Percona など) を含め、あらゆる MySQL ソース コードからの構築をサポートします。 )、MySQL を変更する必要はありません。
10) ストレージ エンジンに依存しない
MySQL-EnterpriseInnoDB プラグインと Percona XtraDB プラグインのみをテストしましたが、HandlerSocket は理論的にはあらゆるストレージ エンジンと対話できます。 MyISAM は簡単な変更によってサポートすることもできますが、これはデータ キャッシュとメモリ使用率の観点からはあまり重要ではありません。
1)プロトコルの非互換性
HandlerSocket API は Memcached API と互換性がなく、使い方は簡単ですが、HandlerSocket と対話する方法を学ぶには少し学習が必要です。ただし、Memecached 関数をオーバーロードすることで、これを HandlerSocket API に変換できます。
2) セキュリティ機能なし
他の NoSQL データベースと同様に、HandlerSocket はセキュリティ機能をサポートしていません。HandlerSocket のワーカー スレッドはシステム ユーザー権限で実行されるため、アプリケーションは HandlerSocket を介してすべてのテーブルにアクセスできますプロトコル オブジェクトですが、単にプロトコルを変更して、my.cnf にパスワードとして構成項目を追加することもできます。接続時に、この構成を通じてパスワードを検証できます。もちろん、ネットワーク ファイアウォールを介してデータ パケットをフィルタリングすることもできます。
3) ディスク IO 集中型のシナリオには利点がありません
IO 集中型のアプリケーション シナリオでは、データベースは 1 秒あたり数千のクエリを実行できず、通常は 1 ~ 10% の CPU しかありません。この場合、SQL 解析はパフォーマンスのボトルネックにはならないため、HandlerSocket を使用する利点はありません。HandlerSocket は、データがメモリに完全にロードされているサーバーでのみ使用してください。ただし、1 秒あたり 4w IOPS を提供できる PCI-E SSD (Fusion-IO など) デバイスの場合、IO デバイス自体が大量の CPU を消費するため、HandlerSocket を使用することには依然として利点があります。
注: この本に記載されているインストール方法は古く、バージョンも比較的低いため、使用することはお勧めできません。インストールについては公式ドキュメントを使用することをお勧めします。 Github アドレス: https://github.com/DeNA/HandlerSocket-Plugin-for-MySQL
インストール ドキュメント: https://github.com/DeNA/HandlerSocket-Plugin-for-MySQL/blob/ master/docs-en/installation.en.txt
ソース コードのダウンロード: Github 経由で直接 git clone するか、ダウンロードできます
インストール手順:
1. Handlersocket をビルドします
./autogen.sh ./configure --with-mysql-source=/work/mysql-5.1.50 --with-mysql-bindir=/work/mysql-5.1.50-linux-x86_64-glibc23/bin --with-mysql-plugindir=/work/mysql-5.1.50-linux-x86_64-glibc23/lib/plugin
注 :
2.コンパイル
make && make install
3.構成
HandleSocket はできませんコンパイル後に使用されるため、MySQL 構成ファイル (my.cnf) で次の構成を追加する必要があります:
[mysqld] # 绑定读请求端口 loose_handlersocket_port = 9998 # 绑定写请求端口 loose_handlersocket_port_wr = 9999 # 读请求线程数 loose_handlersocket_threads = 16 # 写请求线程数 loose_handlersocket_threads_wr = 16 # 设置最大接收连接数 open_files_limit = 65535
ここでの追加は主に HandleSocket の構成用です。ポート 9998 が 2 つあります。データの読み取りには 9999、データの書き込みには 9999 が使用されますが、9998 までの読み取りの方が効率的です。ここでは、読み取りと書き込みのスレッド数は 16 に設定されています。さらに、より多くの同時接続を処理するために、開いているファイル記述子の数は65535
に設定します。さらに、InnoDB の innodb_buffer_pool_size または MyISAM の key_buffy_size 設定オプションとキャッシュ インデックスとの関係のため、HandleSocket の可能性を最大限に発揮できるように、できるだけ大きく設定します。
4. HandleSocket をアクティブ化します
MySQL にログインして実行します
mysql> install plugin handlersocket soname 'handlersocket.so';
show processlist または show plugins を通じて HandleSocket を確認できます
最後に、次のことを行う必要があります。 PHP 拡張パックをインストールします PHP HandlerSocket
インストール ドキュメント: https://github.com/tz-lom/HSPHP
PHP の使用法:
Select
<?php $c = new \HSPHP\ReadSocket(); $c->connect(); $id = $c->getIndexId('data_base_name', 'table_name', '', 'id,name,some,thing,more'); $c->select($id, '=', array(42)); // SELECT WITH PRIMARY KEY $response = $c->readResponse(); //SELECT with IN statement $c = new \HSPHP\ReadSocket(); $c->connect(); $id = $c->getIndexId('data_base_name', 'table_name', '', 'id,name,some,thing,more'); $c->select($id, '=', array(0), 0, 0, array(1,42,3)); $response = $c->readResponse();
更新
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->update($id,'=',array(100500),array(100500,42)); // Update row(k,v) with id 100500 to k = 100500, v = 42 $response = $c->readResponse(); // Has 1 if OK $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->update($id,'=',array(100500),array(100500,42), 2, 0, array(100501, 100502)); // Update rows where k IN (100501, 100502) $response = $c->readResponse(); // Has 1 if OK
削除
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->delete($id,'=',array(100500)); $response = $c->readResponse(); //return 1 if OK
挿入
<?php $c = new \HSPHP\WriteSocket(); $c->connect('localhost',9999); $id = $c->getIndexId('data_base_name','table_name','','k,v'); $c->insert($id,array(100500,'test\nvalue')); $response = $c->readResponse(); //return array() if OK
関連する推奨事項: 「mysqlチュートリアル」
以上がMySQL はどのように応答速度を向上させることができるかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。