2010年1月21日木曜日

twitterでキーワードを検索して、その結果を出力するPHPスクリプト

<?php  
$keyword = 'ソフトバンク';  
$query = 'http://search.twitter.com/search?q='.urlencode($keyword);  
$dom = new DomDocument('1.0','UTF-8');  
@$dom->loadHTML( file_get_contents( $query ) );  
$xpath = new DomXPath( $dom );  
foreach( $xpath->query('///span[@class="msgtxt ja"]') as $element ){  
 echo $element->nodeValue."\n\n";  
} 

2010年1月20日水曜日

DELL PowerEdge 2970にdebian lennyでLAMP(Linux Apache PHP MySQL)設定メモ

主に自分用なので読みにくいのはごめんなさい。また下記の設定だけで設定終了というものではありません。

サーバスペック

メモリ16G Six Core Opteron 2.2GHz x 2 SAS 146G 3.5inch 15000rpm x 2 (RAID 1) X25-E 64G x 2 SATA 1T 3.5inch 7600rpm x 2(RAID 1) X25-EとSATA 1Tは後付けした。3.5inchのHDDを選択した場合、もともとSASx6のバックプレーンが付いているので、そこにSAS-SATA変換ケーブルでSATAのHDDをつないだ。この場合、BIOS画面でバックプレーンにケーブルが刺さってないとエラーが表示され、この状態だとIPMIの設定画面にいけなくなるので注意する。X25-EはSSDのためハードウェア障害はないものとしてRAID 1の設定はしていない。ただ、何らかの原因で壊れることも予想されるので、予備にもう一つつけてある。SATA 1Tはデータ保存用。

ディスク、パーティションの設定など

全HDDでLVMを設定。その上でSAS 146Gはext3。X25-Eはxfs。SATA 1Tはext3で設定。RAIDコントローラにバッテリーが付いているので、より高速化させるためにext3はdata=writeback、xfsはnobarrierでマウント。

各ディスクのスケジューラがデフォルトでcfqになっているので全てdeadlineに変更。HDDはデフォルトのキューサイズが128になっているので1024に変更。SSDはデフォルトのまま。 echo deadline > /sys/block/sda/queue/scheduler echo 1024 > /sys/block/sda/queue/nr_requests

Xen

前書いたDebian GNU/Linux 5.0(Lenny)でのXenの設定メモを参照

DELL OMSA、IPMI関係

IPMIでSOL(Serial Over LAN)の設定。ネットワーク越しにBIOSの操作ができたりする。
BIOSで以下の値を設定。 Serial Communication を On with Console Redirection via COM2 External Serial Connector を COM2 Failsafe Baud Rate を 57600

BIOSでIPMIを有効にして静的IPアドレスを割り振る。パスワードは記号を使うとうまく認証できない場合があった(DELL SC1435とか、、)ので、最初はアルファベットだけのほうが無難かも。

ここまでの設定で、ipmitoolからsolでBIOSの設定が出来るようになる。実験するにはサーバ再起動直後にipmitoolからsolでつないでみる。さらにipmitoolのsolからLinuxのログインコンソールまで表示させるには

/boot/grub/menu.listのXen以外のkernel行の後ろに、rhgb console=tty console=tty console=ttyS1,57600n8を追記。 Xenをインストールしたり、カーネルのアップデートをしたりすると消えるので注意。 後はdebianインストール後/etc/inittabに下記の行を追加。 co:2345:respawn:/sbin/getty 57600 ttyS1 vt100-nav これでipmitoolからsolを使ってログインすることが出来る。Xenカーネルについては設定が面倒そうなのでやり方を追求していない。緊急時はとりあえず通常カーネルが動けば良いのでよしとする。ipmitoolのsolはよくSegmentation faultするので、した場合、一回deactivateしてからactivateする。solから抜けるには~.と入力する。

debian設定関係
公開鍵の設定 wget http://ftp.sara.nl/debian_sara.asc apt-key add debian_sara.asc /etc/apt/sources.listに追加 deb ftp://ftp.sara.nl/pub/sara-omsa dell sara 時間帯によっては重くてアクセス出来ないため注意。 apt-get update apt-get install dellomsa apt-get install ipmitool これで各種ハードウェアの状況を確認するための、omreportとipmitoolコマンドが使える。 omreport chassis ipmitool sesnor nagiosやcactiで監視するときは以下のスクリプトを使用する。

- omreport chassisのOKを数える。/etc/snmp/omreport.sh #!/bin/sh omreport chassis | awk '/^Ok/ {LINE+=1} END{print LINE}'

- 指定した項目の値(Sensor Reading)を取得する。/etc/snmp/ipmi.sh #!/bin/sh /usr/bin/ipmitool sdr get "$@" | grep 'Sensor Reading' | awk '{ print $4 }'

SNMP(XenのホストOS上での設定)

apt-get install snmpd /etc/default/snmpd の127.0.0.1を削除(ローカルからのみのアクセス制限) /etc/snmp/snmpd com2secのpublic行をコメントアウトして、private行のコメントアウトを解除。ファイヤーウォールは適切に設定すること。 disk / 10000 のコメントアウトを解除。

