2009-03-04

第一回 ライブドア テクニカルセミナーに参加しました

はてなブックマーク   livedoor clip

日野原です。

週をまたいでしまいましたが、先週末にlivedoor主催のテクニカルセミナーに参加してきました。
検索するとすでにいろいろな方のレポートが見つけられますね。月曜日は別に片付けなくてはいけない仕事があったので相当出遅れてしまいました。やっぱり週末に清書しておけば良かったかと反省しております。…いや、休日に仕事しちゃいけません。ああ悩ましい。
ということで、あまり遅くなってもつまらないのでセミナー中に取っていたメモを整形だけしてスピード優先で掲載します。
後日発表資料が公開されたら、資料と一緒に見ていただけるとよりわかりやすいかと思います。
なお、私が聞いて解釈したとおりに書いているので、間違ったことが書いてあっても発表内容が間違っていたとは限りませんので察してください。指摘をいただけるとさらに幸いです。

セミナーは社員の方の発表はバックエンドの話が中心で、非常におもしろかったです。また、ゲスト講演はWinnyの金子さんとその弁護団事務局長の壇さんで、普段聞けないような話が聞けて刺激的でした。

ただ、壇さんの講演に関しては専門外の法律の話である上に、普通の文字量のプレゼン資料を「高橋メソッド風に(本人談)」進められてしまったのでメモを取る方も追いつけず、十分な報告ができません。申し訳ありません。

開会の挨拶

livedoor テクニカルセミナー 2009 Open & Share
株式会社ライブドア技術部会

司会 伊勢さん
足下の悪い中ありがとうございます。

アンケートにご協力ください。

「Open & Share」だから撮影や録音はご自由にどうぞ。でもうるさくて迷惑なのはやめてください。
ブログに書いてもオーケーです。
ちなみにねとらじで生中継中なので、質問などオフレコにしたければその旨言ってください。
何かあったら黒いストラップの社員まで。

「Practical Cicindela 実践ちちんでら」

メディア事業部 ブログビジネスユニット 井原さん

最近edgeラボで公開したレコメンデーションエンジン。
実際に運用中で実践経験豊富なので、その運用例を紹介する。

井原さんは「ちちんでら」と呼んでいるけれど、社内では「ししんでら」と呼ばれている。

レコメンデーションは脇役なので、応答速度が重要。
新しいデータがすぐに反映されるかも重要なので夜間バッチ処理とかはよくない。
その辺を考慮した作りになっている。

入力はいったんバッファに入れられ、バッチ処理で一次テーブルに入る。
これは入力の処理を軽くするためで、一次テーブルに後からいろいろ情報を足していく。
集計はできる限りバッチでやって中間集計テーブルを作る。
その後、現在使用中のテーブルと中間集計テーブルをrenameして入れ替える。

応答時間は平均数ミリ秒、ちょっと複雑な処理でも20~30ミリ秒で返すことができている。

livedoorクリップでの事例

一日1万2千件くらいの記事がクリップされる。
ひとつのページに4、5件のクリップがついたころが一番見られるので、そのころまでにレコメンドを準備する。

最新1時間、通常のレコメンド(このページをクリップした人はこのページもクリップしています)、タグを考慮したレコメンド(このタグはこのページにも付いています)の3段階に分けてレコメンドを作る。

「~のトップページ」とか、いかにもクリップされがちなページはレコメンドしない。

同人ダウンロード販売サイトでの事例

同人ダウンロード販売サイトではレーティングに基づいたレコメンドや、独特の配慮をしている。
たとえばほかの作家を薦めすぎないとか、一般向け商品のページで成人向け商品を薦めないとか。

レーティングの得点を正規化したり、フィルタリングをしたりという処理が入る。

レコメンド経由の販売が4%くらいあるらしい。

you bride(結婚情報サービス)での事例

アクションをまったくしない人同士をつなげる工夫をしている。

たとえば、「Eさんを選んでいる男性はDさんを選んでいる」のほかに、「同じ属性の同姓が選んでいる異性と、同じ属性の異性」を薦める。

具体的には、何もアクションを起こさないCさんと同じような属性の人たちが選んだ女性Eさんと同じ属性のFさんをCさんに薦める。

この方式の採用により申し込みが6.5%アップ、交際率が2~4%アップした。

ストレートなレコメンドを採用したときには3割とか1割とか上がってるので、それに比べると地味だけど。

伊勢さんより補足。

livedoorのedge ラボで公開しているから使ってね!

質疑

  • Aさん
    • 中間結果の数は制限かけているか?
      • フィルタリングのときにパフォーマンスの目的でlimitをかけることはある。
    • ランダム要素はあるか?
      • レコメンドの結果にランダム要素はないけれど、10件出た中からランダムで2件薦めるとかで一見ランダムに見える工夫はしている。
  • Bさん
    • ニュースのおすすめに使ってる。apacheのログベースでやっているけどドキュメントがまだ無い。
      • ごめんなさい。
    • IPアドレスをユーザとしてみているけど、なんかいいやり方は無いか?
      • mod_usertrackでcookieベースでやっている。これだとcookieが文字列で入ってくるが、それをintに変換して性能向上の工夫をしている。
    • 特にモバイルだとIPが同じになるが何か良い方法はないか。
      • モバイルではやってないので「こうすればいい」というのはない。アプリ側でセッションIDを使うとかするのかな。
    • HTTPだと遅いかと思ってDB直でたたこうとしてるけど、どうしてる?
      • livedoorでもHTTPでやっている。

「ライブドアブログ公式攻撃マニュアル」

引き続き井原さん。

2chのコピペブログへの無差別DOS攻撃があった際、社内勉強会で話した内容から。

2008/3/7 22:00攻撃が開始された。

しかしすでに対策済みで、10秒くらい連続アクセスするとアク禁になるようにしてあった。

そのとき、LDブログチームは送別会中だった。

結果、2chでほめられた。

どうすれば落ちるかの部分は社外秘のため発表できません!

まとめ

  • ブログでお金儲けたっていいじゃないか。
  • livedoorのブログサーバはそんなに簡単に落ちるほど単純じゃない。

伊勢さんより補足。

去年の2008/07号の日経SYSTEMSでコラムになっているので読んでください。

「インサイド livedoor Blog」

メディア事業部 ブログビジネスユニット 垣内さん

agenda

  • サーバ構成
  • apache独自モジュール
  • 管理画面
  • 新サービス

2003年11月オープンで、5年ちょっと経つ。
キャッシュとかを抜いて16TBのデータがある。

サーバ構成

構成図をこんなに細かく出していいのかな。
(発表資料が無いとこのあたりは意味不明です、すみません)
この構成図からは検索サーバ等は省いてる。
CMSは管理画面

portal/cmsはlivedoor標準な構成になっている

blog側(攻撃をうけやすいところ)
blog-wwwではApache2.2 mod_ldblog_mapper2 mod_include (SSI)を使っている。

blog-app (コメント、トラバを受ける場所)
apache2.2 mod_proxy_balancerも使っている。後はsledge。

DB
mysql
user-cluster DB
user単位のパーティショニングで1~2万ユーザ×150クラスタ。
クラスタリングは手動で、運用でカバーしている。

ストレージ
商用でNFSマウント。
DBの内容をhtmlに変換した静的ファイルをキャッシュとしておいてる。

イメージストレージ
容量を安く増やすために自作している。
WebDAVでアクセスする。
どのサーバに何のファイルがあるかをapache + 自作module + mysqlで解決している。
解決の部分とかreplicationはapache moduleだから強い。
ほかのサービスで新版を試験運用中。

サーバ構成のまとめ

  • OSはBSDとかLinuxとかばらばら。
  • 回数の多い処理はmoduleにして性能を上げている。

独自モジュール

mod_counter
画像カウンタ。

mod_ldblog_mapper2
URLからNFSマウントされたストレージのパスを計算する。
memcachedやDBから引いた結果を環境変数に入れている。
キャッシュがあれば mod_rewrite でキャッシュに飛び、無ければblog-appに行く。
キャッシュがあればほとんどApacheで完結するのでDDOS攻撃とかに強い。
ストレージに入った画像はgzipで圧縮されるけれど、その辺もの処理もフロントでやっている。

静的ファイルキャッシュについて
htmlファイルを全部いっぺんにキャッシュしてしまうとよく変更される部分(新着記事、新着コメント)にキャッシュ再構築の頻度が依存する。
→個別ファイルにしてmod_includeでSSIしている。

