MongoDBドキュメント日本語訳一部完了のお知らせ

12th Oct, 2010 | mongodb

ぼちぼち進めてきた MongoDB の日本語訳ですが、その中の大きなセクションの一つである Developer Zone翻訳 が完了しました。Developer Zone内のすべてのページは完全に英語版と同期しているはずです。

Developer Zoneとは

このセクションでは、MongoDBの特徴、仕組み、基本的な操作、MongoDBを使ってアプリケーションを開発する開発者はどういうことに意識した方がいいのか、と言ったことが書かれています。

MongoDBで開発をする人はまず一読しておくべき内容です。

目次

誤字脱字、苦情、要望の連絡先

今回の更新で、Developer Zone内のすべてのドキュメントに、元の英語ドキュメントへのリンクを置きました。「何かおかしいな」というところがあればそっちも見てみてください。

連絡先は、私の目に入るところならどこでもいいです。見ているのは、ここのコメントや Twitter です。ここの右上にメールアドレスも載せています。

ドキュメントの各ページにDisqusのコメント欄がありますが、ここは今のところ私に通知されないので気がつかない可能性が高いです。MongoDBの人に相談中です。

今後

MongoDBのドキュメントのもう一つの柱である Admin Zone というのがあります。これは、どちらかというと運用サイドのことが書かれています。たとえば、MongoDBの目玉機能の一つである複数台での運用(shardingやreplication)などもこのセクションにあります。Admin Zoneは一部の翻訳が終わっているのですが、私一人では手が回らないので諦めかけてたところ @doryokujin さん が手伝ってくれることになりました。

今後、私は Developer Zone のメンテナンス(中身を良くしていくことと、最新に追いついていくこと)に集中し、 Admin Zone は @doryokujin さんにお任せする予定です。

では!



tenshiでサーバ上のログファイルを効率良く監視

1st Oct, 2010 | sysadmin

tenshiとは

サーバ上のログファイルは、ただ記録しておいて問題があったときの調査に使うだけではなく、リアルタイムで監視することでアプリケーションやサーバの不具合の早期発見をすることができる。問題が表面化する前に対策を行なうにはログの監視が不可欠だ。

しかし、サーバは、種類も数もどんどん増えていくものだし、それに合わせログファイルの種類も量もどんどん増えていく。全部見るのはもちろん不可能だし、適当に通知をしてもメールボックスを溢れさしてしまうことになり、結局は無視することになってしまい意味がない。

そこで、賢く効率的に監視するために tenshi というツールが非常に便利に使える。

このツール、最近しばらく使っていなかったのだが、最近会社で再び使い始め、便利さを再確認したので紹介してみる。知る人は知るツールだと思うけどいまいちマイナーなのかな?

tenshiは、元々はGentoo Linuxプロジェクトのインフラ用に作られたものなのだけど(だったと思う)、今では色々なLinuxディストリビューションや、*BSDのパッケージに入っているようだ。うちではFreeBSDで使っている。

tenshiの基本的な動作

  • 指定したログファイルを常時監視 (最近ではsyslogサーバとして動くモードもあるみたい)
  • 設定した条件にマッチした(またはマッチしない)ログが現れたら、指定したタイミング(リアルタイム/毎時間/毎日とか)でメールで指定した管理者に通知

tenshiの優れている点

  • とても小さいツールで導入や設定が簡単。設定ファイルを一つ書くだけ。
  • ログのマッチングルールは正規表現なので柔軟。どんな形式のログファイルでもテキストファイルなら対応可能。
  • メール通知する頻度をマッチングルール毎に変更できる。たとえば「多分重大なエラーではないけど、一日に一度くらいは受け取って眺めておきたいようなログ(例えば、Webサーバの404 Not Foundエラーのログとか)」の指定ができる。
  • 同じようなエラーをまとめてくれる。同じエラーが大量に出たときでもメールボックスが溢れにくい。

tenshiの運用

もちろん、各サーバにtenshiを入れてもいいのだけど、うちでは、ログサーバにsyslog経由でログを集め、そこでtenshiを動かしている。監視対象は、Railsアプリケーションのログや、データベースのログ、OSのログなど広い範囲。

また、tenshiのマッチングルールは、ホワイトリスト方式で運用している。つまり、とりあえず最初はすべてのログを通知。そして無視できるものをホワイトリストとしてどんどん追加していく。

この方法だと「未知なログ」を闇に葬ることなくしっかり通知してくれるので、予期しない不具合の兆候(ってだいたいそうだよね)を見逃すことなく通知してくれる。

