PHP を使用した memcache キャッシュの例の詳細な説明。この記事では、これまでほとんど使用したことのない多くの利用可能な拡張機能を使用します。これは PHP の共有メモリにも当てはまります。いくつかの共有機能を使用すると、開発者は拡張機能をインストールせずにメモリ セグメントを簡単に操作できます。
概要
共有メモリは、同じマシン内のアプリケーション間でデータを交換する効率的な方法です。プロセスは、正しい権限が割り当てられている限り、他のプロセスがアクセスできるメモリ セグメントを作成できます。各メモリ セグメントには、他のプロセスが動作できる物理メモリの領域を指す一意の ID (shmid と呼ばれる) があります。作成され、適切な権限が与えられると、同じマシン上の他のプロセスがこれらのメモリ セグメント上で読み取り、書き込み、削除を実行できるようになります。
これは、C で書かれたアプリケーションが、Java™ や PHP などの他の言語で書かれたアプリケーションと情報を共有できることを示しています。情報にアクセスして理解できる限り、全員が情報を共有できます。共有メモリはほとんどの言語の実装で広く使用されているため、アクセスは問題になりません。情報を理解するには、XML や JSON などの標準形式を使用できます。
共有メモリの使用は、主にメモリセグメントの作成後にカーネルを介さずにデータが渡されるため、プロセス間でデータを高速に交換する方法です。この方法は、プロセス間通信 (IPC) と呼ばれることがよくあります。他の IPC メソッドには、パイプ、メッセージ キュー、RPC、ソケットなどがあります。アプリケーション間でデータを迅速かつ確実に交換できるこの機能は、相互に通信する必要があるアプリケーションのエコシステムを操作する場合に役立ちます。エコシステムの規模によっては、データベースを使用してアプリケーション間で情報を交換する一般的な方法では、クエリが遅くなったり、I/O ブロックが発生したりする場合があります。共有メモリを使用すると、開発者の進行を遅らせる I/O が発生しません。
この記事の提案は非常にシンプルです。PHP を使用して共有メモリ セグメントを作成および操作し、それらを使用して他のアプリケーションで使用できるデータ セットを保存する方法を学びます。データ交換に共有メモリを使用する予定がない場合でも、アプリケーションが I/O の問題を回避できるため、それ自体に多くの利点があります。データセットをメモリに直接保存すると、Web サービス データのキャッシュからセッション共有まで、多くの利点があります。これは、すべての PHP 開発者が知っておくべき非常に便利な概念です。
共有メモリとPHP
PHP には豊富な拡張機能が用意されており、共有メモリも同様です。いくつかの共有機能を使用すると、開発者は拡張機能をインストールせずにメモリ セグメントを簡単に操作できます。
トップに戻る
メモリセグメントを作成する
共有メモリ関数はファイル操作関数に似ていますが、ストリームを処理する代わりに、共有メモリ アクセス ID を処理します。最初の例は shmop_open 関数です。この関数を使用すると、既存のメモリ セグメントを開いたり、新しいメモリ セグメントを作成したりできます。この関数は、ファイル操作用のストリームを開き、開かれたストリームへの読み取りまたは書き込みを行う他の関数が使用するリソースを返す、古典的な fopen 関数に非常に似ています。リスト 1 の shmop_open を見てみましょう。
リスト 1. shmop_open 関数
コードは次のとおりです | コードをコピー |
$systemid = 864; // 共有メモリセグメントのシステムID ?>
|
コードは次のとおりです | コードをコピー |
$shmid = shmop_open(864, 'c', 0755, 1024); ?> |
この関数は fwrite 関数に似ており、オープン ストリーム リソース (fopen によって返される) と書き込みたいデータという 2 つのパラメーターを受け取ります。 shmop_write 関数もこのタスクを実行します。
最初のパラメータは shmop_open によって返される ID で、操作している共有メモリ ブロックを識別します。 2 番目のパラメータは保存したいデータで、最後の 3 番目のパラメータは書き込みを開始する位置です。デフォルトでは、書き込みを開始する場所を示すために常に 0 を使用します。この関数は失敗すると FALSE を返し、成功すると書き込まれたバイト数を返すことに注意してください。
トップに戻る
メモリセグメントからデータを読み取る
共有メモリセグメントからのデータの読み取りは簡単です。必要なのは、開いているメモリ セグメントと shmop_read 関数だけです。この関数はいくつかのパラメータを受け取り、fread のように動作します。 PHP ファイルの内容を読むには、リスト 3 を参照してください。
リスト 3. shmop_read を使用してファイルの内容を読み取る
コードは次のとおりです | コードをコピー |
$stream = fopen('file.txt', 'r+'); ?> |
リスト 4 に示すように、共有メモリ セグメントの内容を読み取るプロセスも同様です。
リスト 4. 共有メモリセグメントの内容を読み取る
コードは次のとおりです | コードをコピー |
$shmid = shmop_open(864, 'c', 0755, 1024); ?> |
ここのパラメータに注意してください。 shmop_read 関数は shmop_open によって返される ID を受け入れますが、これはすでにわかっていますが、他の 2 つのパラメータも受け入れます。 2 番目のパラメータは読み取りたいメモリ セグメント内の場所で、3 番目のパラメータは読み取りたいバイト数です。 2 番目のパラメータは常にデータの始まりを示す 0 にすることができますが、3 番目のパラメータは読み込むバイト数がわからないため、問題が発生する可能性があります。
これは fread 関数で行うことと非常に似ており、オープン ストリーム リソース (fopen によって返される) とストリームから読み込むバイト数という 2 つのパラメーターを受け取ります。ファイルを完全に読み取るには、filesize 関数 (ファイル内のバイト数を返す) を使用します。
幸いなことに、共有メモリ セグメントを使用する場合、shmop_size 関数は filesize 関数と同様にメモリ セグメントのサイズをバイト単位で返します。リスト 5 を参照してください。
リスト 5. shmop_size 関数はメモリセグメントのサイズをバイト単位で返します
コードは次のとおりです | コードをコピー |
$shmid = shmop_open(864, 'c', 0755, 1024); $size = shmop_size($shmid); ?> |
トップに戻る
メモリセグメントを削除します
共有メモリセグメントを開いたり、書き込んだり、読み取ったりする方法を学びました。 CRUD クラスを完了するには、メモリ セグメントを削除する方法も学習する必要があります。このタスクは、shmop_delete 関数を使用して簡単に実行できます。この関数は、削除する共有メモリの ID という 1 つのパラメータのみを受け入れます。
リスト 6. shmop_delete は、削除するメモリセグメントをマークします
コードは次のとおりです | コードをコピー |
$shmid = shmop_open(864, 'c', 0755, 1024); ?> |
これは実際にメモリセグメントを削除するわけではありません。共有メモリ セグメントは、別のプロセスが使用している間は削除できないため、メモリ セグメントに削除のマークが付けられます。 shmop_delete 関数は、メモリ セグメントを削除対象としてマークし、他のプロセスがメモリ セグメントを開くのを防ぎます。それを削除するには、そのメモリセグメントを閉じる必要があります。
トップに戻る
メモリセグメントを閉じる
共有メモリセグメントを開くと、そのセグメントに「接続」されます。このメモリ セグメントを接続した後は、読み書きすることができますが、完了したらメモリ セグメントから切り離す必要があります。これは、リスト 7 の shmop_close 関数を使用して行われます。
これは、ファイルを操作するときの fclose 関数に非常に似ています。ファイルを含むストリームを開いてデータを読み書きした後は、ストリームを閉じる必要があります。閉じないとロックが発生します。
リスト 7. shmop_close を使用したメモリーセグメントの切り離し
コードは次のとおりです | コードをコピー |
$shmid = shmop_open(864, 'c', 0755, 1024); ?> |
トップに戻る
ストレージオプションとして共有メモリを使用する
共有メモリおよび共有メモリ セグメントに対する基本的な CRUD 操作に関する基礎知識があれば、この知識を応用してみましょう。共有メモリを独自のストレージ オプションとして使用すると、高速な読み取り/書き込み操作やプロセスの相互運用性などの利点が得られます。 Web アプリケーションの場合、これは次のことを意味します:
•キャッシュ ストレージ (データベース クエリ、Web サービス データ、外部データ)
• セッションストレージ
•アプリケーション間のデータ交換
先に進む前に、SimpleSHM という小さなライブラリを紹介したいと思います。 SimpleSHM は、PHP を使用して共有メモリを操作するためのより小さな抽象化レイヤーであり、オブジェクト指向の方法でメモリ セグメントを簡単に操作できるようにします。このライブラリは、ストレージとして共有メモリを使用する小さなアプリケーションを作成するときに、非常に簡潔なコードを作成するのに役立ちます。 SimpleSHM について詳しくは、GitHub ページにアクセスしてください。
処理には読み取り、書き込み、削除の 3 つの方法を使用できます。このクラスからオブジェクトをインスタンス化するだけで、オープン共有メモリ セグメントを制御できます。リスト 8 に基本的な使用法を示します。
リスト 8. SimpleSHM の基本的な使用法
コードは次のとおりです | コードをコピー |
$memory = 新しい SimpleSHM; ?> |
このクラスにはIDは渡されませんのでご注意ください。 ID が渡されない場合は、ランダムに番号が選択され、その番号で新しいメモリ セグメントが開きます。コンストラクターにパラメーターとして数値を渡して、既存のメモリー・セグメントを開いたり、特定の ID を持つメモリー・セグメントを作成したりできます (リスト 9 を参照)。
リスト 9. 特定のメモリセグメントを開く
コードは次のとおりです | コードをコピー |
$new = 新しい SimpleSHM(897); ?> |
マジック メソッド __destructor は、そのメモリ セグメント上で shmop_close を呼び出して、そのメモリ セグメントから切り離すオブジェクトの設定を解除します。これを「SimpleSHM 101」と呼びます。次に、この方法をより高度な用途に応用してみましょう。共有メモリをストレージとして使用します。配列やオブジェクトはメモリに保存できないため、データセットを保存するにはシリアル化が必要です。ここではシリアル化に JSON が使用されていますが、他の方法 (XML や組み込みの PHP シリアル化機能など) でも十分です。リスト 10 に例を示します。
リスト 10. ストレージとして共有メモリを使用する
コードは次のとおりです | コードをコピー |
require('SimpleSHM.class.php'); $results = array( $data = json_encode($results); $memory = 新しい SimpleSHM; print_r($storedarray); ?> |
配列を JSON 文字列にシリアル化し、共有メモリ ブロックに保存し、そこからデータを読み取り、JSON 文字列を逆シリアル化し、保存された配列を表示することに成功しました。これは単純なことのように思えますが、このコード スニペットで可能性を想像してみてください。これを使用して、Web サービス リクエスト、データベース クエリ、さらにはテンプレート エンジン キャッシュからの結果を保存できます。メモリ内での読み取りと書き込みは、ディスクでの読み取りと書き込みよりもパフォーマンスが高くなります。
このストレージ テクノロジーの使用は、データが両端で読み取り可能な形式で保存されている限り、キャッシュだけでなく、アプリケーション間のデータ交換にも役立ちます。 Web アプリケーションの共有メモリの力を過小評価しないでください。このストレージを賢く実装するにはさまざまな方法がありますが、唯一の制限は開発者の創造性とスキルです