キャッシュの再構築はファイルを消すだけ。作るのはアクセスがあったとき。

お知らせメールなどqueueの必要な処理には、TheSchwartzを使っている。

新管理画面

今までEUC-JPだったのをUTF-8にした。
蓄積データも新規ユーザはUTF-8。

文字コード多重化
blog単位でcharsetを切り替えられる様になっている。
マルチブログで二つのblogを持ってる場合、EUCとUTF-8と共存したりできる。
複雑になったので、ORMでアクセサを切り替える仕組みを仕込んだ。

URL変更
シングルサインオンをlivedoor.comと分離するのが目的。
OpenID連携にした。
新サービスの準備のため。

新サービス

livedoor Blog ASP

ブログのドメイン名を変えられる。
既存のlivedoor Blogのいろいろな機能と素直に連携できるのが売り。

OpenIDについて
RPをやるわけではないが、裏で使っている。

AXでいろいろ情報を交換している。sregではなくAXを使ったのは、sregだとuser_idをうまく取れなかったため。

IEのURL長の制限の対策もしている。

パートナー募集中。

質疑

  • Cさん
    • 画像のサーバが別になっていることに関して、blogと一緒に投稿された画像には公開範囲の限定があると思うけど、mod_accesstokenを使っているか?
      • blogではmod_accesstokenは使ってない。
    • mod_accesstokenの導入事例はある?
      • コスプレサイトのCure
      • 会社で見るときには注意してください。ファンクラブに登録すると効果がわかります。
  • Dさん
    • 守るマニュアル教えてください。
      • 資料中にもあったように、10秒の連続アクセスで防御される(mod_dos_detectorみたいなもの)
      • 他にはYAPC ASIA2008 で発表したスパムチャンプルーも使ってる。
      • 詳細には言えない。ごめんなさい。
  • 伊勢さん
    • blog ASPはいつから?
      • 4月から

「ライブドアのネットワークとトラフィックパターン」

ネットワーク事業部コアネットワークグループ 市川さん

agenda

  • DATAHOTEL(データセンター)ネットワーク概要
  • iDC ISPの立場から見た傾向
  • 最近の話題
  • IPv6

概要

DATAHOTELではiDC(データセンター)、公衆無線LAN、企業向けISP(ライブドアBB)とトランジットサービスをやっている。

サービスごとに別に接続してるのでどれかに障碍があってもほかには影響しない。

DATAHOTEL内の冗長化はメッシュ型だが、ライブドアBBは拠点が離れてて難しいのでリング型になっている。

トラフィックの傾向

一般的なプロバイダのトラフィックはユーザへの下りがメイン。
平日

  • 20時から始まり24時がピークで、そこから減少。
  • 朝のメールチェック時に小さなピークがある。
  • 昼休みにもちょっとピーク。

休日

  • 昼の12時から増え始めて24~25時がピーク。

P2Pのトラフィック

  • 上りと下りがほぼ同じ。
  • livedoorでは帯域制限は基本的にかけていない。

iDC(データセンター)のトラフィック

  • ISPと逆になる。
  • ピークになる時間帯は同じ。

ルータのメンテナンスをするのはトラフィックの落ち込む2時から5時くらい。

休日は一日中ネットをやっているユーザが多いらしい。
「土日」じゃなくて「休日」。

トラフィックの例:コンテンツダウンロード販売系のラック

「これがピーク」と言う時間帯が無い。一番少ない時間帯でもそこそこの量が流れている。
アキバ系は強い。
ピークで1G弱。

トラフィックの例:ポータル系のトラフィック

livedoor Blog

  • 0時過ぎの落ち方が緩やか。ユーザに夜更かしする若者が多いのか?

livedoor ねとらじ

  • お昼休みピークが無い。
  • 就業時間後にまた下がる。
  • 仕事中にBGMとして聴いてるのかな?
  • 夜に最大値を迎えるのは変わらない。

インターネットのトピック

1/31~2/1にかけてGoogleが正常なサイトをフィッシングと誤認する障碍が発生したが、livedoorのトラフィックにはほとんど影響はなかった。

年末年始、12/31~1/1には夜中の大きなピークが無い。0時前後に「あけおめ」書き込みか?という小さなピークがある程度。

2/17 01:30~02:30ごろにインターネットに障害。
上位回線で回線が切断されたりしたらしい。
livedoorの上流では幸い影響なかったが、インターネットって意外と脆弱だという印象を受けた。

IPv6に関して

実験だからお客さんには出してないが、WIDEとつながっている。

2ちゃんのIPv6板を運用している。IPv6がreachableな人は書き込みができるから書いてみてください。

IPv6のトラフィックは少ない。20kとか1Mとか、バックボーンでは考えられない量。

Tokyo6to4というprojectに参加してみてね。

伊勢さんより補足

  • ネットユーザって初詣行くんだね。意外と信心深いのかな。
  • DLサイト、平日は少なくて休日は多いってことから同人ファンはサラリーマンが多いってのがわかるね。

質疑

  • 伊勢さん
    • 18:00-20:00のトラフィックの落ち込みの原因はわかる?
      • ご飯?
    • 正解。「飯落ち」と呼ばれる現象。
    • blogのトラフィックってお昼にキューンとあがる。みんな見ているんですね。

「P2Pコンテンツ配信技術の現状」

金子さん

自己紹介
(株) Dreamboat 技術顧問
コンテンツ配信システムSkeedCastの開発中。

agenda

  • P2Pの紹介
  • WinnyとSkeedCast
  • SkeedCast

P2Pの紹介

P2P(型ファイル共有ソフト)の発展
第一世代 Napsterなど
→ハイブリッド(P2Pなのはデータ転送のみ)
第二世代 Gnuteraなど
→pure P2P(検索もP2P)
第三世代 Winnyなど
→キャッシュ型(転送キャッシュ)
第四世代
→商用(P2P教科書(インプレス)による)
インプレスによる分類は技術的な分類ではない。
金子さんによると第四世代にはSkeedCastやWinny2が該当し、ノード群をサーバとみなしてクラサバ的挙動をする

Winny→SkeedCast

Winny1
→ファイル共有ソフト
Winny2
→もっと汎用的なものを目指した。BBSをP2Pでやる。BBS部分だけ第4世代的。

Winny2ははるかな高みを目指していた。
Winny1の落穂ひろいにWinny2の要素を入れていったのがSkeedCast

SkeedCastの特徴

P2Pノードがサーバになる→分散サーバとP2Pのハイブリッド

Winnyにも速度による上下関係はあったが、SkeedCastではもっっとノードの役割を意識している。

アップローダ(投入ノード)、中継(共有ノード)、ダウンローダ(レシーバ)の3つがあり、ダウンローダは中継もできる。

投入ノードは課金とかDRMとかを考えてる。
共有ノードはUNIX、レシーバはWindowsで動く。

共有ノードはコントロールノードからコントロール可能。
キャッシュコントロールとか。
ある人気コンテンツを優先的にキャッシュに入れるとかもできる。

P2Pは不安定という弱点があるので、サーバのトラフィックが予定外に増えすぎたときにユーザノードを中継ノードとして動かしてしのげる。P2Pのいいところ。

SkeedCastはファイル共有ではなくコンテンツ配信のシステムなので、普段はCDN的に動作して、サーバが大変なときにP2P的に動作して凌ぐ。

特徴
Winnyはハッシュを多用していたが、SkeedCastは代わりにデジタル署名を多用する。
ホワイトリストのフィルタリングやキャッシュのライフタイム管理に使う。

コンテンツにデジタル署名をする。
コンテンツプロバイダが秘密鍵を持ち、流通段階で署名をチェックして問題があれば流通させないといったコントロールが可能。
公開鍵をホワイトリストとして使う(後述)

流通フィルタリング
Winnyはダウンロードフィルタ、無視フィルタ(ブラックリスト)の二つのフィルタがあった。
SkeedCastはダウンロードフィルタ、無視フィルタ、許可フィルタ(ホワイトリスト)の三つのフィルタを持つ。
許可フィルタは公開鍵の束なので偽装は不可能。

再中継の制御
Winnyはどこかにキャッシュがあると再中継可能だが、SkeedCastは投入ノードがコントロール可能。