tenshiの設定

  • 一つ以上のqueueを作成する。queueは正規表現でマッチしたログを突っ込む場所。queue毎に通知先のメールアドレスや通知タイミング(その場で通知や、1日1回通知とか)を設定できる
  • 通知させたいログを正規表現でマッチさせqueueまたはtrashに突っ込む。trashは見なくてもいいログの宛先。

詳しくは http://www.inversepath.com/tenshi_man.html 参照。

おわり

流行りのかっこいいツールとかもいいけど、こういうプロジェクトの地固め的なツールも大事ですね。



Chefを最速で使いこなすためのいくつかのポイント

7th Sep, 2010 | chef sysadmin ruby

前回書いた さようならPuppet、こんにちはChef が、それなりに反響あったので調子に乗ってもうちょっと書いてみる。

前回、ChefはPuppetに比べて簡単!とか書いたが、実際には慣れるまでそれなりに戸惑うところがあった。

ドキュメント を読み、実際に触っただけでは一発で理解できなかった部分を、自分のメモを元に晒しておく。これだけ読んでもいまいちだと思うので、関連するドキュメントへのリンクも張っておくので合わせて読んでみると高速でChefを理解できるかも!

client vs node

ドキュメントを読んだりChefを触っていると clientnode という二つのワードが出てくる。この二つは似ているけど別物。

client は文字通り Chef server の相手になるもの。 Chef server にアクセスするものはすべて client になる。例えば、管理ツールである knife (後述)や、管理用のWeb UIなども client になる。認証や通信はすべて clientChef server と行う。

一方、 node というのは、Chefで管理するマシン/サーバ自体を指す。各 nodeChef server にアクセスし自分の設定を持ってくるのが、これは実際には node にある client 経由で行う。

そのため通常は nodeclient でもある。そして、 client数 >= node数 になる。

書いてしまうと簡単なのだけど、最初は両者がごちゃごちゃになってしまっていた。ここをしっかり理解しておくとトラブルシューティングもしやすくなる。

トラブルシューティングの例:

ある node (の client )で、サーバにアクセスするのに必要な秘密鍵を間違って消してしまい Chef server へのアクセスができなくなってしまった。この場合どうすればいいか?

対応策: 鍵情報は client に結びついているので、 client の鍵ペアを作り直せばいい(または、 client をサーバから削除して作り直す)。 どちらの場合も、 node の情報をいじる必要ない。

knife

Chefサーバ上にあるデータを触るためのコマンドラインツール。主に手作業でサーバの情報にアクセスしたいときに使う。管理者が使用するもの。上に書いたように knife 自体も client になる。管理者毎に別の client として登録する。

特に、 node の情報は、他の設定と違いサーバ上にしかないので、このコマンドをよく使う。

例1: node の情報(JSON形式)を $EDITOR で開き編集する

$ knife node edit hogehoge.example.com

例2: 指定した client を削除

$ knife client delete fugafuga.example.com

node と cookbook (recipe) と role

まず、 node は、上にも書いたように管理対象のサーバのこと。

cookbook は、実際にChefで行いたい設定の手順を記述したもので、基本的に環境に依存するのものは書かない。依存するものは rolenodeattributes に書く(後述)。

recipe とは、設定を記述したrubyスクリプトのことを指す(ドキュメント等で cookbook のことを recipe と呼んでいるケースもあるので注意)。

一つの cookbook は複数の recipe を持つことができる。例えば, LDAP cookbookの中に、 LDAPクライアント用の recipe と、LDAPサーバ用の recipe を持つことができる。

role は、サーバの役割を記述したもの。 どの recipe を使うかということを主に書く。また、 node は、基本的に1つ以上の role を持つ。ただし、ちょっとややこしいが、 nodereciperole を介さないで直接持つこともできる。

たとえば、 “hoge-system-app” role というのを考えてみる。これは “hoge-system” という Webシステムのアプリケーションサーバを想定する。

ここで、

  • hoge-system-app1.example.com
  • hoge-system-app2.example.com
  • hoge-system-app3.example.com

という3つの node があったとする。3つとも、"hoge-system-app" role を持つ。ただし “hoge-syste-app1.example.com” だけは、特別に、"git" クライアントも入れたい。こういう場合には、gitの recipe を直接指定することもできる。

  • hoge-system-app1.example.com
    • hoge-system-app role
    • git recipe
  • hoge-system-app2.example.com
    • hoge-system-app role
  • hoge-system-app3.example.com
    • hoge-system-app role

