GRUBの設定でカーネルが認識するメモリ容量を制限する

もう年末です。今年のISUCONではpixivさんの社内ISUCONで練習させていただきました。

inside.pixiv.net

その時に気になったことがありまして。インスタンスタイプがc4.largeなのにメモリが1Gしかなくて、なんでかなーと。

$ free -m
             total       used       free     shared    buffers     cached
Mem:           998        236        762         12         11        105
-/+ buffers/cache:        119        879
Swap:            0          0          0

$ cat /proc/meminfo 
MemTotal:        1022972 kB

c4.largeのメモリは3.75GBのはずですが、1Gしか認識されていません。

どこかで制限しているのだろうけど・・・OSが認識していない、OSが起動する前に制限してる?ブートローダー?と思ったらそうでした。

/boot/grub/grub.cfg を確認すると、 mem=1G という記述があります!

linux   /boot/vmlinuz-3.16.0-4-amd64 root=UUID=e0f20fc2-3ca6-416b-8907-4050fe6120ab ro mem=1G init=/bin/systemd console=hvc0 console=ttyS0

この設定を変えてみます。 /boot/grub/grub.cfg を直接変更するのではなく、 /etc/default/grub を編集します。

参考 GRUB を設定する 〜 GRUB 2 編 - いますぐ実践! Linuxシステム管理 / Vol.202

/etc/default/grub を確認してみると

$ cat /etc/default/grub | grep GRUB_CMDLINE_LINUX
GRUB_CMDLINE_LINUX_DEFAULT="init=/bin/systemd console=hvc0 console=ttyS0"
GRUB_CMDLINE_LINUX="mem=1G"

ありますねー、 mem=1G という記述が。 GRUB_CMDLINE_LINUX にはカーネルの起動パラメータを記述できます。ここに起動パラメータを記述してOSが認識するメモリ容量を制限していました。

GRUB_CMDLINE_LINUX から mem=1G の記述を消して、以下のコマンド実行します。

$ sudo update-grub
Generating grub configuration file ...
Found linux image: /boot/vmlinuz-3.16.0-4-amd64
Found initrd image: /boot/initrd.img-3.16.0-4-amd64
done

再度 /boot/grub/grub.cfg を確認してみると mem=1G がなくなっています。

linux   /boot/vmlinuz-3.16.0-4-amd64 root=UUID=e0f20fc2-3ca6-416b-8907-4050fe6120ab ro  init=/bin/systemd console=hvc0 console=ttyS0

インスタンスを再起動して、確認してみると

$ free -m
             total       used       free     shared    buffers     cached
Mem:          3774        245       3529         16         11        109
-/+ buffers/cache:        124       3650
Swap:            0          0          0

$ cat /proc/meminfo 
MemTotal:        3865596 kB

使用できるメモリが増えました!

JJUG CCC Fall 2016 で Spring のソースコードを読んだことについて話してきた #jjug_ccc

SpringはどうやってDIしているのか?というタイトルで話してきました。

資料はこちらです。

資料を書いている時にいろいろ迷ったのですが、Springのソースコードを淡々と話すスタイルにしました。過去にはSeasarGoogle Guiceを使うことが多くて、Spring暦は1年ちょっとくらいです。Springを使い始めた時、 @ComponentScan 書いて @Component 書いて @Autowired 書いておけばDIされて便利だなぁと思って何となくソースコードを読んだら、想像以上に読むのが大変でした。Springが裏で泥臭いことをやってくれていたり色々な機能を提供してくれていたので、後々参考になるようにまとめました。

Springを使っている前提で話しを進めました。が、使ったことのない人も聞いて頂いていたようで、Springを使ってる人向けであることを発表の説明文でもっと強調しておくべきだったなぁと反省しております。。

Springにどういう機能があるとか、どうやって使うとかはこの本と公式ドキュメントを読むのが良いと思います。

個人的には、ブログをよく参考にさせて頂いている方達にお礼ができてよかったなぁ。

スタッフのみなさん、楽しいイベントをありがとうございました!

ISUCON6予選で負けた #isucon

ISUCON6 に yokohamanorth というチームで出場して負けました。。

2人(@hanhan1978, @trtaki)がアプリケーションの改修、おれがミドルウェアSQL のチューニング、サーバリソースのモニタリングを担当してました。

最終スコアは、83482。予選突破ライン90214に届かず。1位は251425、全く及ばず。。