omreportやipmitoolの設定をして、外部から値をとれるようにする。下記サンプル。/etc/snmp/snmpd.confに追記。 extend .1.3.6.1.4.1.2021.54 Temp /etc/snmp/ipmi.sh 'Temp' extend .1.3.6.1.4.1.2021.55 Temp /etc/snmp/ipmi.sh 'Ambient Temp' extend .1.3.6.1.4.1.2021.60 FAN /etc/snmp/ipmi.sh 'FAN 1 RPM' extend .1.3.6.1.4.1.2021.61 FAN /etc/snmp/ipmi.sh 'FAN 2 RPM' extend .1.3.6.1.4.1.2021.62 FAN /etc/snmp/ipmi.sh 'FAN 3 RPM' extend .1.3.6.1.4.1.2021.63 FAN /etc/snmp/ipmi.sh 'FAN 4 RPM' extend .1.3.6.1.4.1.2021.70 DELL_OMSA /etc/snmp/omreport.sh

MySQL関係(XenのゲストOS上での設定)

今までTritonnを使用してきたがMySQLのバージョンが古くなってきたため、最新が使いたいのものあり、MySQL最新版とTritonnを併用することにした。

MySQL最新版インストール

MySQL5.5最新版ダウンロード 解凍後、/usr/local/mysqlに移動。 support-filesコピー cp support-files/myなんとか.cnf /etc/mysql/my.cnf cp support-files/mysql.server /etc/init.d/mysql

必要に応じてDB初期化 cd /usr/local/mysql; ./bin/mysql-install-db –-user=mysql /etc/init.d/mysqlを編集 basedir=/usr/local/mysql datadir=/var/lib/mysql startの処理をしているところの、$bindir/mysqld_safe の直後に—defaults-file=/etc/mysql/my.cnfを足す。- あと何故か/etc/init.d/mysql stopがエラーになるので、 /etc/init.d/mysqlのstopの処理をしているところの、 if (kill -9 $mysqld_pid 2>/dev/null) を if trueに置き換える どうもkill –9 $mysqld_pidするとmysqlのpidが変わってその後のkillがうまくいってないようだ。原因不明。

ユーザ、グループの追加 /usr/sbin/groupadd mysql /usr/sbin/useradd -g mysql mysql データベース初期化 scripts/mysql_install_db --user=mysql cp -a data /var/lib/mysql /etc/init.d/mysql startで起動。 特に問題なければサービスとして登録して、自動起動させる。 update-rc.d –f mysql defaults
Tritonn最新版インストール

Tritonnは通常ポート3306のところを、3307にして起動する。

Tritonn最新版ダウンロード 解凍後、/usr/local/tritonnに移動。

support-filesコピー cp support-files/myなんとか.cnf /etc/mysql/tritonn.cnf cp support-files/mysql.server /etc/init.d/tritonn

必要に応じてDB初期化 cd /usr/local/tritonn; ./bin/mysql-install-db –-user=mysql ※/usr/local/mysql以外の場合mecabが正しく動かないため下記の操作が必要。 cp –a /usr/local/tritonn/etc/ /usr/local/mysql/etc/ cp –a /usr/local/tritonn/lib/mecab/ /usr/local/mysql/lib/mecab/ /etc/init.d/tritonnを編集 basedir=/usr/local/tritonn datadir=/var/lib/tritonn startの処理をしているところの、$bindir/mysqld_safe を書き換え./bin/mysqld_safe —defaults-file=/etc/mysql/tritonn.cnfにする。 その直前の行に、cd $basedirを足す。こうするとmecabにパスが通るようになる。

/etc/mysql/tritonn.cnfを編集 portを3307に。socketを/var/run/mysqld/tritonnd.sockに修正 /etc/init.d/tritonn startで起動。 問題があれば、起動時のオプションに—senna-log –senna-log-level=DEBUGを追加して、様子を見る。

特に問題なければサービスとして登録して、自動起動させる。 update-rc.d –f tritonn defaults

Apache関係(XenのゲストOS)

今回はコンテンツ配信用とプログラム処理用にApacheのインスタンス二つを一台のサーバ上で起動するように設定する。コンテンツ配信用はapache2lightとし、プログラム配信用のポート番号は8080とする。二つに分ける理由は、同時アクセス数が極端に増えた場合に、プログラム処理用のインスタンスだけではmod_phpでメモリが大量に消費され効率よく同時アクセス数を増やせないため。

Apache2台構成設定

apt-get install apache2

cp –a /etc/apache2 /etc/apache2light cp –a /etc/init.d/apache2 /etc/init.d/apache2light

/etc/apache2/ports.confのポート番号を8080にする。 /etc/apache2/sites-available/defaultのポート番号を8080にする。

/etc/apache2light/apache2.confの/etc/apache2/のパスを/etc/apache2light/に置換する。Pidファイルを/var/run/apache2light.pidとする。