もちろん、gitの recipe を持つような、 developer role みたいのを作り、それにgitを持たせ、 node にセットすることもできる。

基本的には、 role 経由で管理したほうがいいが、本当に例外の場合はわざわざ role を作らなくてもいいかもしれない。これは設計次第。

attributes

attributes は、実際に設定したい値(パラメータ)のこと。上述したように、 cookbook / recipe には、サイト固有の情報を持たせないのが原則なので、そういうものはすべて attributes にして外出しにする。

attributesrecipe 自体や、 recipe 経由で template (erbで記述) から使われる。基本的にrubyのHashそのもの。

attributesrecipe にも設定できるし、 rolenode にも書ける。

recipe に書いた attributes がその recipe のデフォルト値で、それを rolenodeattributes で必要に応じて上書きする、と考えると理解しやすい。

例:まず、 tokyo-office という role があったとしよう。とある東京オフィスにあるサーバ群はこの role を使うというルールになっている。今、この role に対して、LDAPクライントを設定したいとする。

最初に、LDAP cookbook ( recipe ) を作成する。このとき、LDAPサーバのホスト名(IP address)みたいなのがサイト固有の情報になるので、 attributes に切り出す。

次に作成した、 recipetokyo-office role に設定する。このとき attributes として切り出した LDAPサーバの IP addresses を roleattributes ととして設定する。

ここで、もし、その中のある、特定の node だけに対して例外的に特別な値(例えば、テスト用のLDAPサーバを見させたいとか)を書きたい場合には、 その nodeattributes に書いて、 roleattributes を上書きする。

自分が理解しているのはこんな感じ。enjoy cooking!



さようならPuppet、こんにちはChef

30th Aug, 2010 | chef sysadmin puppet ruby

ここ最近、サーバの設定ファイルの管理で Chef を使い始めている。まだ全然詳しくないけど、今感じている「Chefの楽しさ」を誰かに伝えておきたかったので、ファーストインプレッションを簡単に。

Puppetを今までそこそこ使っていたので、どうしてもそことの比較な感じになっちゃいます。Puppetも良いのだけど、Chefは後発ということでさらに良くなっている感じ。

基本的な仕組

これは、Puppetとほぼ同じ。クライアント-サーバ型のシステム。設定を書き、それをサーバに置いておく。クライアントはサーバと接続し、自分自身の設定を書き換えたり、必要なソフトウェアをインストールしたりする。

rubyな設定ファイル

Puppetは基本的に独自DSLで設定ファイルを記述すので「覚えるのがめんどくさい」「細かいこと、ちょっと無茶なことをしようとすると大変」。Chefの設定ファイルはrubyそのものなので、rubyで表現できることは何でもできる。とは言えDSL風にもなってるのでrubyを知らなくてもなんとかなるレベルでもある。その辺はさすがにruby。実際にどんな感じで設定を書くか、というのは、 この辺参照

ローカルでのテストが楽

chef-soloというコマンドがあり、これを使うとChefサーバに接続せずにローカルだけでテストができる。大袈裟なテスト環境を作らなくても自分の環境でテストできるのがとても楽。

設定ファイルが直感的

Puppetは、manifestとかmoduleとかclassとか、どうも最後まで慣れなかったが、Chefは初めの数時間で、すーっと頭に入ってきた。この差はでかい。

いくつかの理由があるけど、まず、設定ファイルのディレクトリ構成がわかりやすいというのが大きい。

設定ファイル内の主要なディレクトリは、cookbooksとrolesの二つだけ。cookbooksの中には、cookbookと呼ばれるソフトウェア毎の設定を置くサブディレクトリがある。一つのcookbookに関連する設定はそのサブディレクトリ内にすべて置く。

例:

cookbooks
  + sshd
    + recipes
    + templates
    + attributes
  + sudo
    + recipes
    + templates
    + attributes
  + apache2
    + recipes
    + templates
    + attributes
  + .....
roles
  + hoge_app.rb
  + hoge_rproxy.rb

この「cookbook内で完結し独立している」というのがとても扱いやすい。完結しているので、自分で管理するのももちろん楽だけど、他の人や会社がが作っているcookbookの流用もしやすい。 Chef公式のcookbook はもちろん、 37 signalsのcookbooks もよく参考にしている。

roleは、どのcookbookをどういう設定で使うか、というのを書く。そして作成したroleを実際のサーバに割り当てる。一つのサーバが複数のroleを持つこともできる。このroleとcookbookという関係もとてもわかりやすい。

