株式会社クリアコード > ククログ

ククログ


LXCコンテナにホスト側のユーザをバインドする方法

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コンテナにホスト側のユーザをバインドする方法を紹介しました。

*1 Ubuntuテンプレートでやっていることを手動でやります

*2 LXCのバージョンは1.0を想定しています

*3 /etc/shadowのエントリをコピーすればパスワードもホスト環境と同じものを使うことができます。

2014-08-06

RubyKaigi 2014にスピーカー・スポンサーとして参加予定

9月18日から20日の3日間RubyKaigi 2014が開催されます。

クリアコードは例年RubyKaigiのスポンサーをしています。去年のRubyKaigi 2013のスポンサーに引き続き、RubyKaigi 2014もスポンサーになりました。

また、須藤がスピーカーとして参加します。

例年、クリアコードにとってRubyKaigiは数少ない露出の機会となっています。RubyKaigiに参加したことで正社員への応募やインターンシップへの応募がきます*1。今回の機会もぜひ活かしたいところなので、クリアコードを知っていて応援したいという方は、会期中、まわりの人にクリアコードを紹介してください。ご協力よろしくお願いします。

*1 今年は、まだRubyKaigiが開催されていないのにも関わらず、すでにインターンシップへの応募がきています。

タグ: Ruby
2014-08-12

新装版リファクタリング

2014年7月にリファクタリングの新装版がオーム社から出版されました。旧版は2000年にピアソン・エデュケーションから出版されていましたが、今は絶版となっています。

新装版 リファクタリング―既存のコードを安全に改善する― (OBJECT TECHNOLOGY SERIES)
Martin Fowler/児玉 公信/友野 晶夫/平澤 章/梅澤 真史
オーム社
¥ 4,536

内容

訳は洗練されたそう*1ですが、翻訳対象の内容は2000年のものと変わっていません。旧版のバージョンアップではなくリニューアルです。

本書を読むと、当時は「リファクタリング」は一般的ではなかったことがわかります。リファクタリングの方法の説明だけでなく、どうやって広めていこうか、といった話がちらほらと入っているからです。

10数年経った今、リファクタリングは「当たり前」になっています。最先端の開発者*2だけでなく、ちょっとした開発者であれば知っています。「あぁ、リファクタリングしたい」なんて普通に言っています。

「コードをキレイにすることでしょ?」ちょっとした開発者が知っていることはそんな感じかもしれません。旧版が絶版になっていることもあり、リファクタリングという本を読んだことがない開発者は増えているかもしれません。

リファクタリングという本が伝えようとしていることは「コードを安全に改善すること」です。単に、改善すること、キレイにすること、を伝えているわけではありません。「安全に」がポイントです。

本書の大部分を占めるのはリファクタリング(改善方法)のカタログです。カタログは次のものを含んでいます。

  • 名前
  • 要約
  • 動機
  • 手順

本書を読むと「手順」がとてもしっかりしていることに気づきます。この通りやっていけばたしかに「安全に」既存の機能を壊すことなく改善できるな、とわかります。単に改善することが大事ならば、もっと簡単に説明したり、ポイントだけを指摘することもできたはずです。そうしていないのは「安全に」を大事にしているからでしょう。

あなたのリファクタリングは単にコードをキレイにするだけですか?それとも、コードを安全に改善していますか?もし、「リファクタリング?コードをキレイにすることでしょ?」くらいに思っているなら本書を読んでみるべきです。「なぜリファクタリングをするのか」、そのために「どうやってリファクタリングをするのか」を整理する機会になるはずです。自分自身のコードに対する考えのリファクタリングですね。「リファクタリングをするとコードが改善される」というあなたの挙動は変わらないでしょうが、考えはずっと明確になるはずです。

テストとリファクタリングとリーダブルコード

本書の中でも自動化されたテストについて触れています。テストがあった上でリファクタリングができるといいます*3。その後、10年ほど経ってリーダブルコードが出版されました。