レシーバ(PCに入れるソフト)
Webと連携する。
ブラウザでリンクをクリックすると起動する。
SkeedReceiverはWebサーバとして動作し、裏でCacheとしてダウンロードする。
また、SkeedReceiverがストリーミングサーバになって、メディアプレーヤで視聴する。ストリーミングだけどローカルにあるからシークもできる。

展開可能フラグがたってればCacheをファイルに展開することもできるよ。

視聴のコントロールにはDRMを使う。

言ってみれば巨大なProxyになる。

(株)Dreamboatではほかにもいろいろやってるから使ってください。
社内ネットワークでの配信もできる。

質疑

  • 伊勢さん
    • receiverはプラグイン? デーモン?
      • 常駐はしない。ブラウザのプラグイン経由で必要なときに起動して、終わったら終了する。タスクバーにも出るので、気になったら消すこともできる。
    • ヒントをもらった。ありがとうございます。ストリーミングサーバのランニングコストは馬鹿にならないから。
  • Eさん
    • ダウンロード可能性は投入ノードで管理といってたけど、ダウンロード済みのものをレシーバでストリーミングするかどうかはチェックするのか?
      • ダウンロード済みの物はWinny的な感じで処理している。詳細は想像してください。

「デジタルコンテンツ配信の法的問題」

壇さん
金子さんの弁護団の事務局長

P2P教科書は私も書いているので買って読んでください。

cocologでblogを書いています。

Livedoorには壇さんを誹謗中傷するwikiがある。

ネットのせいでコンテンツ産業は損害を受けてるってホント!?

CDやレコードはの売り上げは落ちてるけど、着うたとか増えてるから消費シフトと見るべきではないか。
映画の興行収入は年ごとに上がったり下がったりしている。
結論:ネットは関係無いんじゃないか? むしろうまく使えば利益もたらすんじゃないか。

著作権について

厳密には著作権と言う名前の権利は無い。
いろいろな法律で規定されてるいろいろな権利をまとめて著作権と総称してる。

Winnyは大容量コンテンツの配信を可能にした。
それまでは映画一本流すなんてできなかった。

(以下、追いつけなかった部分はキーワードのみで失礼します。)
プロバイダ責任制限法
カラオケ法理とか
私的目的での複製
著作権侵害はP2Pに固有の問題ではない。ニコ動とか。
アメリカ:セーフハーバーとかDMCAとか
クラブキャッツアイ事件
カラオケ法理がP2Pのファイルローグに適用された。

開発者、提供者が刑事事件の当事者になったのは日本、韓国、台湾のみ。
有罪になってるのは金子さんと台湾の1件(Kuro事件)のみ。
金子さんは確定してないので最高裁まででひっくり返すよ!

Winny事件地裁判決における幇助成立の基準
証拠として提出されたWinnyの利用状況がなぜかアンケート結果。

よくある誤解
Winnyに匿名性があるから有罪?
→匿名性は関係ない。
金子さんの目的が著作権侵害蔓延だったから有罪?
→そんなことのためにわざわざソフトを開発するわけ無い。

IP-TVのニーズ
海外で日本の番組を見たい
東京ローカルを地方で見たい。
しかし地方免許制度の枠組みでしか見られない。

IP-TVの訴訟
録画ネットと選撮見撮は著作権者側が勝っているけど、まねきTVとロクラクはサービス提供者側が勝っている。

著作権の問題
カラオケ法理の適用範囲
非親告罪化
ダウンロード違法化
日本版フェアユース(ぜひとも立法化すべき)
ただし裁判所の判断にゆだねることになるので危険性はある

質疑

  • Aさん
    • 日本の著作権関連団体は強い主張を繰り返していて、徐々にその主張に引きずられている気がするが、彼らの言うような方向にこのまま行ったらどうなる?
      • アメリカから制度変えろといわれて終わるんじゃないか。
  • 伊勢さん
    • SkeedCastと連携しろなんてあったけどメディア事業部の担当役員さん、どう思う?
      • やりたい。

閉会の挨拶

代表取締役社長 出澤さん

みなさん、雨の中ありがとうございます。
金子さん、壇さん、ありがとうございます。
新規サービス(最後の質疑のSkeedCastの連携)も決まってうれしいねw

Open & Shareという企業理念でやっています。

今後ともがんばるのでよろしくお願いします。

2008-12-03

プロキシ認証の通し方まとめ その2

はてなブックマーク   livedoor clip

お久しぶりです、日野原です。

読者の皆さんは山本のレビューの設計編を楽しみにしていらっしゃると思いますが、彼は最近何やら忙しく飛び歩いていて、ここの記事を書く時間がとれそうにないのでもう少々お待ちください。

私はこの3ヶ月の間にまたプロキシの設定をしなければいけないケースに遭遇したので追記しておきます。

今回もプロキシの情報は同じとします。

ホスト proxy.example.com
ポート 8080
ユーザ foo
パスワード bar

sudo 編

まず、前回基本編で挙げた

export http_proxy=http://foo:bar@proxy.example.com:8080

ですが、これの適用範囲が広がりました。

rubygems編で「sudo では環境変数を引き継げない」と書いてしまったのですが、これは私の無知で、実は設定で引き継ぐ環境変数を指定できることがわかりました。

設定するためには、/etc/sudoers の env_keep という変数に引き継ぎたい環境変数を指定します。

具体的には、

Defaults env_keep = "COLORS DISPLAY HOSTNAME HISTSIZE INPUTRC KDEDIR \
         LS_COLORS MAIL PS1 PS2 QTDIR USERNAME \
         LANG LC_ADDRESS LC_CTYPE LC_COLLATE LC_IDENTIFICATION \
         LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC \
         LC_PAPER LC_TELEPHONE LC_TIME LC_ALL LANGUAGE LINGUAS \
         _XKB_CHARSET XAUTHORITY"

という箇所があるので、これの最後の行を

         _XKB_CHARSET XAUTHORITY http_proxy NO_PROXY"

と変更します。
これで rubygems や yum を sudo で動かすときには別途プロキシを設定する必要がなくなりました。

ちなみに /etc/sudoers を編集するときには chmod して編集して戻してなんてせずに、visudo を使ってくださいね。

pear / pecl 編

PHP のモジュールを追加するときに使う pear や pecl は、プロキシ対応を独自でやっているので設定しなくてはいけません。

設定するには次のようにします。

% pear config-set http_proxy=http://foo:bar@proxy.example.com:8080

ちなみに、これで設定すると pecl にも反映されるので pear だけ設定すれば OK です。
試しに確認してみましょう。

% pecl config-get http_proxy
http://foo:bar@proxy.example.com:8080

air 編

Adobe の air のアプリケーションを作って配布するためには .air ファイルにパッケージングする必要がありますが、その際にタイムスタンプを付与するためにタイムスタンプサーバにアクセスします。そう、ここでプロキシの壁に阻まれるのです。

そこで、プロキシの内側にタイムスタンプサーバがある場合は -tsa オプションに url を指定し、無い場合にはやむを得ないので -tsa none と指定してタイムスタンプの付与を省略します。
タイムスタンプを省略した場合は署名証明書の有効期限切れ後にインストールできなくなってしまいますが、正式に製品としてリリースするときまでは考えなくても大丈夫でしょう。

ちなみにこれは http ではなく、RFC3161で定義された Time-Stamp Protocol(TSP) で、318番のポートを使用するので -Dhttp.proxyHost 等で設定してもダメです。

socksで通れば -DsocksProxyHost を指定することでできるかもしれませんが、私の環境ではまだうまく行っていません。

今回は前回の Chrome のような目玉はありませんでしたが、また何かあったら追加していきます。

2008-09-05

proxy 認証の通し方まとめ

はてなブックマーク   livedoor clip

こんにちは、日野原です。

Google のブラウザ、「Google Chrome」が発表されてダウンロードできるようになりましたが、社内でインストールしようとしてみたところプロキシ認証に対応していないらしく、インストールに失敗してしまいました。プロキシ自体には対応しているようなので、ローカルプロキシを立てて認証を任せてあげればインストールできるようです。

と言うわけで今日はプロキシ認証についてです。

自宅で趣味のプログラミングをしているときなどは良いのですが、会社で何かをしようとするとこれのせいではまることがとっても多いので、同じような悩みを持っている人達のために情報をまとめておこうと思います。

ただし、基本的にLinux(Fedora もしくは CentOS 系)での情報です。また、以下の例では、プロキシの情報は下表のようなものとします。