各roleの中にはどのcookbookを使うか、というのを羅列する。例えば,

run_list "recipe[apache2]", "recipe[apache2::mod_ssl]", "role[monitor]"

みたいな感じ。そして、cookbookに対する設定もrole内に書く。

default_attributes "apache2" => { "listen_ports" => [ "80", "443" ] }

(このサンプル から引用)

こんな感じ。とってもわかりやすいでしょ?

Git等との距離感

設定ファイルはもちろんGitとかで管理するのだけど、それと実際のChefの動作部分は特に関係ない。設定ファイルを書き換えた後commit/pushで設定の反映ではなく、rake upload_cookbooks 等のコマンドでサーバへ反映。これがなかなか気持ちいい。ソフトウェアをdeployする感覚と似ている。

よくわかってないところ

サーバ側の設定は 弊社のすばらしいシステム管理者の人 がしてくれたので自分はよくわかってない。結構ややこしいみたい。

嫌いなところ

SEO的にどうよ、な部分。Chef自体もそうだし、出てくる単語もcookbookとかrecipeとかknifeとか、ぐぐるの大変だよ!

そんなわけで

とりあえず使い始めてみましたよ。という感じです。

追記: もうちょっと書いた。

追記2: chefのプレゼン資料のようです。わかりやすい。



nginxでcacheの部分的なpurgeをしてみる (あまり使えない)

18th Aug, 2010 | nginx

ちょっと調べてみたのだけど、現実的にあまり使えない気がする。でもせっかく調べたのでメモ。

まず、このブログは Sinatra+MongoDBをnginx+thin で動かしているのだけど、非力なVPSサーバなので、Sinatra+MongoDB+thinをなるべく使わないように できるだけnginxにcacheをさせている 。そのため更新時にはcacheを消さないといけない(トップページとか)。今はデータ更新時に、すべてのキャッシュを消している。ただ、どう考えてもださいので更新したコンテンツだけpurgeできる方法がないか調べてみた(サーバに余裕あれば、毎回backend(Sinatra)に問い合わせてもいいんだけどもね)。

nginxはデフォルトでは部分的なpurgeはできないので、 ngx_cache_purge module を使ってみた。FreeBSDのports (www/nginx-devel をこのサイトでは使っている)ではオプションで選択できる。Gentooだと USE=“nginx_modules_http_cache_purge” でいけそう(未確認)。

基本的には、 そのサイトのトップページに乗っている設定 を自分のURLの構成にあわせて変更してnginx.confとかに追加すれば動く。

ポイントは、

proxy_cache_key $uri$is_args$args;

の一つ目の引数と、

proxy_cache_purge tmpcache $1$is_args$args;proxy_cache_key

の二つ目の引数に同じ値が来るようにすること。一文字でも違ったら動かない(最後の/があるとかないとかではまる)。

実際のpurge(キャッシュのクリア)はhttpで行う。GETでいいみたい(POST/DELETEでもいい)。

たとえば、

curl http://example.com/purge/{key}

みたいにコマンドラインからも呼べるし、httpなんで呼ぶのは色々なスクリプトや言語からでも簡単。

で、何が現実的に使いづらいかというと、 key の部分は通常URL(query stringとかも込み)になるのだけど、たとえば、

http://example.com/hoge?page=2
http://example.com/hoge/
http://example.com/hoge?tag=gentoo

みたいなのが、それぞれ別々のキーでキャッシュされることになる(それ自体はそうなるべきであるケースもあるし別にいい)。しかし、ここで今/hogeに関連するコンテンツを更新したとして、/hogeに関するキャッシュをすべて消したいとしよう。でも、それを簡単にやる方法がない。ワイルドカードや正規表現が使えないので、いちいち全部自分で消さないといけない。引数まで考えると場合によっては非現実的。

同じように、 http://example.com/javascript/*.js みたいな条件でpurgeをしたい場合もあると思うけど、それもできない。

というわけで、いまいち使えないなーという結論なのでした。

おまけ: 会社では、リバースプロキシ+キャッシュとして、varnishをメインのサイトで、nginxを社内のちょっとしたサーバ用途(redmineとか)で使っている。両方触ってみて思うのは、nginxはすごく楽だけどもう一歩深い設定をしだすとできなかったりややこしいことが多い。今回の件もvarnishだと、正規表現でpurge対象を決められたりできる。 ま、適材適所ってことで。