序章
Webサイトが成長し、トラフィックが増加するにつれて、ストレスを最も早く示すコンポーネントの1つは、バックエンドデータベースです。 データベースが分散されておらず、高負荷を処理するように構成されていない場合、トラフィックの比較的穏やかな増加に簡単に圧倒される可能性があります。
これに対処する1つの方法は、memcachedなどのメモリオブジェクトキャッシュシステムを利用することです。 Memcachedは、通常はデータベースから取得される情報をメモリに一時的に保存することで機能するキャッシュシステムです。 インメモリ情報の次のリクエストは、バックエンドデータベースにストレスをかけることなく、信じられないほど高速になります。
このガイドでは、Ubuntu14.04サーバーにmemcachedをインストールして使用する方法について説明します。
前提条件
始める前に、サーバー上にsudo
権限にアクセスできる通常の非rootユーザーが必要です。 そのようなユーザーをまだ作成していない場合は、Ubuntu 14.04の初期セットアップガイドの手順1〜4に従って作成できます。
通常のユーザーを構成したら、このガイドを続けてください。
Memcachedとコンポーネントをインストールします
開始するには、Ubuntuのリポジトリから必要なすべてのコンポーネントを取得する必要があります。 幸いなことに、必要なものはすべて利用できます。
これは、このセッションでのapt
を使用した最初の操作であるため、ローカルパッケージインデックスを更新する必要があります。 次に、プログラムをインストールできます。
相互作用を処理するために、memcached、MySQLデータベースバックエンド、およびPHPをインストールします。 また、memcachedインタラクションを処理するPHP拡張機能もインストールしています。 次のように入力することで、必要なものをすべて入手できます。
sudo apt-get update sudo apt-get install mysql-server php5-mysql php5 php5-memcached memcached
利用可能な*2つの"PHPmemcache拡張機能があることに注意してください。 1つはphp5-memcache
と呼ばれ、もう1つはphp5-memcached
と呼ばれます(2番目の例の末尾の「d」に注意してください)。 安定しており、より幅広い機能を実装しているため、これらの2番目を使用しています。
MySQLをまだインストールしていない場合、インストールにより、管理者のパスワードを選択して確認するように求められます。
これにより、必要なものがすべてインストールおよび構成されます。
インストールを確認してください
信じられないかもしれませんが、memcachedはすでに完全にインストールされており、すぐに使用できます。 これはさまざまな方法でテストできます。
最初の方法はかなり簡単です。 PHPに、memcached拡張機能について知っているかどうか、およびそれが有効になっているかどうかを尋ねることができます。 これを行うには、ユビキタスなPHP情報ページを作成します。
これは、ドキュメントルートにinfo.php
というファイルを作成することで簡単に実現できます。 Ubuntu 14.04のApacheでは、デフォルトのドキュメントルートは/var/www/html
です。 ここでroot権限でファイルを開きます。
sudo nano /var/www/html/info.php
このファイルに、これを入力します。 これは基本的に、サーバーに関する情報を収集してWeb対応のレイアウトに出力するPHP関数を呼び出すだけです。
<?php phpinfo(); ?>
これで、サーバーのドメイン名またはパブリックIPアドレスに続いて/info.php
にアクセスでき、情報ページが表示されます。
http:// server_domain_name_or_IP /info.php
下にスクロールするか、「memcached」セクションヘッダーを検索すると、次のようなものが見つかります。
これは、memcached拡張機能が有効になっていて、Webサーバーによって検出されていることを意味します。
次のように入力して、memcachedサービスが実行されているかどうかを確認することもできます。
ps aux | grep memcached
memcache 6584 0.0 0.0 327448 3004 ? Sl 14:07 0:00 /usr/bin/memcached -m 64 -p 11211 -u memcache -l 127.0.0.1 demouser 6636 0.0 0.0 11744 904 pts/0 S+ 14:29 0:00 grep --color=auto memcached
次のように入力して、サービスの統計を照会できます。
echo "stats settings" | nc localhost 11211
memcachedサービスを停止、開始、または再起動する必要がある場合は、次のように入力して実行できます。
sudoサービスmemcached再起動
Memcachedがデータをキャッシュできるかどうかをテストする
memcachedが実行されていること、およびmemcachedに接続するためのPHP拡張機能が有効になっていることを確認したので、データを保存するためにmemcachedを取得してみることができます。
これを行うには、別のPHPスクリプトを作成します。 今回はもっと複雑になります。
ドキュメントルートでcache_test.php
というファイルを開きます。
sudo nano /var/www/html/cache_test.php
内部では、PHPラッパータグを作成することから始めます。
これらの中で、PHP Memcachedオブジェクトの新しいインスタンスを作成し、それを変数に格納します。 このPHPオブジェクトがサーバーで実行されている実際のmemcachedサービスに接続できる場所を定義します。 Memcachedはデフォルトでポート11211
で実行されます。
$ mem = new Memcached(); $ mem-> addServer(“ 127.0.0.1”、11211); ?>
次に、Memcachedインスタンスに、キャッシュからキーをクエリするように指示します。 このキーはまだ作成していないので、何とでも呼ぶことができます。 「何とか」を使用します。 このリクエストの結果は、$result
変数に保存されます。
addServer(“ 127.0.0.1”、11211); $ result = $ mem-> get( "blah"); ?>
次に、何かが返されたかどうかをテストする必要があります。 memcachedが「blah」というキーを見つけた場合、そのキーに関連付けられた値を出力する必要があります。 memcachedが一致するキーを見つけることができなかった場合は、そのことを示すメッセージを出力する必要があります。
次に、キーに値を設定して、次に値を要求したときにmemcachedが指定した値を検出できるようにする必要があります。
addServer(“ 127.0.0.1”、11211); $ result = $ mem-> get( "blah"); if($ result){ echo $ result; } else { echo“一致するキーが見つかりません。 今すぐ追加します!」; $ mem-> set( "blah"、 "私はデータです! memcachedに保持されています!」)またはdie(「memcachedに何も保存できませんでした…」); } ?>
この時点で、スクリプトは完了です。 Webブラウザーでこのページにアクセスすると、これがどのように機能するかを確認できます。
http:// server_domain_name_or_IP /cache_test.php
最初は次のようなページが表示されます。
ただし、ページを更新すると、別のメッセージが表示されます。
ご覧のとおり、memcachedサービスは、スクリプトが設定したデータをキャッシュしています。
データベース値を一時的にキャッシュするテスト
memcachedにデータを保存する機能をテストしたので、より現実的なシナリオを示すことができます。データベースクエリからの結果を一時的にキャッシュします。
MySQLでサンプルデータを作成する
これを行うには、最初にデータベースにいくつかの情報を保存する必要があります。
これを入力して、管理ユーザーとしてMySQLインスタンスに接続します。 インストール時に設定したMySQLルートパスワードを入力する必要があります。
mysql -u root -p
その後、MySQLプロンプトが表示されます。
まず、テストするデータベースを作成します。 次に、データベースを選択します。
CREATE DATABASE mem_test; USE mem_test;
作成したデータベースにアクセスできるパスワードtesting123
を使用してtest
というユーザーを作成しましょう。
GRANT ALL ON mem_test.* TO test@localhost IDENTIFIED BY 'testing123';
次に、非常に基本的なテーブルを作成し、それにレコードを挿入します。 テーブルはsample_data
と呼ばれ、インデックスと文字列フィールドのみが含まれます。
CREATE TABLE sample_data (id int, name varchar(30)); INSERT INTO sample_data VALUES (1, "some_data");
これで、構造が作成され、データが挿入されました。 MySQLを終了できます。
exit
MySQLデータをキャッシュするPHPスクリプトを作成する
MySQLにデータが入ったので、本番PHPアプリケーションと同じように動作する別のPHPスクリプトを作成できます。
memcachedでデータを検索し、データが見つかった場合はそれを返します。 データが見つからない場合は、データベース自体からクエリを実行し、将来のクエリのために結果をmemcachedに保存します。
まず、ドキュメントルートに別のPHPスクリプトを作成します。 このスクリプトをdatabase_test.php
と呼びます。
sudo nano /var/www/html/database_test.php
最後のスクリプトと同様の方法で開始します。 PHP memcachedインスタンスを作成し、前回と同じように、サーバーで実行されているmemcachedサービスがどこにあるかを通知します。
addServer(“ 127.0.0.1”、11211); ?>
次に、前回のスクリプトからの最初の出発点として、PHPがMySQLデータベースに接続する方法を定義する必要があります。 作成したユーザーのログイン資格情報を指定する必要があります。次に、使用するデータベースを指定する必要があります。
addServer(“ 127.0.0.1”、11211); mysql_connect( "localhost"、 "test"、 "testing123")またはdie(mysql_error()); mysql_select_db(“ mem_test”)またはdie(mysql_error()); ?>
次に、テーブルに挿入したデータをフェッチするために必要なクエリを設計する必要があります。 これを$query
変数に格納します。
次に、$querykey
変数を作成して、memcachedが情報を参照するために使用するキーを保存します。
このキーは、文字列「KEY」を使用して作成し、クエリのmd5(ハッシュメソッド)チェックサムを最後に追加します。 これにより、より大きなデータセットでこの手法を使用する場合に、各キーが一意になります。 また、一致するクエリが後続のリクエストに対して同じキーを生成することも保証します。
addServer(“ 127.0.0.1”、11211); mysql_connect( "localhost"、 "test"、 "testing123")またはdie(mysql_error()); mysql_select_db(“ mem_test”)またはdie(mysql_error()); $ query =“ SELECT ID FROM sample_data WHERE name ='some_data'”; $ querykey =“ KEY”。 md5($ query); ?>
次に、最後のスクリプトと同じように、$result
変数を作成します。 これにより、以前と同じように、memcachedクエリの結果が保持されます。 生成したクエリキーをmemcachedに要求して、システム内でそのキーによって識別されるレコードがあるかどうかを確認します。
addServer(“ 127.0.0.1”、11211); mysql_connect( "localhost"、 "test"、 "testing123")またはdie(mysql_error()); mysql_select_db(“ mem_test”)またはdie(mysql_error()); $ query =“ SELECT name FROM sample_data WHERE id = 1”; $ querykey =“ KEY”。 md5($ query); $ result = $ mem-> get($ querykey); ?>
これで、結果がmemcachedで見つかったときに何が起こるかを決定する実際のテストロジックを実行する準備が整いました。 結果が見つかった場合は、引き出したデータを印刷して、memcachedから直接取得できたことをユーザーに通知します。
addServer(“ 127.0.0.1”、11211); mysql_connect( "localhost"、 "test"、 "testing123")またはdie(mysql_error()); mysql_select_db(“ mem_test”)またはdie(mysql_error()); $ query =“ SELECT name FROM sample_data WHERE id = 1”; $ querykey =“ KEY”。 md5($ query); $ result = $ mem-> get($ querykey); if($ result){ print " データは次のとおりです:"。 $result[0]。 「「 」; 印刷「 キャッシングの成功! memcachedからデータを取得しました! 」; } ?>
次に、代替シナリオのロジックを追加しましょう。 結果が見つからない場合は、作成したクエリを使用してMySQLにデータを要求します。 これを作成した$result
変数に格納します。 これは配列の形式になります。
クエリの結果を取得したら、その結果をmemcachedに追加して、次にデータがそこにあるようにする必要があります。 これを行うには、データ($querykey
変数で既に作成済み)、データ自体($result
変数に格納されている)を参照するために使用するキーをmemcachedにフィードします。 MySQLクエリ)、およびデータをキャッシュする時間(秒単位)。
コンテンツを10秒間キャッシュします。 現実の世界では、コンテンツをより長くキャッシュすることが最も有益である可能性があります。 コンテンツがあまり変わらない場合は、おそらく10分(600秒)に近いものです。 テストの場合、値を小さくすると、memcachedサービスを再起動しなくても、何が起こっているかをより速く確認できます。
その後、クエリ結果とともに同様のメッセージを出力し、何が起こったかをユーザーに通知します。 このブロック全体を、以前のif
のelse
として追加する必要があります。
addServer(“ 127.0.0.1”、11211); mysql_connect( "localhost"、 "test"、 "testing123")またはdie(mysql_error()); mysql_select_db(“ mem_test”)またはdie(mysql_error()); $ query =“ SELECT name FROM sample_data WHERE id = 1”; $ querykey =“ KEY”。 md5($ query); $ result = $ mem-> get($ querykey); if($ result){print " データは次のとおりです:"。 $result[0]。 「「 」; 印刷「 キャッシングの成功! memcachedからデータを取得しました! 」; } else { $ result = mysql_fetch_array(mysql_query($ query))またはdie(mysql_error()); $ mem-> set($ querykey、$ result、10); 印刷" データは次のとおりです:"。 $result[0]。 「「 」; 印刷「 memcachedにデータが見つかりません。 MySQLから取得され、次回のためにmemcachedに保存されたデータ。 」; } ?>
これが完成したスクリプトです。 memcachedからデータを取得して返します。 これに失敗すると、MySQLから直接クエリを実行し、結果を10秒間キャッシュします。
スクリプトをテストする
スクリプトが作成されたので、Webブラウザのファイルの場所に移動してスクリプトを実行できます。
http:// server_domain_name_or_IP /database_test.php
このページに初めてアクセスすると、次のような出力が表示されます。
これを更新すると(最後の訪問から10秒以内)、ページに別のメッセージが表示されます。
もう一度待つと、キャッシュされたコンテンツは期限切れになり、memcachedから再び削除されます。 サーバーは適切な値を取得するためにデータベースに戻る必要があるため、この時点で更新して最初のメッセージを再度取得できます。
結論
これまでに、memcachedがどのように機能するか、およびmemcachedを活用して、Webサーバーが同じコンテンツに対してデータベースに繰り返しアクセスしないようにする方法を十分に理解しているはずです。
このガイドで作成したPHPスクリプトは単なる例ですが、システムがどのように機能するかについての良いアイデアを提供するはずです。 また、memcachedを確認し、必要に応じてデータベースにフォールバックできるように、コードを構造化する方法についての良いアイデアも得られるはずです。