ホスト proxy.example.com
ポート 8080
ユーザ foo
パスワード bar

基本編

まず基本として、環境変数 http_proxy にプロキシの URL を指定します。
bash や zsh を使っている場合は .bashrc、.zshrc に以下の行を書いておきます。

export http_proxy=http://foo:bar@proxy.example.com:8080

これで wget、curl や Plagger は OK です。例外設定は NO_PROXY ですね。ただ、wget は NO_PROXY には対応していないようです。

yum 編

/etc/yum.conf 内で proxy を設定します。(次の一行を追加します)

proxy=http://foo:bar@proxy.example.com:8080/

最後の / は、付けないと動かなかったことがあるので付けておきました。現象の再現ができていないため、詳細はわかっていないのですが。

subversion 編

ホームディレクトリ下の ~/.subversion/servers に指定します。
初期状態でこのファイルの最後の [global] セクションにコメントアウトされた状態で設定が書かれているので、それを書き換えます。

http-proxy-exceptions = *.example.com
http-proxy-host = proxy.example.com
http-proxy-port = 8080
http-proxy-username = foo
http-proxy-password = bar

subversion の場合は社内にアクセスすることも多いと思うので、例外設定(http-proxy-exceptions)もしておかないと後悔するでしょう。

rubygems 編

rubygems は環境変数を見てくれるので list 等のコマンドは基本編と同じでいけます。
しかし install など root 権限が必要になるコマンドでは su 後に export して環境変数を設定する必要があります。また、sudo では環境変数を引き継げないので、-p オプションでプロキシの設定を渡します。

sudo gem install rails -p http://foo:bar@proxy.example.com:8080

ただ、1.0より前のバージョンの rubygems ではバグがあって -p オプションが効かないので、rubygems の config_file.rb(私の環境では /usr/lib/ruby/site_ruby/1.8/rubygems/config_file.rb)内にある class Gem::ConfigFile に以下のメソッドを追加する必要があります。

  def []=(key, value)
    @hash[key] = value
  end

ruby/open-uri 編

Rails の script/plugin など、ruby の open-uri を使用しているプログラムはそのままでは環境変数にプロキシを設定しても認証には対応してくれません。(1.8.6.114までではだめでした。)
open-uri.rb(私の環境では /usr/lib/ruby/1.8/open-uri.rb)に以下のパッチを当てる必要があります。

216c216
<         klass = Net::HTTP::Proxy(proxy.host, proxy.port)
---
>         klass = Net::HTTP::Proxy(proxy.host, proxy.port, proxy.user, proxy.password)

これで、環境変数 http_proxy の設定でいけるようになります。

apache ant 編

最近 ant を使って java のアプリをインストールしたんですが、ivy で必要なライブラリを自動でダウンロードしてくれるところに感動しました。
でもその感動の前にはプロキシ認証の壁が立ちはだかったのです。
と言うわけで環境変数 ANT_OPTS にプロキシの設定を渡しましょう。

export ANT_OPTS="-Dhttp.proxyHost=proxy.example.com \
                 -Dhttp.proxyPort=8080 \
                 -Dhttp.proxyUser=foo -Dhttp.proxyPassword=bar"

Amazon Web Services(EC2) 編

ant が JVM に渡すパラメータを独自の環境変数で管理しているということは、同じ java のアプリである EC2 の管理ツールも同じようになっているわけです。
EC2_JVM_ARGS に指定してください。(EC2の場合は https も使うので、https の設定も必要です。)

export EC2_JVM_ARGS="-Dhttp.proxyHost=proxy.example.com \
                     -Dhttps.proxyHost=proxy.example.com \
                     -Dhttp.proxyPort=8080  -Dhttps.proxyPort=8080 \
                     -Dhttp.proxyUser=foo -Dhttp.proxyPass=bar"

Amazon Web Service を試してみたので次は Google App Engine… と行きたいところですが、Python はわからないのでそれはまた次の機会にでも。

【番外?】Google Chrome(Windows版)インストール編【本題?】

最後に、冒頭で触れた Google Chrome のインストールをしましょう。
今回はローカルプロキシに Proxomitron日本語の情報)を使用しました。

読者層を考えて、ダウンロードからインストールの手順は省略します。

起動したら、まずは右側の下の方にある「Proxy」をクリックして、HTTP Proxies とある欄のコンボボックスにプロキシのサーバ名とポートを「proxy.example.com:8080」というように入力します。

次にパスワードを入力するため、今入力したコンボボックスを右クリックして開くメニューで「Advanced Proxy settings」を選択します。
普通こんな操作、気付きませんよね。隣に座っている同僚が教えてくれました。

ダイアログが開いたら一番下の「Send username and password to proxy」にチェックを入れて、ユーザ名とパスワードを入れます。これでプロキシサーバの設定は終了です。

次にこのサーバを使うようにするため、一番はじめのウインドウで左下にある「Bypass」をクリックし、その上にある「Use Remote Proxy」にチェックを入れます。

これでローカルプロキシの設定は終わりです。

後は Google Chrome のインストーラがこのプロキシを使うように、IE と Firefox のプロキシの設定を localhost:8080 にして、ChromeSetup.exe を起動するだけです。
(IEだけだとインストールが途中で止まってしまう場合もあるようです。)

以上で番外編も終了です。

今回はこんなところで打ち止めですが、またなにかあったら情報を載せていきます。

2008-07-22

MogileFS のために MySQL の NDB Cluster を動かす

はてなブックマーク   livedoor clip

お久しぶりです、日野原です。引き続き MogileFS の話題です。

と言っても前回の続きで開発環境上での話ではなく、サーバに MogileFS を入れていこうと言う話になります。

そこで MogileFS についてちゃんと調べ始めると、「Learning MogileFS」という資料の「mysql database cluster」のところになんと「その名の通りNDB Cluster推奨」と書いてあるではありませんか。

というわけで今回は MySQL の NDB Cluster を 3 台の CentOS 5.2 のマシンにセットアップします。NDB Cluster 自体の説明はThink ITの記事などいろいろとあるので、参考にしてください。
インストールにはrpm 形式で配布されているバイナリを使います。(CentOS 5.2 なので Red Hat Enterprise Linux 5 用の RPM をダウンロードします。記事中ではダウンロードの部分は省略します。)

配布されているページに行くとバージョン番号が MySQL Cluster 6.2.15 となっていて面食らいますが、管理ツールの出力によると MySQL 自体は 5.1.23 で、その上に ndb の 6.2.15 が載っているようです。

今回の構成では、クラスタの 3 種類のノードは以下のように構成します。

3台のマシンのホスト名は srv[1-3] 、IPは 192.168.10.[1-3] とします。そして srv1 上で管理ノード(ndb_mgmd)、srv2 と srv3 上で SQLノード(mysqld)とデータノード(ndbd)を動かします。

この構成だと管理ノードが単一故障点になってしまっていますが、ここを複数構成にするための説明はまだ見つかっていないので今後の課題とさせてください。

それでは実際にインストール作業を始めていきます。
ちなみに、今回のサーバはちゃんと識者に CPAN が使えるようにしてもらってあるので、perl のモジュールのインストールは yum ではなく CPAN から行います。

まずは管理ノードです。
管理ノードに必要なのは以下の3つです。

  • perl の Class::MethodMaker モジュール
  • MySQL-Cluster-gpl-management-6.2.15-0.rhel5.i386.rpm
  • MySQL-Cluster-gpl-tools-6.2.15-0.rhel5.i386.rpm

これらを srv1 にインストールします。

% sudo cpan -i Class::MethodMaker
% sudo rpm -ivh MySQL-Cluster-gpl-management-6.2.15-0.rhel5.i386.rpm
% sudo rpm -ivh MySQL-Cluster-gpl-tools-6.2.15-0.rhel5.i386.rpm

次に設定ファイルを作成します。今回は設定ファイルは /var/lib/mysql-cluster/config.ini という名前で配置します。また、管理ノードは mysql というユーザで起動しますので、ユーザを作成しておいてください。

% sudo /usr/sbin/useradd mysql -d /var/lib/mysql-cluster
% cd /var/lib
% sudo mkdir mysql-cluster
% sudo chown mysql:mysql mysql-cluster
% cd mysql-cluster
% sudo vim config.ini
% cat config.ini
[NDBD DEFAULT]
NoOfReplicas = 2
DataDir = /var/lib/mysql-cluster
ServerPort = 63132[MGM]
Id = 1
HostName = 192.168.10.1
DataDir = /var/lib/mysql-cluster

