システム構築が終わったので、試運転してみましょう。
実際のシステムではWebサーバからPHPやJavaなどでPostgreSQLとmemcachedにアクセスしますが、ここでは説明を簡略化するため、psqlから直接アクセスします。適宜お使いの言語でアクセスすることを念頭にサンプルのSQLをご覧ください注2。
注2)PHPでの接続方法については前編「memcached+PostgreSQLで実現するハイパフォーマンスWebアプリケーション構築」コラム1:PHPからmemcachedを使うを参照ください。
ユーザーデータをテーブル「userlist」に登録します。
testdb=# INSERT INTO userlist VALUES (1234, true, 'デューク東郷', 'GOLGO13', 2, 'gol13.jpg'); INSERT 0 1
せっかくなので、memcache_get()を使って、memcachedにデータが保存されたかどうか確認してみましょう。
testdb=# SELECT memcache_get('1234'); memcache_get --------------------- GOLGO13,2,gol13.jpg (1 row)
ニックネーム=「GOLGO13」、友人数=「2」、写真=「gol13.jpg」がカンマ(,)で連結されて登録されていることが分かります。
次に、ユーザーデータを更新してみます。friends_numを2から0に更新します。
testdb=# UPDATE userlist SET friends_num = 0 WHERE uid = 1234; UPDATE 1
同様にmemcachedを確認すると、更新が反映されていることが分かります。
testdb=# SELECT memcache_get('1234'); memcache_get --------------------- GOLGO13,0,gol13.jpg (1 row)
最後に退会です。テーブルuserlistのflagをfalseに更新すると、memcachedからuid=1234のデータが削除されます。
testdb=# UPDATE userlist SET flag = false WHERE uid = 1234; UPDATE 1 testdb=# SELECT memcache_get('1234'); memcache_get -------------- (1 row)
実運用で必須の、memcachedの初期化とデータの定期再登録を行う関数を定義して説明を締めたいと思います。
システムを起動するときにmemcached上にデータをアップロードしなければならないのは当然ですが、データの定期再登録とは何でしょうか?
memcachedを長期間連続運用する場合、メモリ上にデータがゴミとして残っては困るので、データの登録には必ずexpire時間を設定することが推奨されています。しかしexpire時間を設定すると、今度は必ずある時点でデータが消えてしまいます。そのため、expire時間よりも短い時間間隔でデータを再登録する必要があるのです。
下に示すのが、そのための関数userlist_upload()です。
01: CREATE FUNCTION userlist_upload() RETURNS int AS 02: $$ 03: DECLARE 04: c int; 05: id userlist.uid%TYPE; 06: flg userlist.flag%TYPE; 07: nm userlist.nickname%TYPE; 08: fn userlist.friends_num%TYPE; 09: ph userlist.photo%TYPE; 10: data text; 11: cur CURSOR FOR SELECT uid, flag, nickname, friends_num, photo FROM userlist; 12: BEGIN 13: c := 0; 14: 15: OPEN cur; 16: 17: LOOP 18: FETCH cur INTO id, flg, nm, fn, ph; 19: EXIT WHEN NOT FOUND; 20: IF flg != FALSE THEN 21: data := nm || ',' || fn || ',' || ph; 22: PERFORM memcache_set(id::TEXT, data, INTERVAL '2 days'); 23: c := c + 1; 24: END IF; 25: END LOOP; 26: 27: CLOSE cur; 28: 29: RETURN c; 30: END; 31: $$ 32: LANGUAGE 'plpgsql';
この関数はカーソルを使ってテーブルuserlistを全件検索し、1件1件のデータをmemcachedに再登録します。
実行はSELECT文を使って次のように実行するか、定期的にバッチ処理として実行します。
testdb=# BEGIN; BEGIN testdb=# SELECT userlist_upload(); userlist_upload ----------------- 54321 (1 row) testdb=# COMMIT; COMMIT
以上で、pgmemcacheを使ってPostgreSQLからmemcachedを使う方法、およびPostgreSQLとmemcachedを連携させる方法を説明しました。
前編で述べたようにpgmemcacheは歴史あるライブラリです。pgmemcacheはmemcachedを利用するに十分な機能を有し、すでに「枯れた」ライブラリとして実運用にも十分堪える品質を持っています。
pgmemcacheは2007年3月以降開発が停止していますが、現状をメンテナーのN.Conway氏に尋ねたところ、「現在はサン・マイクロシステムのJ.Gates氏がlibmemcached対応を検討している」とのことです。詳細はまだ不明ですが、libmemcacheからlibmemcachedへの対応が試みられている模様です。
また、筆者は別のアプローチとして、libmemcachedの関数群を直接利用できる「pgmemcached」を作ってみました。
pgmemcached
http://www.interdb.jp/techinfo/pgmemcached/
APIは今回説明したpgmemcacheと異なりますが、libmemcachedの多くの関数が利用でき、また、エラーハンドリング機能も実装できます。ご興味のある方は上記URLにアクセスしてみてください。
鈴木 啓修
某電器メーカーの研究員を皮切りにエンジニアとしてのキャリアを重ねる。データベース、OS、分散システム、プログラム検証論、形式的仕様記述、関数型言語、スペイン移住に興味がある。
著書に『PostgreSQL完全機能リファレンス』(秀和システム)、『MySQL全機能リファレンス』(技術評論社)、『標準PostgreSQL』(ソフトバンククリエイティブ)などがある。
Copyright © ITmedia, Inc. All Rights Reserved.