リーダブルコードの観点で見るとリファクタリングの例にでてくるコードは微妙に見えることもあるでしょう。リーダブルコードではtmpresultなどの一般的な名前よりも、もっと具体的な名前を使おうといいます。一方、リファクタリングではresultを積極的に使っています*4

今はリファクタリングよりもリーダブルコードが広く読まれています。リーダブルコードを読んで、実践して、身につけた最近の人たちは、次のステップとしてテスト、その次のステップとしてリファクタリングに進んでみるとよいでしょう。

リーダブルコードにするために自己流で改善していたやり方が体系化され、整理されることでしょう。リーダブルコードが示しているのは改善する指針だけです。リファクタリングは具体的な改善手順まで示しています。そのまま鵜呑みにできるものもあればそうでないものもあるはず*5ですが、自分のやり方を体系化するヒントにはなるはずです。

クリアコードも、SEゼミでやったリーダブルコード勉強会の次のステップとして、テストやリファクタリングも伝えていくのはどうかと検討しています。なお、まだ正式アナウンスはでていませんが、10月30日にアジャイルアカデミーでリーダブルコードを題材にした有料セミナーを開催する予定です。リーダブルコードやリファクタリングなどを活用してメンテナンス性の高いコードを開発したい方は予定を空けておいてください。

*1 旧版と比べていないので違いはわかっていません。

*2 最先端の開発者ってなんだろう?

*3 「堅実なテストは、リファクタリングをする上で欠かせない事前条件です。」第4章「テストの構築」の最初の文。

*4 resultはMartin Fowlerのいつものコードの書き方のようです。ちなみに、Rubyに標準添付のXMLパーサーREXMLはrvを好んで使っています。REXMLのソースをよく読んでいた頃は、真似してrvを使っていたことを思い出しました。

*5 リファクタリングはJavaを使っているため、コンパイラーを活用しています。言語によってはこのやり方は使えません。

2014-08-18

PassengerでRroongaを使ったWebアプリケーションを動かすときにチューニングのコツ

RroongaはSQLite3のような手軽さで使えるRuby用の全文検索ライブラリーです。Webアプリケーションに全文検索機能をつけたいときにも便利です。Rubyのリファレンスマニュアルの検索サービスであるるりまサーチもRroongaを使っています。

そんなRroongaをPassengerで動かすときのチューニング方法を紹介します。チューニングすることにより少ないリソースでも高速に動作するようになります。例として、docs.ruby-lang.orgにデプロイされている、るりまサーチを使います。

環境

docs.ruby-lang.orgの環境は次の通りです。

  • OS: CentOS 6
  • (/proc/cpuinfoで見える)CPU: Intel(R) Xeon(R) CPU L5630 @ 2.13GHz
  • (/proc/cpuinfoで見える)CPU数: 2つ
  • メモリー: 1GB
  • スワップ: 1GB
  • Ruby: 2.1.2
  • Passenger(nginxバージョン): 4.0.48

このマシン上で、Rubyのリファレンスマニュアル(HTML)とるりまサーチが動いています。

チューニング前の状態

まず、チューニング前の状態を説明します。当時のシステムの統計情報をグラフ化したものを見てください。

チューニング前のCPU使用率

チューニング前のロードアベレージ

CPU使用率がほぼ0%になっているときはるりまサーチが落ちている状態です。動いているときはCPU使用率50%から100%くらいの状態がほとんどで、そのうちの半分いかないくらいがiowaitです。ロードアベレージは1から5の間なので、常に数プロセス待っている状態です。

チューニング前のメモリー使用量

メモリー使用量は常にほぼ100%です。スワップも半分いかないくらい使っています。なお、メモリ使用量がガクンと減っているときはサービスが落ちているときです。

グラフからもわかる通り、この頃は慢性的なメモリー不足で数十分に1回OOM Killerが動いている状態でした*1

チューニング後の状態

この状態をチューニングした後の統計情報のグラフを見てみましょう。グラフの真ん中あたりがチューニングを始めた頃です。左半分を見るとチューニング前の状態、右半分を見るとチューニング後の状態がわかります。

チューニング後のCPU使用率