[NDBD]
Id = 11
HostName = 192.168.10.2

[NDBD]
Id = 12
HostName = 192.168.10.3

[MYSQLD]
Id = 21
HostName = 192.168.10.2

[MYSQLD]
Id = 22
HostName = 192.168.10.3

ここで、NDBD DEFAULT セクションの最後の ServerPort がはまりどころです。
オフィシャルのドキュメントを見ると「旧式」となっており、「デフォルトのポートは同じコンピュータ上の 2 つのノードが同じポート番号を受信しないようにダイナミックに割り当てられているため、通常このパラメータの値を指定する必要はありません。」とあるのですが、これを指定しておかないとファイアーウォールに阻まれて通信がうまくいきません。ひょっとしたら将来のバージョンでは不要になるかもしれませんが、今回インストールしたバージョンでは必要です。
具体的には、データノードから管理ノードに一見ちゃんと接続されているように見えているのに接続されておらず、SQLノードが管理ノードに接続できないという現象が起こります。
私はこれで2日つぶしました。

そのほかのオプションについてはオフィシャルのドキュメントを見てください。基本的な設定例等を見ればわかると思います。

設定ファイルができたら管理ノードにアクセスするためのポートを開けます。

% sudo /usr/sbin/lokkit

デフォルトのポートの 1186 は CentOS 5.2 では /etc/services に書いてあるので、カスタマイズのボタンから「その他のポート」に「mysql-cluster:tcp」を追加します。

そして、管理ノードを起動します。

% sudo -u mysql /usr/sbin/ndb_mgmd -f /var/lib/mysql-cluster/config.ini

起動したら、管理クライアントを起動して show コマンドで状況を確認してみましょう。

% ndb_mgm
-- NDB Cluster -- Management Client --
ndb_mgm> show
Connected to Management Server at: localhost:1186
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=11 (not connected, accepting connect from 192.168.10.2)
id=12 (not connected, accepting connect from 192.168.10.3)

[ndb_mgmd(MGM)] 1 node(s)
id=1    @192.168.10.1  (mysql-5.1.23 ndb-6.2.15)

[mysqld(API)]   2 node(s)
id=21 (not connected, accepting connect from 192.168.10.2)
id=22 (not connected, accepting connect from 192.168.10.3)

これで管理ノードの準備はOKです。

次にデータノードとSQLノードの設定をしますが、これは srv2 と srv3 の両方に対して実行します。以下では srv2 に対して実行しているものとして解説しますが、srv3 に対しても実行してください。

まず、最低限必要なのは以下の4つです。

  • perl の DBI モジュール
  • MySQL-Cluster-gpl-client-6.2.15-0.rhel5.i386.rpm
  • MySQL-Cluster-gpl-storage-6.2.15-0.rhel5.i386.rpm
  • MySQL-Cluster-gpl-server-6.2.15-0.rhel5.i386.rpm

これらを順にインストールします。

% sudo cpan -i DBI
% sudo rpm -ivh MySQL-Cluster-gpl-client-6.2.15-0.rhel5.i386.rpm
% sudo rpm -ivh MySQL-Cluster-gpl-storage-6.2.15-0.rhel5.i386.rpm
% sudo rpm -ivh MySQL-Cluster-gpl-server-6.2.15-0.rhel5.i386.rpm
% mysqladmin -u root password rootpass

(mysql のルートのパスワードは適切に設定してください)

次に設定ファイルを作成します。ひな形はrpmで提供されているので、これを /etc/ 以下にコピーして、NDB Clusterに必要な設定を追加します。

% sudo cp /usr/share/doc/MySQL-Cluster-gpl-server-6.2.15/my-large.cnf /etc/my.cnf
% sudo vim /etc/my.cnf

追加するのは以下の内容です。
[mysqld]セクション内に以下の2行

ndbcluster
ndb-connectstring = 192.168.10.1

ファイル末尾に [mysql_cluster] セクションを追加して1行。

ndb-connectstring = 192.168.10.1

そしてファイアーウォールの設定をします。

% sudo /usr/sbin/lokkit

で、受信を許可する「その他のポート」に「63132:tcp mysql:tcp」と書きます。

また、これだけだと mysql が管理ノードにアクセスしに行くときに selinux に引っかかってエラーになるのですが、そのエラーをわざと一度起こして許可ルールを作るためのログを吐かせます。
もし、/var/log/audit というディレクトリが存在しない場合、audit をインストールしておいてください。

% sudo yum install audit
% sudo /etc/init.d/auditd start% sudo /etc/init.d/mysql start
% sudo grep denied /var/log/audit/audit.log

これで、

type=AVC msg=audit(1216111039.402:59893): avc:  denied { name_con
nect } for  pid=29878 comm="mysqld" dest=32960 scontext=user_u:sy
stem_r:mysqld_t:s0 tcontext=system_u:object_r:port_t:s0 tclass=tc
p_socket

というような行が見つかればOKです。(適当に改行してありますが、本当は一行です。)
mysql はこのまま起動に失敗してプロセスが残ったままになってしまうので、ちゃんとプロセスを kill しておいてください。
次にこのログから許可ルールを作成します。

% sudo audit2allow -a -M mysqlcluster

すると mysqlcluster.pp というファイルが生成されるのでこれをselinuxに取り込ませます。

% sudo /usr/sbin/semodule -i mysqlcluster.pp

ただ、これだとmysqlがネットワークにアクセスするのを全て許可してしまうので、宛先やポートを指定して許可したい場合には適切な te ファイルを作成して設定してください。
ちなみに、srv2 でこの pp ファイルを作れば、srv3 ではログを吐かせるあたりは省略して pp ファイルをコピーして読みこませるだけでOKです。

ここまで来たらあとはデータノードとSQLノードを起動するだけです。
まずデータノードを起動します。

% sudo -u mysql /usr/sbin/ndbd

