日本 HP OpenSource/Linux 技術文書 Memcached による Web サービスの高速化 日本ヒューレット パッカード株式会社 2011 年 6 月 17 日
目次 [ 本ドキュメントについて ]... 4 Memcached について... 5 一般的な memcached のシステム構成... 5 実際の memcached のシステム構成... 6 システム構成... 6 MySQL サーバーの準備... 7 2
図表目次 図 1. memcached サーバーを取り入れた LAMP スタックのシステム構成例... 5 図 2. 64 台の memcached サーバーを取りいれた LAMP 構成例... 6 図 3. Memcached サーバー on HP ProLiant SL6500 のシステム構成例... 7 図 4. MySQL に作成されたデータベース testdb 上のテーブル tbl2 を複数の memcached サーバーにキャッシュする mc.py... 10 3
[ 本ドキュメントについて ] 本ドキュメントでは MySQL サーバーのみでの作業を (MY) Memcached サーバーのみでの作業を (MC) MySQL サーバーと Memcached サーバー両方での作業を (MY,MC) と記すことにします 例 1) ファイルをコピーします (MY) と記載してあるものは MySQL サーバーだけでファイルをコピーするという意味になります 例 2) rpm コマンドでパッケージをインストールします (MY,MC) と記載してあるものは MySQL サーバーと Memcached サーバーの両方で rpm コマンドを使ってインストールを行うという意味になります コマンドラインでの入力が長く紙面の都合で折り返して記載する場合は 下記のように \ 記号を挿入して複数行にわたって記載しています 複数行にわたって記載されていても実際には 1 行で入力するものは その記述の最後に ( 実際には 1 行で入力 ) を挿入しています 例 3) > grant all privileges on testdb.* to root@localhost \ identified by 'password123' with grant option; 本ドキュメントの内容については充分チェックをしておりますが その正確性を保証する物ではありません また 将来 予告なしに変更することがあります 本ドキュメントの使用で生じるいかなる結果も利用者の責任となります 日本ヒューレット パッカード株式会社は 本ドキュメントの内容に一切の責任を負いません 本ドキュメントの技術情報は ハードウェア構成 OS アプリケーションなど使用環境により大幅に数値が変化する場合がありますので 十分なテストを個別に実施されることを強くお薦め致します 本ドキュメント内で表示 記載されている会社名 サービス名 商品名等は各社の商標又は登録商標です 本ドキュメントで提供する資料は 日本の著作権法 条約及び他国の著作権法にいう著作権により保護されています 4
本ドキュメントは MySQLのデーータベースをキャッシュする memcached をHP ProLiantサーバー上に構築し アプリケーションサーババーからmemcached が提供するキャッシュデータをアアクセスできるようにするガイドです memcached は現時点でのリリースの最新版です Memcached はオープンソースで提供されるソフトウェアですのので 本番商用利用についてはサポート面やバグフィィックス等の不具合対応について検討が必要とななりますので十分ご注意ください Memcached について Memcached は データベースにに保存されている Web コンテンツをメモリ上にキャャッシュすることによりスループットを改善するオオープンソースソフトウェアです MySQL や PostgreSQL データベースのボトルネックの解消に利用さされます 一般的に Web ブラウザを閲覧するユーザザーがクリックを行って 5 秒以上経過すると他のササイトに移動してしまう傾向があります この課題題に対応するため Web サーバーの応答性能を向上上させる必要があり ユーザーアクセスが多い場合 memcached によるスループット向上が欠かせませせん Memcached を導入しない解決策の一つは 負負荷分散装置の導入です MySQL や PostgreSQL データベースには マスター スレーブ方式をとるこことがありますが このマスタースレーブ方式でボボトルネックが発生する可能性があります MySQL や PostgreSQL では マスターサーバーがユーザーののトランザクションの書き込み処理を行い 複数ののスレーブサーバーが読み込み処理を担当します 読み込みが多いシステムでは MySQL や PostgreSQL のスレーブサーバーを増やすことでスループットトを向上させる試みがありますが データベースササイズが肥大化 低速になるというボトルネックをを抱えており Web サービスの応答速度の低下を招くく問題があります LAMP(Linux/Apache/MySQL/PHP) の構成において Memcached を利用することで読みみ込み性能の向上が可能です 一般的に SQL でも高高速化手法が存在しますが SQL キャッシュは分散散データベースには対応していません 一方 memcached は分散データベースで高速化できるように設設計されています Memcached は Wikipedia facebook Myspace Livejournal Digg Slashdot などの Web サイトで採用されており 非常に大規模模なシステムでも実用に耐えるものとなっています 一般的な memcached のシステム構成 memcachedはデータベースサーババーのデータをメモリ上にキャッシュするため デデータベースと並列に並べます データベースのデデータをmemcached サーバーにキャッシュするためにには アプリケーションサーバー側で memcached サーーバーにデータをセットするようにします 図 1. memcached サーバーを取り入れた LAMP スタックのシステム構構成例 5
実際の memcached のシステム システム構成 実際には マスターデータベースとスレーブデータベースからなる マスターデータベースとスレーブデータベースからなる分散データベースや データベースや HA クラ スターを構成したデータベースシステムの したデータベースシステムの3 層構成に 高密度サーバーをmemcached memcached に実装し アプリケーションサーバーで memcached サーバーにキャッシュするようにアプリケーションを 構成します 以下は memcached memcached サーバーを 64 台で構成した場合のシステム構成例 構成例です 図中 の右下に HP BladeSystem による memcached サーバーが構成されており データベースのスレー ブノードのデータをキャッシュします ブノードのデータをキャッシュします memcached サーバーへのキャッシュを行うアプリケー サーバーへのキャッシュを ションは 図中の中央の HP BladeSysytem のアプリケーションサーバーで実行 実行されます 図 2. 64 台の の memcached サーバーを取りいれた LAMP 構成例 システム構成 以下にMemcachedをインストールする をインストールする環境を示します ハードウェア OS memcached MySQL : HP ProLiant SL6500 SL6500シリーズ : Red Hat Enterprise Linux 5.6 x86-64 MySQLサーバー Memcached Memcachedサーバー : 1.4.5 : 5.0.77 (RHEL OS OSに付属のもの) します 今回の構成ではMySQLサーバーの可用性は考慮 考慮していないため 以下にハードウェア外観を示します MySQLサーバーの障害時のデータロストが のデータロストが発生するSPOFが存在する点にご注意ください ください またアプリ ケーションサーバーを別途用意 別途用意していない点も本番環境とは異なることに注意して して下さい 6
Proof Of Concept 構成 MySQL サーバーは 1 台構成 MySQL サーバーの可用性はない MySQL は RHEL OS 付属のものを使用しており テスト動作作確認用 左図はアプリケーーションサーバーと MySQL サーバーが兼用になっているが 本番環境では分分ける必要がある Memcached は RPM パッケージを利用 Memcacahed のキャッシュサイズは 10GB を設定 図 3. Memcached サーバー on HP ProLiant SL6500 のシステム構構成例 MySQL サーバーの準備 本ドキュメントに記載している memcached サーバーの設定手順を行う前に MySQLサーバーの OSのインストールと事前準備を済ませせておく必要があります データベースサーバーとなるママシンに MySQL をインストールします (MY) # rpm vhi mysql-5.0.77-4.el l5_5.4.x86_64.rpm mysql-server-5.0.77-4.el5_5..4.x86_64.rpm # chkconfig mysqld on # service mysqld start 依存関係を満たすため 以下の RPMパッケージを入手します (MC) http://packages.sw.be/perl-n Net-SSLeay/perl-Net-SSLeay-1.36-1.el5.rfx.x86 64.rpm Red Hat Enterprise Linuxのインストール DVDから以下のパッケージをインストーールします (MC) # rpm -vhi perl-io-socket-ss SL-1.01-1.fc6.noarch.rpm memcached RPMパッケージとそれれに関連する RPMパッケージをインストールします 本ドキュメントでは memcached へのアクセスにに利用するアプリケーションは Pythonで記述するとと想定し python-memcached RPMパッケーージをインストールします (MC) # rpm -vhi perl-net-ssleay-1 1.36-1.el5.rfx.x86_64.rpm # rpm -vhi perl-termreadkey- -2.30-4.el5.x86_64.rpm # rpm -vhi perl-guard-1.021- -1.el5.rf.x86_64.rpm # rpm -vhi compat-libevent-1 11a-3.2.1-1.el5.rf.x86_64.rpm # rpm -vhi perl-common-sense e-3.0-1.el5.rf.x86_64.rpm # rpm -vhi perl-ev-3.9-1.el5 5.rf.x86_64.rpm 7
# rpm -vhi perl-json-xs-2.30-1.el5.rf.x86_64.rpm # rpm -vhi perl-json-2.50-1.el5.rf.noarch.rpm # rpm -vhi perl-anyevent-5.240-1.el5.rf.noarch.rpm # rpm -vhi perl-yaml-0.72-1.el5.rf.noarch.rpm # rpm -vhi libmemcached-0.31-1.1.el5.x86_64.rpm # rpm -vhi memcached-1.4.5-1.el5.rf.x86_64.rpm # rpm -vhi python-memcached-1.47-1.el5.noarch.rpm memcached のパラメーターを設定します 設定ファイルは /etc/sysconfig/memcached になります /etc/sysconfig/memcached ファイルの中の CACHESIZE でキャッシュするメモリ容量を指定します 単位はギガバイトになります 例えば CACHESIZE="8192" と設定すると 1 台の memcached サーバーで 8GB のメインメモリをキャッシュ領域として利用することになります (MC) # vi /etc/sysconfig/memcached PORT="11211" USER="nobody" MAXCONN="1024" CACHESIZE="10240" OPTIONS="" memcached サーバーで memcached サービスを開始します (MC) # service memcached start MySQL サーバーを設定します 今回は memcached の簡易テスト用途ですので MySQL は Red Hat Enterprise Linux に含まれる標準の MySQL を利用します MySQL のサービスを起動します (DB) # service mysqld start MySQL の管理者のパスワードを設定します (MY) # mysqladmin -uroot -p'' password 'password123' MySQL にテスト用のデータベース testdb を作成します (MY) # mysqladmin -uroot -ppassword123 create testdb MySQL のデータベース testdb 内にテスト用のテーブル tbl2 を作成します (MY) # mysql -uroot -ppassword123 testdb >grant all privileges on testdb.* to root@localhost \ identified by 'password123' with grant option; >create table tbl2(id int, name char(10)); >insert into tbl2 values(1,"test1"); >insert into tbl2 values(2,"test2"); >insert into tbl2 values(3,"test3"); >flush privileges; >quit; # 8
データベース testdb にあるテーブル tbl2 が正常に作成されているかを確認します (MY) # mysqldump -uroot -ppassword123 testdb MySQL のデータベース testdb 上に作成したテーブル tbl2 のデータを memcached にキャッシュするための Python スクリプトを作成します 以下のスクリプト例では memcached サーバーが hd01~hd08 の 8 台の物理サーバーを想定しています (MY) # vi /root/mc.py #!/usr/bin/env python import sys, MySQLdb, memcache, commands, cgi hd01="172.16.1.1" hd02="172.16.1.2" hd03="172.16.1.3" hd04="172.16.1.4" hd05="172.16.1.5" hd06="172.16.1.6" hd07="172.16.1.7" hd08="172.16.1.8" USER="root" PASS="password123" TIME=20 #20sec DBNAME="testdb" TABLENAME="tbl2" m = memcache.client([ "hd01:11211", "hd02:11211", "hd03:11211", "hd04:11211", "hd05:11211", "hd06:11211", "hd07:11211", "hd08:11211" ]); try: sql=mysqldb.connect( host ="localhost", user =USER, passwd =PASS, db =DBNAME) except MySQLdb.Error, e: print "Error %d: %s" % (e.args[0], e.args[1]); sys.exit (1) t = m.get(tablename) if not t: selectdb="select * from " + TABLENAME cursor=sql.cursor(); cursor.execute(selectdb) row=cursor.fetchall() 9
for r in row: print "%d, %s" % (r[0], r[1]) m.set(tablename,row,time) print "Data updated into memcached" else: for row in t: print "%d, %s" % (row[0], row[1]) print "Data loaded from memcached" 図 4. MySQL に作成されたデータベース testdb 上のテーブル tbl2 を複数の memcached サーバーにキャッシュする mc.py MySQL サーバー上の testdb に作成された tbl2 のデータをキャッシュするために mc.py を実行します 通常はアプリケーションサーバー上で実行しますが 今回は システム構成の都合上 MySQL データベースサーバー上で実行します mc.py は MySQL に作成された tbl2 のデータが memcached サーバーにセットされると Data updated into memcached と表示するようにプログラムされています (MY) # python /root/mc.py Data updated into memcached スクリプト mc.py によって MySQL のデータを memcached サーバーにキャッシュしたかどうかを確認します Data loaded from memcached という出力は mc.py で記述したもので memcached サーバーからデータを取得した場合に表示されるようにプログラムされています (MY) # python /root/mc.py 1, Test1 2, test2 3, test3 Data loaded from memcached memcached サーバー上で memcat コマンドを使って memcached サーバーがデータをキャッシュしているかどうかを確認することができます (MC) # memcat --server=172.16.1.1 tbl2 ((L1L S'Test1' t(l2l S'test2' t(l3l S'test3' ttp1 memcached サーバー上で memcat コマンドを使ってデータが表示されない場合はキャッシュされていないことを意味します (MC) # memcat --server=172.16.1.2 tbl2 以上 10