チューニング後のロードアベレージ

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のメモリー使用量削減

るりまサーチが使っているライブラリーは主に全文検索ライブラリーのRroongaです。そのため、るりまサーチのメモリー使用量がリクエストごとに増えているなら次のどれかのコンポーネントが問題です。

  • Ruby
  • Passenger
  • 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に限りませんが、回避策を使うよりも、根本的な解決をする方が助かる人が増えることは事実です。ぜひ、根本的な解決にもチャレンジしてみてください。自分で直すことが難しい場合でも、問題を報告する、デバッグに協力するなどで根本的な解決につながる活動をできるかもしれません。

*1 /var/log/messages調べ。

*2 データベースファイルはmmapでマップしてアクセスしているので複数プロセスでデータベース用のメモリー領域を共有します。そのため、データベースのサイズ分のメモリーは複数プロセスで共有します。

タグ: Ruby | Groonga
2014-08-26

FedoraプロジェクトのGroongaパッケージを一緒にメンテナンスしてみませんか?

はじめに

オープンソースのカラムストア機能付き全文検索エンジンに、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のspecに手を入れてパッケージをビルドしたことがある人(必須)
  • 毎月肉の日(29日)以降に新規リリースに追従するための作業時間がとれる人(必須)
  • Gitを使ったことがある人

最初の条件は必須です。さすがにRPMについてまったく知らないというのでは難しいので、最低限RPMのビルドをしたことがあるくらいの知識は必要です。また二つ目の肉の日以降に作業時間がとれるというのも必須です。三つめのGitについては、定型的な更新の手順があるので、それをなぞりながら覚えるというので構いません。

共同メンテナのお仕事について

実際にどんなことをすればいいのかというのが気になっていることでしょう。 具体的な手順については過去のククログにFedoraプロジェクトでパッケージを更新するにはという記事としてまとめました。ざっくりと紹介すると以下の通りです。

  • 新規リリースを取り込む(ソースアーカイブをアップロード)
  • SRPMを作成する
  • ビルドチェックする
  • 修正内容(spec等)をコミットする
  • パッケージをビルドする(f20,f19を対象にする)
  • パッケージをアップデートする(testingリポジトリに入れる)
  • パッケージをリリースする(testingリポジトリからstableに入れる)

共同メンテナになるには

共同メンテナの仕事がわかったところで、そもそも共同メンテナになるにはどうすればいいのでしょうか。そのためには次のステップを踏む必要があります。 各ステップの具体的な内容については、以前ククログにまとめたFedoraプロジェクトで新規パッケージをリリースする方法という記事を参照してください。

まずすべきは、必要なアカウントの作成や基本的な設定です。以下を行ってください。

  • Bugzillaにアカウントを作成する
  • FAS(Fedora Account System)にアカウントを作成する
  • CLA(Contributors License Agreement)へ同意する
  • リポジトリへアクセスする公開鍵をFASアカウントに登録する

ここまでできたら、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に登録しておいてください。

それから参加の意思を以下のいずれかの方法で表明してください。

  • @groonga宛に参加したい旨のツイートをする
  • groonga-devの共同メンテナ募集の投稿に参加したい旨の返信をする(あとで募集の投稿をします)

まとめ

今回はFedoraプロジェクトでリリースしているGroongaパッケージを一緒にメンテナンスしませんかというお誘いでした。共同メンテナになることで、よりRPMのパッケージングに対する知識を深めることができます。ソースアーカイブしか提供されていなくて、残念に思ったソフトウェアがあるという経験をしたことはありませんか?パッケージングに対する知識を深めることで、そういったソフトウェアのお手伝いができるようになるかも知れません。

*1 主要なディストリビューションであるDebian/Ubuntu/CentOS/Fedoraを対象としています。

*2 それまではFedoraのパッケージをpackages.groonga.orgでリリースしていた。

2014-08-29

«前月 最新記事 翌月»
タグ:
年・日ごとに見る
2008|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|02|03|04|05|06|07|08|09|10|11|12|
2020|01|02|03|04|05|06|07|08|09|10|11|12|