LXCコンテナを作ったとき、毎回自分の設定をコピーするのは面倒です。 dotfilesを変更する度にLXCコンテナ側に設定を反映するのは特に面倒です。
Ubuntuコンテナを作るときは--bindhome
オプションを付けることで自動的にユーザを追加することができます。
しかし、他のディストリビューション向けのテンプレートにはそのような機能はありません。
そこで、手動でホスト環境にいる自分ユーザをコンテナ側に追加してホームディレクトリを共有する手順を紹介します*1。
ここではFedora18のコンテナを使って説明します*2。
まず、コンテナを作成します。
$ sudo lxc-create -t fedora -n f18 -- --release 18 --arch x86_64
次にコンテナに追加したいユーザのuid/gidを調べます。
$ id -u $ id -g
この2つの値を覚えておきます。ここではuid=1000,gid=1000
とします。
また、ユーザ名とグループ名はfedora
とします。
コンテナにグループを追加してから、ユーザを追加します。
$ sudo chroot /var/lib/lxc/f18/rootfs groupadd --gid=1000 fedora $ sudo chroot /var/lib/lxc/f18/rootfs useradd --uid=1000 --gid=fedora --create-home -s /bin/bash fedora
パスワードを設定します。ここではパスワードもfedora
にしてあります*3。
$ echo "fedora:fedora" | sudo chroot /var/lib/lxc/f18/rootfs chpasswd
ホームディレクトリを共有するための設定をコンテナに追加します。
$ sudo sh -c "echo '/home/fedora home/fedora none bind 0 0' >> /var/lib/lxc/f18/fstab"
追加したいユーザの分だけ、この手順を繰り返します。 これでコンテナを起動すると、追加したユーザが使えるようになっています。
LXCコンテナにホスト側のユーザをバインドする方法を紹介しました。
9月18日から20日の3日間RubyKaigi 2014が開催されます。
クリアコードは例年RubyKaigiのスポンサーをしています。去年のRubyKaigi 2013のスポンサーに引き続き、RubyKaigi 2014もスポンサーになりました。
また、須藤がスピーカーとして参加します。
例年、クリアコードにとってRubyKaigiは数少ない露出の機会となっています。RubyKaigiに参加したことで正社員への応募やインターンシップへの応募がきます*1。今回の機会もぜひ活かしたいところなので、クリアコードを知っていて応援したいという方は、会期中、まわりの人にクリアコードを紹介してください。ご協力よろしくお願いします。
*1 今年は、まだRubyKaigiが開催されていないのにも関わらず、すでにインターンシップへの応募がきています。
2014年7月にリファクタリングの新装版がオーム社から出版されました。旧版は2000年にピアソン・エデュケーションから出版されていましたが、今は絶版となっています。
新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)
オーム社
¥ 4,536
訳は洗練されたそう*1ですが、翻訳対象の内容は2000年のものと変わっていません。旧版のバージョンアップではなくリニューアルです。
本書を読むと、当時は「リファクタリング」は一般的ではなかったことがわかります。リファクタリングの方法の説明だけでなく、どうやって広めていこうか、といった話がちらほらと入っているからです。
10数年経った今、リファクタリングは「当たり前」になっています。最先端の開発者*2だけでなく、ちょっとした開発者であれば知っています。「あぁ、リファクタリングしたい」なんて普通に言っています。
「コードをキレイにすることでしょ?」ちょっとした開発者が知っていることはそんな感じかもしれません。旧版が絶版になっていることもあり、リファクタリングという本を読んだことがない開発者は増えているかもしれません。
リファクタリングという本が伝えようとしていることは「コードを安全に改善すること」です。単に、改善すること、キレイにすること、を伝えているわけではありません。「安全に」がポイントです。
本書の大部分を占めるのはリファクタリング(改善方法)のカタログです。カタログは次のものを含んでいます。
本書を読むと「手順」がとてもしっかりしていることに気づきます。この通りやっていけばたしかに「安全に」既存の機能を壊すことなく改善できるな、とわかります。単に改善することが大事ならば、もっと簡単に説明したり、ポイントだけを指摘することもできたはずです。そうしていないのは「安全に」を大事にしているからでしょう。
あなたのリファクタリングは単にコードをキレイにするだけですか?それとも、コードを安全に改善していますか?もし、「リファクタリング?コードをキレイにすることでしょ?」くらいに思っているなら本書を読んでみるべきです。「なぜリファクタリングをするのか」、そのために「どうやってリファクタリングをするのか」を整理する機会になるはずです。自分自身のコードに対する考えのリファクタリングですね。「リファクタリングをするとコードが改善される」というあなたの挙動は変わらないでしょうが、考えはずっと明確になるはずです。
本書の中でも自動化されたテストについて触れています。テストがあった上でリファクタリングができるといいます*3。その後、10年ほど経ってリーダブルコードが出版されました。
リーダブルコードの観点で見るとリファクタリングの例にでてくるコードは微妙に見えることもあるでしょう。リーダブルコードではtmp
やresult
などの一般的な名前よりも、もっと具体的な名前を使おうといいます。一方、リファクタリングではresult
を積極的に使っています*4。
今はリファクタリングよりもリーダブルコードが広く読まれています。リーダブルコードを読んで、実践して、身につけた最近の人たちは、次のステップとしてテスト、その次のステップとしてリファクタリングに進んでみるとよいでしょう。
リーダブルコードにするために自己流で改善していたやり方が体系化され、整理されることでしょう。リーダブルコードが示しているのは改善する指針だけです。リファクタリングは具体的な改善手順まで示しています。そのまま鵜呑みにできるものもあればそうでないものもあるはず*5ですが、自分のやり方を体系化するヒントにはなるはずです。
クリアコードも、SEゼミでやったリーダブルコード勉強会の次のステップとして、テストやリファクタリングも伝えていくのはどうかと検討しています。なお、まだ正式アナウンスはでていませんが、10月30日にアジャイルアカデミーでリーダブルコードを題材にした有料セミナーを開催する予定です。リーダブルコードやリファクタリングなどを活用してメンテナンス性の高いコードを開発したい方は予定を空けておいてください。
RroongaはSQLite3のような手軽さで使えるRuby用の全文検索ライブラリーです。Webアプリケーションに全文検索機能をつけたいときにも便利です。Rubyのリファレンスマニュアルの検索サービスであるるりまサーチもRroongaを使っています。
そんなRroongaをPassengerで動かすときのチューニング方法を紹介します。チューニングすることにより少ないリソースでも高速に動作するようになります。例として、docs.ruby-lang.orgにデプロイされている、るりまサーチを使います。
docs.ruby-lang.orgの環境は次の通りです。
このマシン上で、Rubyのリファレンスマニュアル(HTML)とるりまサーチが動いています。
まず、チューニング前の状態を説明します。当時のシステムの統計情報をグラフ化したものを見てください。
CPU使用率がほぼ0%になっているときはるりまサーチが落ちている状態です。動いているときはCPU使用率50%から100%くらいの状態がほとんどで、そのうちの半分いかないくらいがiowaitです。ロードアベレージは1から5の間なので、常に数プロセス待っている状態です。
メモリー使用量は常にほぼ100%です。スワップも半分いかないくらい使っています。なお、メモリ使用量がガクンと減っているときはサービスが落ちているときです。
グラフからもわかる通り、この頃は慢性的なメモリー不足で数十分に1回OOM Killerが動いている状態でした*1。
この状態をチューニングした後の統計情報のグラフを見てみましょう。グラフの真ん中あたりがチューニングを始めた頃です。左半分を見るとチューニング前の状態、右半分を見るとチューニング後の状態がわかります。
CPU使用率は20%くらい下がっています。それもよいことですが、それよりも特筆すべきはiowaitがほとんどなくなっているところです。ロードアベレージは常に1より小さくなりました。処理待ちのプロセスはほとんどいないということです。
メモリー使用率は半分くらいになりました。もちろん、スワップも使わなくなっています。iowaitがほとんどなくなっているのはスワップを使わなくなったからです。メモリーに余裕ができたのでOOM Killerも動いていません。
だいぶよくなりましたね。
この改善のためにはPassengerの設定を2つ追加しただけです。それは次の設定です。
passenger_max_pool_size 2
passenger_max_requests 100
それぞれのパラメーターについて何をするものか、どういう効果があるものかを説明します。
passenger_max_pool_size
passenger_max_pool_size
はRackアプリケーションのプロセスを最大でいくつ起動するかを制御するパラメーターです。デフォルトは最大で6プロセスです。
1つのPassengerで1つのRackアプリケーションしか扱っていないケース(今回のケース)は、このパラメーターの値は多くてもCPU数と同じにするのが適切です。プロセス数がCPU数よりも多くても、CPU数以上同時に実行できないのでそれほど性能はあがりません。
一方、プロセスを起動すればするほど使用メモリー量は増えます。今回のケースのようにそれほどメモリーがない環境では、使用メモリー量が増えてスワップを使うようになるとiowaitが発生し一気にパフォーマンスが落ちます。
このようにプロセス数を増やす方が遅くなることがあります。チューニング前の状態はまさにこの状態でした。
そのため、このpassenger_max_pool_size
というパラメーターをCPU数と同じ2にするだけでチューニング後のグラフの状態になりました。メモリーが少ない環境では重要なパラメーターです。
特に、Rroongaを使ったアプリケーションはプロセス内でデータベースを開くため、メモリー使用量が大きめになります*2。そのため、このパラメーターは重要です。
passenger_max_requests
passenger_max_requests
は、指定した数だけリクエストを処理したらそのRackアプリケーションプロセスを終了し、新しいRackアプリケーションプロセスを起動するようにするパラメーターです。デフォルトは0で、この機能は無効になっています。
このパラメーターはリクエストを処理するごとにメモリー使用量が増えていくRackアプリケーションに有効なパラメーターです。passenger_max_pool_size
でベースのメモリー使用量を削減できます。passenger_max_requests
は継続して動作したときのメモリー使用量を削減できます。
チューニングを開始した時点のるりまサーチはリクエストを処理するごとにメモリー使用量が増えているようでした。そのため、passenger_max_requests 100
として100リクエスト処理するごとにプロセスを再起動するようにしました。
ただし、passenger_max_requests 100
は回避策であり、根本的な解決ではありません。根本的に解決した方が助かる人が増えます。そのため、根本的な解決にも取り組みました。
るりまサーチが使っているライブラリーは主に全文検索ライブラリーのRroongaです。そのため、るりまサーチのメモリー使用量がリクエストごとに増えているなら次のどれかのコンポーネントが問題です。
RubyとPassengerは多くの環境で使わているので見逃されているメモリーリークに遭遇する可能性は低いです。そのため、Rroongaとるりまサーチを調べました。
詳細は省略しますが、Rroongaの一部がRubyのGCと相性の悪い実装になっていました。長生きしているオブジェクトが一時オブジェクトを参照しているため、RubyのGCが回収できていませんでした。
やはり、詳細は省略しますが、Rroonga本体を修正し、RubyのGCが動いたときに一時オブジェクトが回収されるようにしました。この修正は次回リリースのRroonga 4.0.4に含まれる予定です。
docs.ruby-lang.orgのるりまサーチはmasterのRroongaを使うようにして、passenger_max_requests 100
という設定は無効にしています。この状態で1週間ほど動いていますが、メモリー使用量は170MBほどで安定しています。
% sudo -H ~rurema/.rbenv/versions/2.1.2/bin/passenger-status Version : 4.0.48 Date : 2014-08-26 17:30:35 +0900 Instance: 7756 ----------- General information ----------- Max pool size : 2 Processes : 2 Requests in top-level queue : 0 ----------- Application groups ----------- /var/rubydoc/rurema-search/current#default: App root: /var/rubydoc/rurema-search/current Requests in queue: 0 * PID: 26038 Sessions: 0 Processed: 691258 Uptime: 6d 14h 51m 7s CPU: 20% Memory : 167M Last used: 0s a * PID: 26045 Sessions: 0 Processed: 685916 Uptime: 6d 14h 51m 6s CPU: 19% Memory : 166M Last used: 0s a
Rroongaを使っていてメモリー使用量が徐々に増えていくというケースがある場合は、Rroonga 4.0.4がリリースされたらぜひ試してみてください。
PassengerでRroongaを使ったWebアプリケーションを動かすときのチューニングのコツを紹介しました。ポイントはpassenger_max_pool_size
です。まずは、CPU数と同じにして様子を見てみてください。メモリー使用量が大きくなるようならCPU数よりも少なくしましょう。
そろそろリリースされる予定のRroonga 4.0.4ではGCフレンドリーになっています。長時間動き続けるRroongaを使ったプロセスを持っている人は楽しみにしていてください。すぐにアップデートできない人はpassenger_max_pool_size
の使用も検討してみてください。
ただ、Rroongaに限りませんが、回避策を使うよりも、根本的な解決をする方が助かる人が増えることは事実です。ぜひ、根本的な解決にもチャレンジしてみてください。自分で直すことが難しい場合でも、問題を報告する、デバッグに協力するなどで根本的な解決につながる活動をできるかもしれません。
オープンソースのカラムストア機能付き全文検索エンジンに、Groongaがあります。Groongaを使うと全文検索機能付き高性能アプリケーションを開発することができます。
Groongaでは各種ディストリビューション*1向けにパッケージを提供しています。そのため、比較的簡単にインストールできるようになっています。 ただし、パッケージをインストールするのに、あらかじめ独自に提供しているリポジトリを登録しないといけないのがちょっと面倒です。できれば、それぞれのディストリビューションの公式リポジトリからインストールできると余計な作業が必要ないので便利ですね。
上記の理由から、現在GroongaのFedora向けのパッケージはFedora公式リポジトリでパッケージをリリースしています。今回はそのパッケージの共同メンテナの募集のお知らせです。
Groongaは3.0.3から、groonga-normalizer-mysqlは1.0.5から独自に用意したリポジトリ*2ではなく、Fedora公式のリポジトリからインストールできるようになっています。
ただし、Groongaのほうはメンテナが2人、groonga-normalizer-mysqlについては1人といった具合で、少人数でパッケージをメンテナンスしている状態です。 現在のところ、ただちにリリースに支障がでているわけではありません。しかし、継続的なメンテナンスをしていく上では複数人でメンテナンスしていく体制を整えるのが望ましいため、今回手伝ってくれる共同メンテナ(co-maintainer)を募集することにしました。
共同メンテナに必要な条件は次の通りです。
最初の条件は必須です。さすがにRPMについてまったく知らないというのでは難しいので、最低限RPMのビルドをしたことがあるくらいの知識は必要です。また二つ目の肉の日以降に作業時間がとれるというのも必須です。三つめのGitについては、定型的な更新の手順があるので、それをなぞりながら覚えるというので構いません。
実際にどんなことをすればいいのかというのが気になっていることでしょう。 具体的な手順については過去のククログにFedoraプロジェクトでパッケージを更新するにはという記事としてまとめました。ざっくりと紹介すると以下の通りです。
共同メンテナの仕事がわかったところで、そもそも共同メンテナになるにはどうすればいいのでしょうか。そのためには次のステップを踏む必要があります。 各ステップの具体的な内容については、以前ククログにまとめたFedoraプロジェクトで新規パッケージをリリースする方法という記事を参照してください。
まずすべきは、必要なアカウントの作成や基本的な設定です。以下を行ってください。
ここまでできたら、FASアカウントを教えてください。あなたのFASアカウントをパッケージのメンテナンスに必要な'packagers'グループに入れてもらう必要があるためです。 教えてもらったFASアカウントでproxy-sponsorshipのリクエストチケットをpackager-sponsorsに作成します。このチケットの作成はこちらで実施します。 これは、「メンターとして新規参入者の面倒をみるので、スポンサーになって協力してくれる人はいませんか?」というスポンサー(packagersに追加する権限を持っている)を募集するお約束になっています。 スポンサーがついて、'packagers'グループに入れてもらえるまでしばらく待ちましょう。
'packagers'入りしたかどうかは次のページで確認することができます。
https://admin.fedoraproject.org/pkgdb/packager/(FASアカウント名)/
スポンサーがついて'packagers'グループ入りしたら、次はコミット権限を取得します。FASアカウントにログインして次のページにアクセスしてください。
それぞれ'Request Commit Access'というボタンがあるのでクリックしてください。あとはリクエストが承認されるまで待ちましょう。 承認されると、パッケージのCommitter(s)欄にあなたのFASアカウントがリストアップされているはずです。
ここまでくると、あなたもパッケージの共同メンテナです。ちょうど肉の日(毎月29日)なのでGroonga 4.0.5がまもなくリリースされるはずです。すぐに応募があれば今回のリリースから、なければ次回以降のリリースから実際にアップデートをやってみましょう。
共同メンテナになってみよう、と思ったらまずはGroongaに関するメーリングリストであるgroonga-devに登録しておいてください。
それから参加の意思を以下のいずれかの方法で表明してください。
今回はFedoraプロジェクトでリリースしているGroongaパッケージを一緒にメンテナンスしませんかというお誘いでした。共同メンテナになることで、よりRPMのパッケージングに対する知識を深めることができます。ソースアーカイブしか提供されていなくて、残念に思ったソフトウェアがあるという経験をしたことはありませんか?パッケージングに対する知識を深めることで、そういったソフトウェアのお手伝いができるようになるかも知れません。