/etc/apache2light/envvarsのPidファイルを/var/run/apache2light.pidとする。

/etc/init.d/apache2lightの/etc/apache2/のパスを/etc/apache2light/に置換する。$APACHE2CTLでconfigtest以外のコマンドを実行している行を、$APACHE2CTL –k コマンド名 –f /etc/apache2light/apache2.confに修正する。

起動テスト等行ってみて、特に問題がなければ、 update-rc.d –f apache2light defaults

Apache設定(プログラム処理用)

主にプログラム処理用。KeepAliveをオフにする。

mod_statusを入れる。ExtendedStatusをOnにする。 mod_deflateを切る(PHPが処理するため) mod_rpafを入れる(リバースプロキシを使った際の環境変数HTTP_HOSTの自動書き換え) mod_php5を入れる。 mod_rewriteを入れる。

Apache Light設定(コンテンツ配信用)

主にコンテンツ配信用。こっちはKeepAliveをオン。PHPの処理はプログラム処理用のApacheに投げる。動的に作成した画像などは最初だけプログラム処理用にアクセスし、その後はコンテンツ配信用から生成されたキャッシュを送る。キャッシュ機構自体はPHPのフレームワークSymfonyのものを使い、Apacheのモジュールは使わない。キャッシュフォルダにすでに画像が作られていれば、プログラム配信用にアクセスせずにその画像を送るというような設定にする。

mod_statusを入れる。ExtendStatusをOnにする。 mod_deflateを切る(PHPで処理するため) mod_expireを入れる(cssや画像などに適切にExpireを入れる。YSlowやPage Speedで見ながら調節する) mod_rewiteを入れる。
Apache二台体制の考察

現在すでに本稼働中で、その様子を。 コンテンツ配信用はサーバは17.9リクエスト/秒、プログラム処理用は8.73/秒となっている(ピーク時はこれの二倍ぐらい)。ただ処理中のプロセス数は、プログラム処理用はKeep AliveをOFFにすることにより、プログラム処理用はコンテンツ配信用の1/5程度のプロセス数しかない。 http://d.hatena.ne.jp/naoya/20080212/1202830671 また上記ブログを参考に、各Apacheプロセスの消費メモリは下記の通り。 # ./apache_shared_memory_size.sh PID RSS SHARED 22825 63028 35756 (56%) 22827 63520 36824 (57%) 22836 53004 35076 (66%) 22848 45608 36936 (80%) 22850 45224 34760 (76%) 全7プロセス。 (MaxRequestsPerChild 100のためSHARED数値が安定していない多分)

# ./apachelight_shared_memory_size.sh PID RSS SHARED 22129 3892 3524 (90%) 22583 3628 3240 (89%) 22597 3676 3256 (88%) 22726 3896 3536 (90%) 22789 3612 3252 (90%) 22790 3620 3212 (88%) 全33プロセス。 上記のように、コンテンツ配信用は1プロセスあたり大体360kしか消費していないのにたいして、プログラム処理用は1プロセスあたり9M~28Mほど消費しているのがわかる。これがもしプログラム配信用のみで運用しているとした場合ざっとした計算で3~4倍ほどメモリを消費することになる。

簡単にApacheの全プロセスの合計消費メモリ調べたい場合は下記ブログが参考になる。 http://d.hatena.ne.jp/kazuhooku/20091221/1261392787 上記ブログのスクリプトを何回か走らせると、150M~180Mと表示される。 現状ではサーバに大分余裕があるので、今の10倍ぐらいの同時接続数までならなんとかなると思う。

Apache二台体制とキャッシュについて

このApache二台体制の場合、いかにプログラム処理用を使用しないかで、メモリ消費量が大きく変わってくる。たとえば、動的に生成する画像が一つのWebページに10枚はってあるとすると、これだけでプログラム処理用のプロセスを10も起動しなければならなくなり大量のメモリを消費する。この場合、この動的に生成する画像がリアルタイムに生成する必要がなければ、キャッシュすることで、コンテンツ配信用のみで処理することが出来、より高速化できメモリの節約にもなる。 この場合、Apacheのレベルで処理するのであれば、mod_cache、mod_disk_cache、mod_mem_cache等のmoduleをコンテンツ配信用サーバに組み込んでキャッシュ処理を行う。 またPHPのフレームワークsymfonyでsfSuperCachePluginつかうことにより、一回目のアクセスのみ、プログラム処理用サーバで画像を生成しキャッシュすることで、二回目のアクセスからはコンテンツ配信用サーバからそのキャッシュされたファイルを直接配信するよう設定することも出来る。symfonyに詳しくない方もいると思うので、簡単に内部処理を説明すると、特定のキャッシュ保存用ディレクトリにファイルがあるかないかをmod_rewriteのRewriteCond -fで調べ、もしファイルがあればそのファイルをクライアントに送り、無ければPHPで処理する。Apacheのmoduleを使用するよりこちらのやり方の方が無駄がないが、運用方法によってどちらが良いかは変わってくると思う。

以上、、