この時点で srv1 の ndb_mgm から確認すると以下のようになっているでしょう。

ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=11   @192.168.10.2  (mysql-5.1.23 ndb-6.2.15, starting, Nodegroup: 0, Master)
id=12   @192.168.10.3  (mysql-5.1.23 ndb-6.2.15, starting, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1   @192.168.10.1  (mysql-5.1.23 ndb-6.2.15)

[mysqld(API)]   2 node(s)
id=21 (not connected, accepting connect from 192.168.10.2)
id=22 (not connected, accepting connect from 192.168.10.3)

ここでndbdのどちらにもMasterの表示がない場合、外からndbdへのアクセスに失敗している可能性があります。srv1 の config.ini の [NDBD DEFAULT] セクションで SeverPort が 63132 に設定された上で、srv2 と srv3 でポートが空いているかどうか確認してください。

次にsrv2 とsrv3 でmysqlを起動します。

% sudo /etc/init.d/mysql start

そして srv1 で確認します。

ndb_mgm> show
Cluster Configuration
---------------------
[ndbd(NDB)]     2 node(s)
id=11   @192.168.10.2  (mysql-5.1.23 ndb-6.2.15, starting, Nodegroup: 0, Master)
id=12   @192.168.10.3  (mysql-5.1.23 ndb-6.2.15, starting, Nodegroup: 0)

[ndb_mgmd(MGM)] 1 node(s)
id=1   @192.168.10.1  (mysql-5.1.23 ndb-6.2.15)

[mysqld(API)]   2 node(s)
id=21   @192.168.10.2  (mysql-5.1.23 ndb-6.2.15)
id=22   @192.168.10.3  (mysql-5.1.23 ndb-6.2.15)

この画面がちゃんと表示されれば、インストールは成功です。

それでは srv2 と srv3 でデータが同期されることを確認しましょう。

まずは srv2 で。

% mysql -u root -p
mysql> create database cluster_test;
Query OK, 1 row affected (0.24 sec)

そして srv3 で。

% mysql -u root -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| cluster_test       |
| mysql              |
| ndb_12_fs          |
+--------------------+
4 rows in set (0.00 sec)

を!?

では srv3 で

mysql> use cluster_test
Database changed
mysql> create table foo(bar int(10) primary key, name varchar(255))
    -> engine=ndbcluster;
Query OK, 0 rows affected (0.82 sec)

そして srv2 で

mysql> use cluster_test
Database changed
mysql> show tables;
+------------------------+
| Tables_in_cluster_test |
+------------------------+
| foo                    |
+------------------------+
1 row in set (0.00 sec)

をを!?

では srv2 で

mysql> insert into foo values(1, 'ggrecus');
Query OK, 1 row affected (0.01 sec)

そして srv3 で

mysql> select * from foo;
+-----+---------+
| bar | name    |
+-----+---------+
|   1 | ggrecus |
+-----+---------+
mysql> drop database cluster_test;
Query OK, 2 rows affected (0.82 sec)
1 row in set (0.02 sec)

うむ。
そして srv2 で

mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| ndb_11_fs          |
+--------------------+
3 rows in set (0.00 sec)

素敵ですね。

ちなみにテーブルを作るときに engine=ndbcluster を入れ忘れると同期されないので寂しいです。

さて、これでやっと MogileFS をインストールする準備ができました。

長かったですね。当初の目的を忘れるところでしたよ…

2008-06-30

MogileFS を Ruby の mogilefs-client から触ってみた

はてなブックマーク   livedoor clip

日野原です。

今回はこの前に引き続いて MogileFS の話題です。

前回の最後に唐突に ruby から触ると言う話をした通り ruby のクライアントライブラリから MogileFS を操作してみましょう。

まず環境ですが、前回と同じ Fedora7 on coLinux です。
その上に、ruby と rubygems をインストールしておきます。

% sudo yum install ruby ruby-ri ruby-rdoc ruby-libs\
  ruby-irb ruby-devel rubygems

次に MogileFS のクライアントを gem でインストールします。

% sudo gem install mogilefs-client

ではこれで ruby のプログラムから触ってみましょう。
まずは下準備です。

% irb
irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'mogilefs'
=> true

次に domain と class を作成します。(結果は見やすいように改行しています)

irb(main):003:0> mogadm = MogileFS::Admin.new :hosts => ["127.0.0.1:7001"]
=> #<MogileFS::Admin:0xb7649c10
              @readonly=false,
              @backend=#<MogileFS::Backend:0xb7649bc0
                                   @mutex=#<Mutex:0xb7649b70>,
                                   @lasterrstr=nil,
                                   @lasterr=nil,
                                   @hosts=["127.0.0.1:7001"],
                                   @socket=nil,
                                   @timeout=3,
                                   @dead={}>,
              @hosts=["127.0.0.1:7001"],
              @timeout=nil>
irb(main):004:0> mogadm.create_domain "hoge"
=> "hoge"
irb(main):005:0> mogadm.create_class "hoge", "important", 3
=> "important"
irb(main):006:0> mogadm.create_class "hoge", "normal", 2
=> "normal"

これでファイルを保存する準備が整いました。
ここで作った domain とは、保存するファイルのまとまりを表すもので、ファイルは必ず domain に属します。蓄積されているファイルを取得するときには、この domain と key の対を指定します。
key とはファイルごとに一意に定める値です。domain をまたがって key を一意にする必要があるかどうかはまだ調べていないので、興味のある方は自分で調べてみてください。
class はファイルの持つ属性で、class ごとにいくつのコピーを保持しておくかを指定することができます。ここでは、important というクラスを持つファイルは 3つのコピーを、normal クラスのファイルは 2つのコピーを保持しておくように指定しました。

では実際にファイルを保存してみましょう。
irb を起動したカレントディレクトリに test.jpg という JPEG 画像と、「Hello, world!」と書かれている ttt というテキストファイルを置いておきます。(結果は見やすいように改行しています)

irb(main):007:0> mog = MogileFS::MogileFS.new :hosts => ["127.0.0.1:7001"], :domain => "hoge"
=> #<MogileFS::MogileFS:0xb76328a8
                @readonly=false,
                @root=nil,
                @backend=#<MogileFS::Backend:0xb7632844
                              @mutex=#<Mutex:0xb76327f4>,
                              @lasterrstr=nil,
                              @lasterr=nil,
                              @hosts=["127.0.0.1:7001"],
                              @socket=nil,
                              @timeout=3,
                              @dead={}>,
                @hosts=["127.0.0.1:7001"],
                @domain="hoge",
                @timeout=nil>
irb(main):008:0> mog.store_file "testimage001", "normal", File.new("test.jpg")
=> 1441195
irb(main):009:0> mog.store_file "testtext001", "important", File.new("ttt")
=> 14
irb(main):010:0> mog.store_file "testtext002", "important", "ttt"
=> 14

store_file の引数は一つ目から順に key, class, ファイルです。
ファイルの指定は File オブジェクトでもファイル名でもいいらしいです。
また、store_content を使えば

irb(main):011:0> mog.store_content "testtext003", "normal", "I'm hungry..."
=> 13

のように文字列を直接保存することもできます。

ちなみに、これらのファイルは /etc/mogilefs/mogstored.conf の中で指定した docroot 以下に保存されています。
実際にちょっと見てみましょう。

% ls -l /var/mogdata/dev1/0/000/000/
合計 1420
-rw-r--r-- 1 root root 1441195 2008-06-26 21:23 0000000002.fid
-rw-r--r-- 1 root root      14 2008-06-26 21:24 0000000003.fid
-rw-r--r-- 1 root root      14 2008-06-26 21:25 0000000004.fid
% ls -l /var/mogdata/dev2/0/000/000/
合計 1424
-rw-r--r-- 1 root root 1441195 2008-06-26 21:23 0000000002.fid
-rw-r--r-- 1 root root      14 2008-06-26 21:24 0000000003.fid
-rw-r--r-- 1 root root      14 2008-06-26 21:25 0000000004.fid
-rw-r--r-- 1 root root      13 2008-06-26 21:28 0000000005.fid
% ls -l /var/mogdata/dev3/0/000/000/
合計 12
-rw-r--r-- 1 root root 14 2008-06-26 21:24 0000000003.fid
-rw-r--r-- 1 root root 14 2008-06-26 21:25 0000000004.fid
-rw-r--r-- 1 root root 13 2008-06-26 21:28 0000000005.fid
% file /var/mogdata/dev1/0/000/000/0000000002.fid
0000000002.fid: JPEG image data, EXIF standard
% cat /var/mogdata/dev1/0/000/000/0000000003.fid
Hello, world!
% cat /var/mogdata/dev3/0/000/000/0000000005.fid
I'm hungry...

ファイルサイズで判断すると、ちゃんとimportant で指定したファイルが 3つずつ、normal で指定したファイルが 2つずつ生成されていますね。
このファイル名は環境によっては異なってくるかもしれないので、バイナリファイルを cat してしまわないように気をつけてください。

ファイルを読み込むときは get_file_data に key を指定します。

irb(main):012:0> mog.get_file_data "testtext003"
=> "I'm hungry..."
irb(main):013:0> mog.get_file_data "testtext002"
=> "Hello, world!\n"

また、MogileFS::Admin を使ってデバイスや保存されているファイルの情報を取得することもできます。(結果は見やすいように改行しています)

irb(main):037:0> mogadm.get_stats
=> {"fids"=>{"max"=>5, "count"=>0},
    "device"=>[{"status"=>"alive", "files"=>"3",
                "id"=>"1", "host"=>"localhost"},
               {"status"=>"alive", "files"=>"4",
                "id"=>"2", "host"=>"localhost"},
               {"status"=>"alive", "files"=>"3",
                "id"=>"3", "host"=>"localhost"}],
    "replication"=>[{"files"=>"2", "class"=>"important",
                     "devcount"=>"3", "domain"=>"hoge"},
                    {"files"=>"2", "class"=>"normal",
                     "domain"=>"hoge", "devcount"=>"2"}],
    "file"=>[{"files"=>"2", "class"=>"important", "domain"=>"hoge"},
             {"files"=>"2", "class"=>"normal", "domain"=>"hoge"}]}

さて、これで最低限の読み書きはできました。
これだけできればきっと誰かが rails のファイルアップロードプラグイン(attachment_fuとか?)のバックエンドに MogileFS が使えるようにしてくれることでしょう。
楽しみですね。

2008-06-13

MogileFS を Feodra7 on coLinux に yum で入れてみた

はてなブックマーク   livedoor clip

日野原です。

今、分散ファイルシステムが熱いです。負荷分散とか冗長化とかを考えていると、当然ファイルシステムも分散させたくなるのです。…なりますよね?

というわけで手元の Fedora7 on coLinux に分散ファイルシステムの一つの実装である MogileFS を入れてみました。

ただ、CPAN を使える人向けの情報はこのページ(Six Apart – Tech Talk Blog: MogileFS のインストールと初期設定)にすでにあるので、今回は perl をちゃんと使ったことがなくてもできるやり方でインストールしてみました。正確に言うと私が CPAN を使って入れようとしてできなかったので回避しただけなんですけど…

というわけでインストールの手順は独自ですが、その後の初期設定などは前述のページで説明されているやり方とほとんど同じです。

前提となる環境は Fedora7 (coLinux) で yum と vi と svn、make が使える状態です。

まず、必要とされているパッケージをインストールします。先ほども言ったように CPAN は使わずに yum でインストールします。とある CPAN Author に言わせると「yum で perl のモジュールを入れる感覚が受け付けない」そうですが、私は perl はまともに使ったことがないので違和感なしです。まぁ、私も yum で ActiveRecord とかをインストールされるとしょんぼりするので同じようなものなのでしょう。

% sudo yum install perl-Net-Netmask perl-Danga-Socket perl-IO-AIO \
Perlbal mysql-server

次に MogileFS も yum で提供されているので入れてしまいます。
そういえば、上で入れた yum は MogileFS を入れるときに依存関係で勝手に入ったかもしれないですね…

% sudo yum install perl-MogileFS-Client perl-MogileFS-Utils

で、これだけだとMogileFSのリポジトリのサブディレクトリの api と utilities に相当する部分しか入らないので、server の部分は自分でコンパイルします。

% svn co http://code.sixapart.com/svn/mogilefs/trunk mogilefs
% cd mogilefs/server
% perl Makefile.PL

ここで ExtUtils/MakeMaker.pm がないと言われるので入れます。

% sudo yum install perl-ExtUtils-MakeMaker
% perl Makefile.PL
Checking if your kit is complete...
Looks good
Warning: prerequisite Gearman::Client 1.07 not found.
Warning: prerequisite Gearman::Client::Async 0.93 not found.
Warning: prerequisite Gearman::Server 1.08 not found.
Writing Makefile for mogilefs-server

問題ないらしいですが、せっかくなのであった方がいいと言われている(らしい) Gearman も入れてしまいましょう。

% sudo yum install perl-Gearman perl-Gearman-Client-Async \
perl-Gearman-Server
% perl Makefile.PL
Writing Makefile for mogilefs-server

問題なさそうです。これでインストールしてしまいます。

% make
% sudo make install

これでインストールは完了です。ここから初期設定に入ります。

まずは mysql の起動とパスワードの設定

% sudo /etc/init.d/mysqld start
% mysqladmin -u root password 'rootpass'

次に MogileFS の DB スキーマを作成します。

% mogdbsetup --dbrootpass=rootpass --dbpass=mogpass

いろいろ聞かれても yes でいいです。面倒なら –yes オプションをつけるといいらしい。

ここ以降は前述のページの説明とほとんど一緒ですが、一応書いておきます。

ここからは tracker の設定です。
まずは mogilefsd 用のユーザを作ります。

% sudo /usr/sbin/useradd -s /sbin/nologin mogile

次に設定ファイルを。

% sudo mkdir /etc/mogilefs
% sudo cp conf/mogilefsd.conf /etc/mogilefs
% sudo vim /etc/mogilefs/mogilefsd.conf

変更点は daemonize の行のコメント解除と db_user、db_pass の設定です。

daemonize = 1
db_dsn = DBI:mysql:mogilefs:host=127.0.0.1
db_user = mogile
db_pass = mogpass
listen = 127.0.0.1:7001
conf_port = 7001
listener_jobs = 10
delete_jobs = 1
replicate_jobs = 5
mog_root = /mnt/mogilefs
reaper_jobs = 1

で、mogilefsd を起動します。

% sudo -u mogile mogilefsd

次は mogstored です。

リポジトリに入っていた mogstored の config ファイルは古い形式らしくて使えないので、新しく作成します。内容は3行だけです。

% cat /etc/mogilefs/mogstored.conf
httplisten = 0.0.0.0:7500
mgmtlisten = 0.0.0.0:7501
docroot = /var/mogdata

で、docroot に指定したディレクトリを作成し、起動します。

% sudo mkdir /var/mogdata
% sudo mogstored -d

後は件のサイトの説明に従い使えるようにしていきます。

% mogadm host add localhost --port=7500
% sudo mkdir /var/mogdata/dev1
% sudo mkdir /var/mogdata/dev2
% sudo mkdir /var/mogdata/dev3
% mogadm device add localhost 1
% mogadm device add localhost 2
% mogadm device add localhost 3
% mogadm host mark localhost alive
% mogadm check
Checking trackers...
127.0.0.1:7001 ... OK

Checking hosts...
[ 1] localhost ... OK

Checking devices...
host device         size(G)    used(G)    free(G)   use%   ob state   I/O%
---- ------------ ---------- ---------- ---------- ------ ---------- -----
[ 1] dev1             3.777      1.257      2.520  33.28%  writeable   0.0
[ 1] dev2             3.777      1.257      2.520  33.28%  writeable   0.0
[ 1] dev3             3.777      1.257      2.520  33.28%  writeable   0.0
---- ------------ ---------- ---------- ---------- ------
total:    11.331      3.771      7.559  33.28%

ここまでで、とうとう ruby の mogilefs-client からさわれるようになりました。

しかし長くなってしまったので、ruby からさわるのは次回にします。
お楽しみに。

補足として、別の環境でやってはまったときの解決策も書いておきます。

mogstored を実行したときに

Weak references are not implemented in the version of perl …

というエラーが出てしまった場合、Scalar::Util を入れ直すと直ります。perl 使いの間では有名なエラーだそうです。

あと、MySQL を独自にビルドしていて socket の位置が異なる場合、
/usr/lib/perl5/site_perl/5.8.8/MogileFS/Store/MySQL.pm
の15行目(私の環境のパスです)を

return "DBI:mysql:$dbname;host=$host;mysql_socket=/tmp/mysql.sock"
               . ($port ? ";port=$port" : "");

と書き換えれば(/tmp/mysql.sockの部分はsocketの位置にしてください)とりあえず動きます。けど本当にとりあえずなのでオススメしません。自分しか困らない開発環境でだけやってください。

2008-06-06

仮想化の使い道

はてなブックマーク   livedoor clip

日野原です。

最近いろいろなところで仮想化と言う言葉を聞くようになってきました。
私も開発環境ではいろいろなところで仮想化技術のお世話になっていますが、ricollab のような場所では仮想化技術は役立つのでしょうか。

よく耳にする仮想化技術の導入事例のほとんどは、「たくさんあるレガシーなサーバを仮想化技術を使うことで集約し、コストを削減した」と言うものです。しかしこれではこれから Web 上のサービスとやっていこうという我々の心には届きません。

ではどういう使い方だとうれしいでしょうか。

まず、開発環境としての使い方では、Windows マシン上で VMWare や coLinux を使って開発している人は多いと思います。

また、実験環境を作るときには仮想マシンが活躍します。
我々の例でいうと、実運用環境は DB やアプリ、ロードバランサなど何台ものサーバで構成されているのですが、社内ネットワークにある実験環境では同じ台数のサーバを準備するのはもったいないので xen を使って2台のマシンで同等の環境を構成しています。当然一台あたりに割り当てられるメモリや CPU の資源は少なくなるのでパフォーマンステストなどはできませんが、一台が停止してもサービス全体は止めないとか、アプリケーションのデプロイのテストなどはこの環境で十分です。

それでは、実運用環境ではどうでしょう。

まず一つ、実サーバを用意せずに Amazon EC2 を利用すると仮想化技術の恩恵にあずかることになりますね。
ただ、これでは「自分で仮想化している!」という実感がわきません。私だけ?
今後は必要になってくることだとは思っていますが、今のところはちょっとおいておきます。

次に考えたのは、実サーバ上には仮想マシンのホストとなる最低限の環境だけ用意し、アプリや DB と言った役割のサーバはすべて仮想マシンで提供するといった形態です。そして、故障対策として予備機を仮想マシンのホストだけインストールした状態で置いておきます。

これだと、一台のサーバが壊れて代替機を準備するとき、空いている予備機にイメージをコピーするだけでいいと言うメリットがあります。
でもこれは kickstart などの設定をちゃんとしてインストールを自動化おけばたいして変わらないですね。それにその方が仮想化によるパフォーマンスの劣化も気にしなくていいのでわざわざ仮想化するメリットがあまり感じられません。

では仮想マシンのイメージを実サーバに2つ以上おけるサイズにしておいて、一台が壊れたときに同じ役割のイメージを他の稼働しているサーバ上で動かすようにすればどうでしょう。

これならば予備機をもし切らしている場合でも代わりが作れるし、よさそうですね。ただ、たとえば一つの実サーバ上に DB サーバ用の仮想マシンが2台載ってしまうと HDD アクセスなどが大変なことになりそうなので、CPU を主に使うアプリサーバとメモリとディスク容量を主に使う DB サーバを一緒にするなど、載せるイメージをうまく配分する必要はありそうです。

などといろいろ考えて楽しんでいるのですが、実はそんなことよりも先に ricollab の単一故障点をなくさないといけないのです…

2008-04-15

私のお気に入り(キーボード:日野原編)

はてなブックマーク   livedoor clip

箸休め担当になってしまっている日野原です。今日も今日とて箸休め的にこだわりのキーボードについて話します。

まずは Happy Hacking Keybord の開発にも携わった和田先生の言葉を引用します。

アメリカ西部のカウボーイたちは、馬が死ぬと馬はそこに残していくが、どんなに砂漠を歩こうとも、鞍は自分で担いで往く。馬は消耗品であり、鞍は自分の体に馴染んだインタフェースだからだ。
いまやパソコンは消耗品であり、キーボードは大切な、生涯使えるインタフェースであることを忘れてはいけない。

http://www.pfu.fujitsu.com/hhkeyboard/dr_wada.html

心に響きますね。私がこれを知ったのは先週山本が他部署のメンバーに送ったメールに私がCCで入っていたからで、つい最近なんですけど。

いい言葉で心が洗われたところで本題に入りましょう。

私が現在メインで使っているキーボードは ThinkPad X40 (JIS配列)です。一番のこだわりポイントはトラックポイントですね。キータッチはそれほどこだわっているつもりはないですが、ずっとこれでやってきた のでデスクトップ PC 用の普通のキーボードを叩くとストロークの深さがちょっと気になるようになってしまいました。

以前は Happy Hacking Keybord Lite2 の JIS 配列版を 使っていたのですが、デスクトップ PC のレンタル期間が切れたタイミングで、ちょうど開発の業務がすべてサーバ上で済んでいて、 CPU パワーが要らなかったのでノート PC と外付けディスプレイ1台に借り換えてしまいました。それ以来 ThinkPad を愛用しています。今はメインの開発マシンはデスクトップ PC になっていますが、それも ThinkPad で操作しています。

デスクトップ用には以前 IBM の USBスペースセーバーキーボード(黒)も 買ったのですが(私物です)、トラックポイントの背が高すぎてちょっと使いにくく、メインにはなれませんでした。これは今もデスクトップ PC につながっていてログインパスワードの入力用に使われています。ついでに言うとデスクトップ PC には Logicool の TrackMan Wheel も接続されています。これは会社ではあまり活躍の場がありませんが、自宅ではキーボードにトラックポイントがついていないため、メインのポインティングデ バイスです。(自宅では会社にいるときほどキーを叩かないので、キーボードは PC を買ったときについてきた NEC の何かです。)

ところでデスクトップ PC をどうやって ThinkPad から操作しているかというと、Synergy というソフトでネットワーク越しに共有しています。
Synergyについて詳しくはググってもらえばいいとして、このソフトはもう手放せなくなってしまいました。ThinkPadの真ん中クリックがデスクトップ PC に伝わらないなどの問題もあるのですが、それを補って余りある快適さを手に入れています。

あと、私の席に来た人がデュアルディスプレイのデスクトップ PC を ThinkPad で操作しているのを見て、「ノート PC にディスプレイ二つもつなげられるの?」とか「これどうなってんの?」とか聞いてくるのも割と愉快です。

さて、これまでさんざん ThinkPad のキーボードを持ち上げてきましたが、問題がないわけではありません。私はテキストエディタは vim(Windows では gVim)を使用しているので(この記事も下書きはgvimです)、ESC キーが遠いとやっていられません(Ctrl+[ はまだ慣れません)。また、IME の on/off は大学時代に使っていた canna の設定のせいで Ctrl+O に慣れてしまっているため、Ctrl キーも A の隣にないと小指がつりそうになります(vim でも Ctrl キー多用しますしね)。ThinkPad では小指の付け根で押すって言う芸当は難しいです。
というわけで、AltIME を使って Ctrl と Caps Lock を、Esc と 半角/全角 を入れ替えています。AltIMEには特に強いこだわりがあるわけではないのですが、以下のような点が気に入っています。

  • Vista でも問題なく動作している
  • Synergy と変にかち合わない
  • ペアプログラミングで他の人にPCをさわらせる場合には簡単に設定を戻せる

まとめると、私の快適キーボード環境は以下の3つで成り立っています。

最初は周りの人の話も書こうと思っていたけど、十分に長くなってしまったので自重しておくことにします。ちょっとだけ触れておくと、HHK と東プレの Realforce は人気です。あと Kinesis 使ってる人もいます。

次回は箸休めじゃない記事を書きます(とここで宣言することで自分を追い詰めてみるテスト)。

2008-04-01

ricollab実験サービス第一弾を開始します!

はてなブックマーク   livedoor clip

本日より、ricollabの語源の一つである「リコーラボ」としての活動の第一弾、郵便番号検索サービスを開始します。

同時に、このブログのサーバも社内のマシンルームから外部のデータセンターに移動して、心機一転です。読者の皆さんにはサーバの場所が変わってもあまり関係ないかもしれませんが、法定点検による停電の心配などが無くなりました。

「何でリコーが郵便番号なの?」という疑問も大いにあるかとは思いますが、いろいろなサービスで使われる情報なので応用が利くというのと、Webサービスとしてまずは小規模なところからスタートし、サーバの運営やWebサービスの提供までの設計・開発ノウハウを蓄積していこうという狙いがあります。

ただし、小規模なアプリとは言ってもただ単に日本郵便のゆうびんホームページで公開されている郵便番号データを検索できるようにするだけではつまらないので、山本がガチで設計したRESTfulなAPI仕様になっています。
検索結果はJSONPで取得することもできるので、よろしかったらWebアプリからご利用ください。

RESTfulにするためにどうやって設計していったかなんて話も今後公開していこうと考えておりますので、ご期待ください。

ご意見やご質問がある場合はこの記事にコメントしていただければ対応しますが、内容が公開されては困る場合は問い合わせ受付フォームもご利用ください。

2008-03-26

FrontRunnerに座談会「進化し続けるWebの世界に毎日がワクワクの連続」が掲載されました

はてなブックマーク   livedoor clip

日野原です。

山本が約一ヶ月間の育児休業に入ってしまい、バタバタしていたので記事の掲載が遅くなってしまいましたが、山本と私、上司の高津、それに研究開発本部の中川の4人(順番は下の写真と対応しています)がWeb技術にまつわる座談会をおこない、スペシャル座談会「進化し続けるWebの世界に毎日がワクワクの連続」としてFrontRunnerに掲載されました。
座談会メンバー一覧
FrontRunnerはリコー ソフトウェア研究開発本部の Web サイトの 1 コンテンツで、本部員のインタビューなどを掲載している連載です。今回はスペシャルと言うことで研究開発本部からゲストを迎え、今までの対談記事形式ではなくビデオでの配信になっています。

当初の予定では以前の座談会と同じ様に対話の書き起こし形式に、おまけとして撮影したビデオの抜粋をいくつか掲載しようということだったのですが、MPMeisterチームの撮影技術がすばらしく、そのまま使えるだろうと言うことで急きょビデオメインの記事になりました。

自分の録音された声を聞くのは私には耐えられないのでちょっとだけしか見ていないのですが、内容としては我々の仕事の仕方やこだわり、Webの世界のこれからなどについて話しています。このブログはどんなやつが書いているんだと興味のある方は見てみてください。

なお、座談会のページでWindows Media Player/IEとなっているリンクはMPMeisterで作られたコンテンツへのリンクですので、注意事項は前の記事と同様です。Firefoxをお使いの方はFLASHの映像をご覧ください。