くやしい。。気持ちを切り替えるためにも忘れないためにも、やったことを覚えてる範囲でメモっておきます。

  • 10:00にスタート。インスタンス作成後、 Nginx と MySQL のログの設定を変更し、ベンチ流す
  • テーブルやレコード数をチェック、kataribept-query-digest 、 sysstat などをインストール、ログを解析、改修プランを検討する
  • @hanhan1978 はアプリケーションの解析、@trtaki は提出用と別途作業用の VMPHP 環境のセットアップと切り替え
  • みんなで情報共有。ちょっとした作業ミスなどで12:00くらいになってしまった
  • SQL のチューニングはインデックスで大きな効果を得ることはなさそうだった。 @hanhan1978 と話して、 htmlify の中の keyword 一覧を取得する SELECT 文を redis を使ってなくすことに
  • @trtaki は htmlify 以外のアプリケーション改修
  • @hanhan1978 に htmlify 内の SELECT 文を託し、自分は他の遅い SQL に対してインデックスを貼る
  • PHP に切り替えたら CSS が当たらなかったので、 Nginx に mime.type の include を追加
  • @hanhan1978 が htmlify の SELECT 文を修正して必要なカラムだけを取得するようにする
  • Nginxのエラーログを warn レベルに変更する。エラーログを見るとリクエストメッセージが大きくリクエストバッファを一時ファイルに作成してることが分かったので、 client_body_temp_path を設定して一時ファイルの作成先を tmpfs 上のディレクトリに変更
  • Nginx で80番で受けてから5000,5001番にリクエストするのを止める、静的ファイルのキャッシュ、などなど
  • 5000番と5001番いらないかなぁと思って止めたら、 isuda と isutar が相互に呼び出しあってたり、ベンチマーカーからリクエストも来てるっぽかったのでとりあえず残したり
  • @trtaki が HTTP 呼び出しをやめて直接 DB からデータを取得するようにしたり
  • この辺で13:30くらいでスコア20000くらい
  • htmlify正規表現の部分をどうにかできないか考える。事前に entry の本文に含まれる keyword のセットを用意しておく、くらいしか思いつかず
  • @hanhan1978 が htmlify の SELECT をなくす
  • PHPボトルネックになっていたので、サーバリソースを php-fpm に集中させプロセス数を増やしたり
  • 確か16時前くらいで40000万ちょい
  • isupam の呼び出しが重くなってくる
  • @hanhan1978 が正規表現で処理してる部分の対応に取り掛かる
  • おれは isupam 対応に
  • とりあえず spam 判定された文字列をログに出力
  • isupam のバイナリを逆コンパイルしてどうにかできないもんかなぁと試みたけど逆コンパイルよくわからず
  • インスタンス生成時に ansible が動いていたので、 playbook に何かヒントがないか!?と思って確認したもののヒントはなし
  • 5050ポートで動いてる isupam に何気なくブラウザでアクセスしてみると、何とフォーム画面が!!!テキストエリアに文字列を入力してボタンを押すとその文字列が有効かどうかを判定してくれた
  • もう時間もなく頭がろくに働いていなかったせいか、このフォームでスパム判定をくらう文字列を探すことに
  • エラーログから文字列をテキストエリアにコピペしてチェック。手動二分探索的に NG 文字列を見つける。 NG 文字列を含むリクエストはログから削る。これを Vim のマクロを使いながらやってた
  • 結局10個くらいしか見つけられなかった。せめて本文は無視してキーワードの方だけを使ってやればよかった
  • そんなことをやってるうちに @hanhan1978 の正規表現の対応が終わる。ここで、 70000くらい
  • 残り1時間を切ったところで、提出用とは別の @hanhan1978 が作業していた VM で再起動テストしたところ、アプリケーションが動かないことが発覚! php-fpm が怪しいということで PHPer な @hanhan1978 と @trtaki に託す
  • その間に NG 文字列の場合は、isupam にリクエストを投げないようにする対応を仕込む、80000を越える
  • 17:45くらい、ようやく再起動でもアプリケーションが動くようになる!
  • 急いで提出用 VM にも対応を入れてもらい再起動して、最後のベンチ!17:55にスコア 83482 で pass!
  • 疲れてまったり、というより放心モードへ。。

本戦行きたかったなぁーーーーーーー、くやしい!!

でも、すんごく楽しかったです。運営のみなさま本当にありがとうございました!

来年こそは予選突破できるように反省して精進しよう。