2013年12月26日木曜日

コミケ85にLinux本を出します(3日目西せ18a)

コミケ85に「低級はっかーズ」として出展します。3日目(火曜日)西せ18aです。

今回の新刊は "Linux Kernel Updates 2013.12" です。価格は300円です。内容は

  • What's New in Linux 3.11?
  • What's New in Linux 3.12?
  • TCP/IPチューニング特集
です。下にプレビューを掲載します!

TCP/IPチューニング特集は主にsysctlのパラメータを解説しています。自称日本語で一番詳しい解説になっています!

表紙は毎度おなじみきのとなおとさんに描いていただきました。

前回までの既刊2冊も持っていきます。こちらも一冊300円です。よろしくお願いします!

2013年12月16日月曜日

MySQLにMHA を導入してハマったところ

この記事はMySQL Casual Advent Calendar 2013の16日目の記事です。

MySQLのマスタ冗長化のいち手段としてMHAというものがあります。マスタが落ちた時に自動的にスレーブに切り替えてくれます。詳しいアーキテクチャは公式ページやそこから辿れるスライドに詳しいのでそちらを参照していただくとして、ここではカジュアルに導入の時に詰まった店を挙げます。

幾つかはバグらしきものも含まれているので、後ほど公式にレポートしようと思います。

MySQLのパスワードに記号が入っているとうまくいかない

MySQLのパスワードに一部の記号が入っていると認証が通りませんでした。コードを見るとエスケープして戻して、MySQL向けのエスケープしたりシェル向けのエスケープをしたりと入り組んでいたので、どこかで対応が崩れているのかと思いましたが他にもこの種の問題はありそうなのでとりあえず記号を使わないパスワードに変更して乗り切りました。

shebangがenv perlになっている

MHAのスクリプトはすべてshebangが "#!/usr/bin/env perl" になっています。make installしても変わりません。ところで、#!/usr/bin/envはイマイチという噂もありますが、これperlbrewと相性が極端に悪くって、システムperlのパッケージを入れてもperlbrewのほうが実行されてライブラリが見つからなかったり逆にperlbrewに入れたのにシステムperlのほうが実行されたりして危ないのです。今回はすべてperlbrewの方に統一することにしました。

たぶんmake installする際に書き換えるのが正解だと思います。

relay_log_info=TABLEだとうまく動かない

MySQL 5.6の新機能でmaster-infoやrelay-log-infoがテーブルに入れれるようになりましたが、これがMHAではうまく動きませんでした。コードを見ると一見サポートしてそうに見えるのですが、マスタはrelay-log-infoが無いのにrelay-log-infoをSELECTして、見つからないのでエラーで止まります。ファイルの場合はちゃんと動くのですけどね。というわけで今回はファイルで使うことにしました。

パスワードを平文で書かないといけない

これはMySQLに常に付きまとう問題ですしもはや仕様なのですが、例えばpurge_relay_logsを動かそうとするとオプション引数にパスワードを平分で書く必要があります。crontabをちゃんと一定のユーザーに設定すれば見られる危険は少ないですが、気持ち悪いですね。

SSHのオプションがおかしい

failoverするときに使うサンプルスクリプトが付属していますが、これから参照されているSSHのオプション定数がちょっとおかしいです。

our $SSH_OPT_CHECK =
"-o StrictHostKeyChecking=no -o PasswordAuthentication=no -o BatchMode=yes -o ConnectTimeout=VAR_CONNECT_TIMEOUT";

VAR_CONNECT_TIMEOUT って謎の定数らしきものが使われていて、sshがinvalid time valueと言って死にます。ちょっとハマりました。

新しいレプリカセットを作って切り替えするときには同時に入らない

MHAはthree tier以上のレプリケーションも限定的にサポートしているのですが、これは一番上のマスタを登録する必要があります。新しいマスタスレーブのペアを既存のマスタにぶら下げて切り替えるという時に、既存のマスタへ新しいマスタからレプリケーションが走っていると、MHAがその既存のマスタに飛んでいって「Master %s:%d from which slave %s replicates is not defined in the configuration file!」というエラーメッセージとともに死にます。ので、新しいセットにMHAを入れてから切り替えようということはできません。

切り替えてからMHAを起動すればいいだけなのですが、どうしようか少し悩みました。

何回もテストすると失敗する

MHAは最近failoverした時刻を .failover.complete というファイルで管理していて、最近failoverしたばっかりでもう一度failoverしようとすると、「Current time is too early to do failover again.」というエラーで止まります。毎回手動でファイルを削除する必要があって少し面倒でした。

おわりに

問題点ばかり列挙しましたが、MHAは実績のある限られたマスタ冗長化ツールです。一度導入してしまえば安眠できると思います。これからパッチやバグレポートを書きます...

明日はYuya Takeyamaさんです。

2013年12月6日金曜日

EC2でプロセッサパワーがほしい時に使うインスタンスはcc2.8xlarge

AWS EC2に新しいc3世代のインスタンスタイプが追加されたのですが、値段あたりの処理性能がいまいちわからなかったのでHeavy Reserved Instanceを1年使う計算で比べてみました。比較対象は c1.xlarge, c3.xlarge, c3.2xlarge, c3.4xlarge, c3.8xlarge, cc2.8xlargeです。3年でもあんまり変わらないと思います。リージョンはバージニアです。

というわけで値段あたりのCPUパワーが一番いいのはcc2.8xlargeでした。c3世代はSSD搭載なので、SSDほしい時は選択肢が変わってくると思いますが、単純にCPUだけほしい、という時はcc2.8xlargeが良さそうです。c3世代より2割ぐらい安い計算になりました。

備忘録的な記事で雑なまとめですがこのへんで。

2013年11月29日金曜日

allocatorを変えてMySQLをベンチしてみた

MySQL Performance Blogにtcmalloc/jemallocを使うとパフォーマンスが良くなるという記事があるので、気になって手元の環境でも計測してみました。

環境

CPUIntel Xeon CPU E5-2620 x 2
OSCentOS 6.4 64bit
MySQLMySQL 5.6.14
sysbenchSysbench 0.4.12
jemallocjemalloc 3.4.1
tcmallocgperftools 2.1

MySQLのmax_connectionsは2048に設定しました。innodb_file_formatはBarracudaで、Buffer poolは56GBを確保し、buffer pool instanceは32に設定しました。

測定内容

sysbench の OLTP テストを下記のようなコマンドで走らせました。

for t in 16 32 64 128 256 512 1024; do sysbench --test=oltp --oltp-table-size=1000000 --mysql-user=benchuser --mysql-password=benchuser --db-driver=mysql --num-threads=$t --max-requests=200000 --oltp-read-only run; done
for t in 16 32 64 128 256 512 1024; do sysbench --test=oltp --oltp-table-size=1000000 --mysql-user=benchuser --mysql-password=benchuser --db-driver=mysql --num-threads=$t --max-requests=200000 run; done

jemalloc の nodirty というのは "MALLOC_CONF=lg_dirty_mult:-1" という環境変数をセットしたものです。これは3.2以降性能がベンチマークによっては劣化することがあるというので気になって測りました。

tcmalloc + large page は、my.cnf に large-page を付けてMySQLを起動したものです。read/writeは取り忘れたのでreadのみです。

なお試行回数は1回で、ベンチマークを2回走らせた2回目の値です(平均とか取ってません)。測定のたびにmysqlを再起動し、cleanup/prepareを実施しました。

allocatorの差し替えは/etc/init.d/mysqlにexport LD_PRELOAD=...を記述する方法を取りました。ロードされていることは/proc/{pid}/mapsを見て確認しました。

測定結果

read/writeに関しては、測定のばらつきが大きく、実行するたびに2割程度は差が出る結果になりましたのであまり信頼の高い結果ではありません。jemallocはスレッド数が1024の場合にのみ、glibc mallocより22%程度高速という結果になりました。tcmallocは16-32スレッドの場合は最大2割遅く、64スレッド以上では1割程度高速でした。

readは比較的安定した結果が出ました。jemallocはglibc mallocと比較し5%程度遅くなりました。tcmallocはglibc mallocと同等または高速で、最大3%程度の差が出ました。

tcmallocでlarge-pageを有効にしても有意な差は見られませんでした。これは今回のデータサイズが小さく、TLBサイズが変わってもヒット率が変わらなかった可能性があります。

考察、まとめ

MySQL Performance blogに掲載されていたような、256スレッド以上ではglibcが遅くなるという現象は見られませんでした。また、jemallocがtcmalloc/glibc mallocとくらべて低速であるという結果になりました。これは設定によるのか、ベンチマークの種類によるのかはわかりませんが、必ずしもjemallocやtcmallocに差し替えることによってMySQLの性能が向上するとは言えない結果になりました。ただしtcmallocはglibc mallocより遅いことはなかったので、差し替えることによってデメリットはメモリの消費量が増える以外は生じないので、メモリに余裕があるのであれば検討してもよいかと思いました。

元のblogでは64スレッドを超えると1万transactions/secを超えているのに対し、こちらではたかだか5000スレッドしか出てません。向こうは32スレッドあるのでこちらより性能が良いのですが、それでも少し性能が低い気がします。ですので、何か設定がまずいのか、それともallocatorが実は差し替わっていない可能性も残っています。

transactions/secだけではなく、CPU使用率やレイテンシにも着目するべきですが、それは今後の課題とします。

2013年11月28日木曜日

Fedora最新技術情報&Systemd勉強会に参加してきました

Linux女子部主催のFedora最新技術情報&Systemd勉強会に参加してきました。

Fedora最新技術情報

講師は藤田稜さん

Fedora最新技術情報といいつつRHEL7のお話でした。いくつか気になった点をピックアップします。

xfsがデフォルトになるかも

RHEL7ではxfsをデフォルトファイルシステムにしたいそうですが、まだ安定性やメモリ消費量に難があり、技術的な観点から決定はしていないそうです。

「RHEL 4, 5, 6 の初期出荷でファイルシステムの破損バグを仕込んだ実績があるので、今からxfsに切り替えたら絶対何か踏む」という声も。

iptablesからfirewalldへ

今までファイアウォールはiptablesを使っていましたが、標準でfirewalldを使うように変更します。従来のiptablesとは排他利用になります。戻すことはできますが、基本的にはfirewalld推奨とのこと。設定を読み込み直すときにreloadしてもセッションが切れなくなっているそうです。

またそれに伴いNetworkManagerが必須となるようで、今まで殺していた人はうまく付き合ってくださいとのことでした。

OpenLMI導入

OpenLMIという管理系機能の共通インタフェースがあるそうなんですが、それがRHEL 7.0GAには入るんじゃないかということ。従来例えばファイルシステムだけ取っても fdisk, gparted, lvm, mkfs など様々なコマンドがバラバラにあったものが、整理され統合されるんだとか。

その他

その他は、systemd入りますよ(後述)、Linux Containerのフルサポート、pNFSのクライアントサポート、実はSELinux enforcedでしかQAしてないので、permissive/disabledはテストしていませんというお話などが聞けました。

大きくはやはり管理系の仕組みがsystemd, OpenLMI, firewalld, NetworkManagerというものに置き換わるのが大きな変更点のようです。「カーネルランドは同じだけどユーザーランドは違うOSと言っても良いほどの変更」と言われていました。

Systemd徹底入門

講師は中井悦司さん

今回のお話のスライドはslideshareにアップロードされていて、時間の都合で省略されたところも含めて詳しく解説されています。ここで細かい話を書いても実際スライドのほうが詳しいので、私が疑問に思った点や補足を中心に記述します。

SysV Init から systemdへ

従来は SysV Init が /sbin/init に存在して最初にpid=1として起動していましたが、代わりに/usr/bin/systemdが起動します。今までは単なるシェルスクリプトが/etc/inittabに定義された順に実行されていたので、シリアルにしか実行できず性能も悪かったものが、systemdではそれぞれのタスクを細かくunitという単位に定義して依存関係と前後関係に基づいて並列的に実行し、起動速度を高速化します。

systemdを作ったのはレナートさんで、彼のblogにどうしてsystemdを作ったのかが載っているので、英語ですがぜひ読んでみてくださいとのこと。systemd の大きな目的は4つあって、

  • システム起動時間の短縮
  • システム構成の動的変更に対応
  • プロセス停止処理を標準機能として提供
  • デーモンの実行環境を制御

です。

依存関係と前後関係

SystemdではRequire/WantedByという依存関係と、Before/Afterという前後関係にもとづいてunitの実行順が決定されます。ここで依存関係というのは単に必要だということを記述するだけで、実際にはその中では平行にunitが実行されていきます。そのため、例えばhttpdが起動する前にDNSが起動しておいてほしい、というようなことはすべて前後関係として記述するようです。

アプリケーションサービスなどもsystemd管理下へ

init だとクラッシュした時の再起動がないので、よくアプリケーションサービスなどを supervisord や daemontools を使って別に起動させていた方も多いと思いますが、基本的には systemd がこれらも含めてすべて見るようにするのが理想的ということです。cgroupを使ってプロセスツリー全体のリソースも管理でき、ログ管理機能もあるのでsystemd管理下に置くほうがシステム全体として整合性も取れるような印象です。

また従来はdaemonizeすることが多かったところsystemdではdaemontoolsのようにforegroundで実行するのが基本的なスタイルになるようです。Typeを変えればforkするデーモンにも対応可能です。

便利そうなコマンド

systemctl status (unit名)すると、関連するプロセスの一覧やログの抜粋が表示される。

systemctl list-units すると、現在有効なunitの一覧が表示され、起動に失敗しているものもひと目でわかる。

systemctl list-dependencies (unit名) すると、依存関係がツリー状に表示される。

manページを読もう

作者のレナートさんがドキュメント魔らしく、manページが大変充実しているので、困っても困らなくてもmanページを読めば良いとのことでした。

感想

systemdという巨大な仕様のものを入れることにRed Hat社内でも議論があったそうですが、結局のところ SysV Init がイケてないし置き換えることは必要で、より良いデーモン管理のため導入することにしたそうです。話を聞くと使う分にはちゃんと動きそう、だけども何でもsystemdにやらせるのは「Unixぽくない」と感じます。

浸透のためにはDebianやGentooもsystemdに移る必要があると思うし、もし今後initが複数使われるのであればソフト作者はsystemd用、upstart用というふうにわけて起動スクリプトを用意しなければいけなくなるかもしれません。そういうのは望ましくないので、なんとか一本化してほしいなぁと思いました。

2013年10月26日土曜日

献本御礼: 独習Linux専科 サーバ構築/運用/管理

著者の中井悦司さんから「独習Linux専科」サーバ構築/運用/管理をいただきました。ありがとうございます。僭越ながら書評を書きました。

Linuxを始める人にぴったり

初心者のかたで、これからLinuxを初めて使おうという方には非常におすすめできる本です。インストールの仕方から基本的なコマンドライン操作、システムの概念が解説されています。そして最後にはSamba, PostgreSQL, Ruby on Railsのサーバーを構築する手順まで書かれています。特にWindowsから入ると馴染みのないパッケージ管理(yum/rpm)やシェルの文法などには多くの紙面が割かれています。

最近はインターネットを検索すると多くの入門記事を見つけることができますが、それでもOSの入門書籍は役に立つと思います。ネットで検索するとディストリビューションが微妙に違ったり、バージョンが微妙に違ったりで「自分の環境に適用出来るか?」を考えなければなりませんが、この本は非常に網羅的に書かれていますので順序立てて学習することができます。

さらに、Fedora 17という比較的最近の2012年5月にリリースされたOSに準拠していることも特徴です。実はネット上の記事の多くはこのバージョンに追いつけていません。Fedoraは最近になって、プロセス管理がinitからsystemdに変更になりましたが、その新しい方法を説明しているのは非常に限られています。もし仕事でLinuxを使うならば、Red Hat Enterprise Linux や CentOS などを使う可能性がありますが、次のバージョン 7 では同じくsystemdが採用されるので、その予習にもなります。

Red Hat系Linuxを学習する最初の一冊としておすすめです。

Linuxのことは知ってる、という方へ

少しLinuxを知っている人がこの本を読んだ場合は、知識の網羅性の確認になると思います。

前述のとおりsystemdの解説はネット上にもほとんどありません。Systemd入門(1) - Unitの概念を理解するというのが日本語で書かれた数少ない記事ですが、実はこの記事を書いた方がこの本の著者です。systemdの解説は7ページほどしかありませんので、あくまで他の記事と合わせて、になります。

他にもSELiunx, setuid/setgid/sticky ビット、find -mtime の -2, 2, +2 の違いなど中級者が「少し自信がないかも」というような内容もカバーされてます。意外とググりながら勉強していく方式だと、自分が直面した課題以外は見過ごされがちなので、そういう方にも使っていただけると思います。逆に今上げたキーワードはわかってるよ、というレベルの方には物足りないと思います。

また、50ページ程度がSamba, PostgreSQL, Railsのインストールと設定に割かれているので、OSのインストールは出来たけれどこのあたりをやったことがないよーという人にも役に立つと思います。

まとめ

  • Linux初学者のために最適
  • 学んだ内容は次のRHEL7にも生きる

2013年10月10日木曜日

MariaDB / MySQL コミュニティイベント in Tokyoに参加しました

10月9日に秋葉原で開催されたMariaDB / MySQL コミュニティイベント in Tokyoに参加してきました。最近話題の MariaDB、いったいどんな感じだろう?という情報収集に出かけました。

MySQL と MariaDB の歴史

  • MySQL は1995年生まれ。MySQL=会社=ソフト
  • 2007年、10億米ドルで Sun が買収
  • 2009年、MariaDB が fork
  • 2009年、Oracle が Sun を買収
  • 2010年、Oracleからコンサルと営業部隊が抜けてSkySQLを創業
  • 2013年、SkySQLとMariaDB Services(エンジニア部隊)が経営統合

SkySQL ABについて

SkySQLはMySQLとMariaDBのサポートを提供している会社。MariaDBの開発にもコミットしているが、MariaDBの運営自体は MariaDB Foundation によって行われている。これはまた買収されることを防ぐため。

ドメインは

  • mariadb.com: Enteprise サービス
  • mariadb.org: MariaDB コミュニティ、Foundation管理

となっている。

顧客満足度は高いと考えている。93%のサブスクリプション更新率を誇る。

MariaDB について

MariaDBの誕生から44ヶ月で、もうすぐ10.0がリリースされる予定。特徴は

  • MySQL との互換性を確保
  • バイナリを置き換えるだけで移行できること
  • 100% GPLv2

バージョン 10.0 は MySQL 5.5 ベース。これは Oracle MySQL 5.6 がリリースされた時に Oracle が過去のコミット履歴をリファクタリングして一部消してしまったため。機能は独自実装を含め、5.6 のスーパーセットを目指している。

私が個人的にいいなと思った機能は

  • Multi-source replication: 一つのスレーブに複数のマスタからレプリケーションする
  • Optimizer がかなり良くなってる(特にJOINやサブクエリ)
  • スレッドプール(Oracle版では有償)
  • SHOW EXPLAIN を使って実行中のクエリに対して EXPLAIN が発行できる
  • group commit によってfsyncを呼ぶ頻度が減った
  • FusionIO DirectFS をサポートし、atomic write できるようになってる
  • GTIDを有効にするときに、全部を一度に切り替えず、徐々にノードを入れ替えられる

あたりです。MySQL でも使えるのかは調べてないので、MySQLでもサポートしていたらご指摘ください...

クライアントライブラリはLGPL版が用意されている。ただしプロトコルは現在のところ互換性があるので、LGPLでなくても良いのであれば無理に移行する必要はないとのこと。

その他、MariaDB Galera Cluster や TokuDB のサポートという言葉が飛んでいて、このあたり知らないので今度調べてみようと思います。

サポートはリリース後5年間提供していて、これは各distributionがMariaDBに移行した理由の一つだと考えている。

MariaDB Manager について

MariaDB をモニタリング、設定、プロビジョンするためのツール群で、シェルスクリプトとPHP、Javaを組み合わせて実装されている。オープンソースで提供される。現在はまだ開発中。

GUIを使っても良いし、RESTful APIを使って既存のツールと組み合わせて利用することも可能。

興味深いと思ったのはスレーブの追加やバックアップもAPIからできるようになっていると言っていたところです。Xtra Backupと組み合わせて使ったりするのか、それとも似たような機能が独自で実装されるのか、そのあたり気になりました。

MaxScale について

MySQL Proxy のような、クライアントとサーバーの間に挟むプロキシを開発中。C言語で、Event-basedで開発しているので高い性能を出せる。従来のプロキシより高機能なものを目指している様子。

  • master-slave、マルチマスタ構成をサポート
  • Sharding のサポート(将来的にはMariaDBの改良とセットでSQLをフルサポート)
  • 各ノードにslaveとして接続し、binlogの進み具合を見て一貫性を保証する仕組み
  • PAM, LDAP, Keystone などの認証をサポート
  • 将来的にはMariaDBのパーザーを載せ、サーバーとの通信をバイナリプロトコルにすることも検討

開発はまだ初期段階で、10月22日にgithubで公開予定なので、フィードバックをくださいとのこと。

全体を通した感想

OracleがMySQLのプロプライエタリライセンスを持っている以上、すべてをGPLで提供するしかないのでどの程度ビジネスが上手くいってるのかなぁと気になって、「いいことばっかりのように思うけど、フリーランチは無いはずで、何を利用者に求めてるの?」と聞いてみました。そしたら「まずはOSSとして開発が進み、フィードバックやパッチがもらえること。もちろんサブスクリプションを買ってもらえるとうれしい」とのことでした。今日聞いただけの話ですが、開発自体はかなりオープンに進めているようで好印象でした。商用版を使っているかどうかで、Oracle MySQLとMariaDBを比較した時の印象は大きく変わるんじゃないかなぁと思います。

テストケースをつけてリリースしていることも強調していました。Oracle MySQL 5.6.14 にはテストケースがひとつも追加されずリリースされたことを引き合いに、オープンソースとしてはMariaDBのほうが参画しやすいのではないか、また、バグトラッカーも一本化していると言っていました。なるほど、普通のオープンソースの開発にかなり近いようです。また、Perconaとは密な協力関係でやっていると言っていました。

今のところRDBMSといえばMySQLという感じですが、PostgreSQLもかなり進化しているし、MariaDBも評価され始めているようなので、一度フラットにいろいろ調べてみるのが良いのかなぁ、と思いました。

「今MySQL 5.6を使ってるんですけど」という話をしたら「MariaDB 10.0が来春に出る予定なので、それまで評価を進めてもらって、その時に移行するかどうか検討するのが良いのではないか」とのことでした。

MaxScale や MariaDB Manager はまだ開発の初期段階で実用は難しそうですが、便利そうではあるのでこの先どういうふうに開発が進むのかなぁと興味を持ちました。

2013年10月7日月曜日

ISUCON3 に参加して予選敗退したので反省してみる

ISUCON3に会社の方と3人でチームを作って参加しました。結果は... 予選敗退! スコアは初期状態のGoで測ったものが最終スコアです...

当日の流れ

今年初参加で、全く予習をしていなかったので勘所もなにもつかめず、まずWebアプリケーションがいくつか転がっていることを認識。言語は議論の末皆がやったことのある Perl に決定。 Perl の会社に務めているのに私だけ Perl がろくに書けません。

作戦は、まずコードを読んでボトルネックになっていそうなところを修正しようとして、コード分析から始めました。具体的には以下の様な点があがりました。

  • markdown を毎回 fork して変換しているのは遅そう
  • ログインしていない状態のページはキャッシュできそう
  • pager は怪しいけど後回しかな
  • 静的ファイルも後ろに投げているのでリバースプロキシで処理しよう
  • SQLにインデックスがなかったり、MySQLがデフォルトで動いているのをなんとかする?

それで、作戦としては基本的にはコンテンツから静的ファイルを作成して nginx の rewrite でがんばろうという話になりました。

最初に想定したアーキテクチャ

初期段階で「このアーキテクチャで行こう」となったものは次のような感じです。

フロント nginx
静的ファイルをサービスする
Webアプリケーション
markdown への変換と動的コンテンツの提供
バックグラウンドWorker
Webアプリケーションから受け取ったデータで静的ファイル生成&DB更新
memcached
アプリケーションとworkerから参照するキャッシュ
RabbitMQ
更新があった時にworkerに仕事を投げるqueue

いま考えると少し大掛かりすぎるわりには全体をカバーできていないアーキテクチャでした。

つまづいたところ

私の担当はworkerだったので、Queueからfetchして静的ファイルを生成するところを作成しだしました。 RabbitMQ との接続には Net::RabbitFoot を使いました。まずはトップページだけ... と思ってやって、ボチボチ出来かけたところで...

  • uri_for で URI 生成しているけど裏workerだと使えない
  • ページにユーザー情報埋め込んでるけど取ってこれない
  • っていうかセッション情報入ってる... 静的にして大丈夫?(いまさら

のようなところで悩み、うまく行かなくなって「ごめん、やっぱり無理...」と断念しました。

その後はいろんなページをmemcachedでキャッシュする方向に進みましたが、なかなか思うように成果が出ず時間切れで終了しました。

こうしたらよかったかな

  • チームで得意言語が違うとそれなりに不利なので、得意言語は合わせるorちゃんと予習したほうがいい
  • 全部を一度に作りなおす方法だとハイリスクなので、少しずつチューニングするほうが失敗した時のダメージが少ない
  • もっと積極的にbenchmark回せばよかった。つねにgit pullしてbenchmarkだけ回し続けるようにしてもいいくらい
  • プロファイリングしたのが午後4時ぐらいで、遅すぎた。
  • いろんな罠が仕掛けられている可能性を考慮すべきだった。
  • ベンチツールがどんなクエリを投げているのか統計とるべきだった

罠というのは、たとえば memcached が 11212 で上がっている問題がありますが、これは自分でmemcachedの設定を書き換えていて、「あれー、反映されない!」となっているのに気付かず、 stats とった時の値がおかしいのに気づかず... というので、自分の設定ミスばかり疑っていました。また、「DOMを変更しないこと」とあったので、スタイルシートの指定にトップページがあるのは気づいていましたが、変更できない... と諦めていました。

memcached 作戦はそこそこ動いて、testでスコア5000ぐらいまで行ったのですが「testは通るけどこの場合にうまくいかない」みたいなケースを見つけてしまいやり直して泥沼にハマってしまいました。多少FAILしても積極的にbenchmarkをとる作戦のほうがよかったと思います。

でも最大の失敗は、コードを中途半端に読んでボトルネックを「推測」するだけに終わり、最初からプロファイリングしたりシステムメトリックスを取得してチューニングに挑まなかったことだと思います。こんなですが会社ではチューニングもやってます...

次回があるとしたら、すぐにgangliaを入れれるようにしておいて基本的な数値は常に見ながらやるようにしようかなぁ、と思いました。あとNYTProfのようなツールの使い方をもっと覚えないといけませんね。

あと一人一インスタンスだったのでChefで構築しようとして途中で諦めてさらに時間をロスしていました。

くやしい

くやしいです...

2013年10月4日金曜日

nginxのsetディレクティブはrewriteモジュールに属する罠

nginxでは変数をセットするときにsetディレクティブを使います。例えば

set $script "";
set $path_info $uri;

というようにです。ところで、このsetディレクティブはngx_http_rewrite_moduleに属します。 つまり、rewrite と組み合わせて

location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3 break;
    set $script "";
    set $path_info $uri;
    fastcgi_pass unix:/tmp/fastcgi.sock;
}

なんていうことをしていると、rewriteが発動してbreakされた瞬間にrewriteモジュールの評価が終わってしまい、setされません。

location /download/ {
    rewrite ^(/download/.*)/media/(.*)\..*$ $1/mp3/$2.mp3;
    set $script "";
    set $path_info $uri;
    break;
    fastcgi_pass unix:/tmp/fastcgi.sock;
}

というふうに、breakする場所をsetの後にする必要があります。

ハマりました。

2013年9月11日水曜日

iPhone 5s/5c LTE 各キャリア使える周波数まとめ

iPhone 5s/5c が発表されましたね!

まだ各キャリアでどの周波数をサポートするという話がないので、iPhone のスペック表から突き合わせてみました。また、ドコモはどのモデルを発売するか公式情報がありませんが、おそらくA1533(GSM)だと仮定して話を進めますドコモもA1453でした。 各キャリアの周波数割り当てはWikipediaのLTE記事他を参考にしました。

BandDocomoKDDISoftbank
1 (2100MHz)10MHz*220MHz*210MHz*2
3 (1800MHz)20MHz*2(東名阪)10MHz*2(emobile)
8 (900MHz)10MHz*2(2014年夏以降)
18 (800MHz)10MHz*2
19 (800MHz)10MHz*2

Docomo, KDDI が保有する 1.5GHz帯には対応しません。

以上からまとめてみますと...

ドコモは東名阪バンドの1800MHz帯が使用可能なので、特に周波数の逼迫する首都圏で高速通信が可能と推測。 800MHz帯はサービス開始間もないのでエリアはまだ狭そう。

KDDIは田中社長ご自慢の800MHz帯に対応したので、エリアの問題はおそらくクリアし、3キャリアで一番広くなりそう。ただし800MHz帯+1500MHz帯+2100MHz帯全体のエリアは公表しているけれど、800MHz帯+2100MHz帯のみのエリアは公表されていない。2100MHz帯の20MHzはまだ数局という感じなので、実質15MHzでのサービス。2100MHz帯での品質は皆様ご存知の通り。 VoLTE はまだ使えないので通話中のデータ通信はできないまま。

ソフトバンクは相変わらず厳しい。イーモバイルの1800MHz帯が今後も使えるとしても相変わらず逼迫したまま。特にプラチナバンドと呼ばれる900MHz帯でのサービスが来年夏以降なのが厳しい。2100MHz帯のみの比較ではKDDIよりも良いようですが、800MHz帯が加わった時にどうなるかは未知数。

現在KDDIでiPhone 5を使っているユーザーは、iPhone 5sに乗り換えると使える周波数が増えます。現在ソフトバンクでiPhone 5を使っているユーザーは、iPhone 5sに乗り換えても使える周波数は今のところ変わりません。

カタログスペックのみの比較なので、実際の通信速度や品質にはもちろんキャリアの基地局整備状況によります。ドコモは特にiPhone初めてなので、そこらへんも含めて注目です。

2013年9月8日日曜日

MySQL 5.6 の GTID のしくみ

MySQL 5.6 で GTID (Global Transaction ID)が導入されました。どうも使うと便利そうだ、というものの実際どんなものかイマイチ分からなかったので、調べてみました。

サーバーがUUIDを持つ

私は調べるまで誤解していたのですが、UUIDを持つのはサーバーであって、トランザクションではありません。それぞれのサーバーにUUIDが割り当てられ、トランザクションは連番が振られます。
例えば、4台のMySQLインスタンスで1台をマスターにした場合は以下のようににUUIDが振られます。
そして、トランザクションは次のようにIDが振られます。
UUID:トランザクション番号
例えば"40bbcf9b-e556-45b0-bdb3-e528f0041652"で実行された123番目のトランザクションは
40bbcf9b-e556-45b0-bdb3-e528f0041652:123
という感じになります。
そして、それぞれのサーバーで実行されたトランザクションは "GTID_Executed" に "uuid:最初-最後" というように記録されます。
この図の場合では、右端のスレーブのみ最後のトランザクションが実行されず、遅れていることがわかります。
ちなみに、途中のトランザクションだけ抜けた場合は、
40bbcf9b-e556-45b0-bdb3-e528f0041652:1-20:22-1021
という感じで、 : でつなげて記録されます。

マスターを切り替える

ではマスターが落ちた場合の動作を見てみましょう。
マスターが落ちました。右端のスレーブが遅れているので除外し、今回は左端のスレーブをマスターに昇格させます。
この場合、左側のスレーブは新マスターに追いついているので、新マスターの最新のログポジションに合わせれば良いことがわかります。右側のスレーブはひとつ遅れているので、新マスターの該当のログポジションに合わせます。これらが自動計算され CHANGE MASTER TO に MASTER_AUTO_POSITION=1 を指定するだけで良いのが GTID の売りです。

新マスターでのトランザクション

新マスターでトランザクションが実行された場合は、新マスターのUUID:1 から新しくトランザクションが数えられます。
GTID_Executed にはこれまで実行されたトランザクションがすべて記録されます。マスターが変更された場合は複数行記録されます。

新しくスレーブを追加

旧マスターに対するスナップショットから新しくスレーブを追加することもできます
右端に新しくスレーブを追加しました。旧マスターのトランザクションのみ実行され、新マスターのトランザクションが実行されていないことが GTID_Executed からわかりますので、新マスターに接続した時にポジションを新マスターの場所に自動的に設定します。

バイナリログの中身

GTIDを有効にした状態では、バイナリログに
SET @@SESSION.GTID_NEXT= 'a8679745-1864-11e3-a1ec-28924a2bea1c:14'
という行が現れます。これは、次に実行するトランザクションのIDを指定しています。
GTID_NEXT は通常であれば "AUTOMATIC" に設定されていて、その状態では "自分のuuid:次の番号" のIDを次のトランザクションに設定しますが、設定し直すと任意のIDのトランザクションを作成することができます。
# at 2621
#130908 21:05:04 server id 10  end_log_pos 2669 CRC32 0x20b2bc89        GTID [commit=yes]
SET @@SESSION.GTID_NEXT= 'a8679745-1864-11e3-a1ec-28924a2bea1c:14'/*!*/;
# at 2669
#130908 21:05:04 server id 10  end_log_pos 2737 CRC32 0x5e5fa3bb        Query   thread_id=10    exec_time=0     error_code=0
SET TIMESTAMP=1378641904/*!*/;
BEGIN
/*!*/;
# at 2737
#130908 21:05:04 server id 10  end_log_pos 2785 CRC32 0x757ca2c9        Table_map: `yuryu`.`test` mapped to number 70
# at 2785
#130908 21:05:04 server id 10  end_log_pos 2829 CRC32 0x4e043fe7        Write_rows: table id 70 flags: STMT_END_F

BINLOG '
8GcsUhMKAAAAMAAAAOEKAAAAAEYAAAAAAAEABXl1cnl1AAR0ZXN0AAEIAADJonx1
8GcsUh4KAAAALAAAAA0LAAAAAEYAAAAAAAEAAgAB//4RAAAAAAAAAOc/BE4=
'/*!*/;
# at 2829
#130908 21:05:04 server id 10  end_log_pos 2860 CRC32 0x3fbac367        Xid = 226
COMMIT/*!*/;
つまり、バイナリログがスレーブに転送されて実行されるのは
  1. GTID_NEXT を次に実行されるトランザクションID(マスターと同じもの)にセット
  2. BEGIN ~ COMMIT でトランザクションを実行
ということになります。

まとめ

  • サーバーごとにUUIDを付与
  • トランザクションIDは サーバーUUID:番号 として連番で生成
  • スレーブで実行するときは GTID_NEXT を指定して同じトランザクションを再生
  • 実行したトランザクションは GTID_EXECUTED に記録される
以上のような仕組みで GTID は自分がどこまでのトランザクションを実行したのか追跡しています。

参考資料

PerconaのMySQL 5.6 GTID in a nutshellというスライドが大変参考になりました。

2013年9月6日金曜日

CentOS / Debian 両方で使える memcached 複数インスタンス対応の init スクリプト

CentOS に標準で添付される memcached 用の init スクリプトは、単一のインスタンスを起動することしかできません。探していると memcached.conf を複数配置して実行するもの は存在するんですが、ほしいのは /etc/sysconfig/memcached を使う CentOS のやりかたと互換性を保ちながら複数インスタンスに拡張するものでした。

というわけで Debian 用の memcached.conf を複数配置するものをベースにして、CentOS / Debian 両対応するとともに環境変数を /etc/sysconfig/memcached から読み込んでインスタンスを起動するものを作成しました。

こちらです: https://github.com/yuryu/memcached-better-init-script/

使い方


もし1インスタンスしか使わない場合は、従来の init スクリプトと変わらず、 /etc/sysconfig/memcached がそのまま使えます。以下は複数インスタンスを起動するときのやりかたです(READMEを日本語にしたものです)。

/etc/sysconfig/memcached-server1
/etc/sysconfig/memcached-server2
        .
        .
        .
/etc/sysconfig/memcached-serverN
というふうに必要なだけサーバーを並べます。 server1 の部分は好きな名前が使えます。
service memcached start
とすると、すべてのサーバーを起動します。
service memcached start server3
とすると、指定したサーバーのみ起動します。 stop も同様です。 それぞれのファイルの中身は
PORT="11212"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS=""
という感じで指定します。
CentOS 6.4 で動作確認しています。 LSB 準拠なので Debian でも動くはずですが確認はしていません。 CentOS では redhat-lsb-core パッケージが必要です。

2013年9月4日水曜日

MySQL 5.6.11でGTIDを有効にしFLUSH LOGSするとレプリケーションが止まる

タイトルのとおりです。 MySQL 5.6.11 (5.6.10までと5.6.12以降は大丈夫) において GTID を有効にした状態で、マスターで FLUSH LOGS すると、レプリケーションが停止します。

スレーブで SHOW SLAVE STATUS すると下記のようなエラーが出ています。

Last_IO_Error: Got fatal error 1236 from master when reading data from binary log: 'Found a Gtid_log_event or Previous_gtids_log_event when @@GLOBAL.GTID_MODE = OFF.; the first event 'mysql-bin.000013' at 404, the last event read from './mysql-bin.000013' at 452, the last byte read from './mysql-bin.000013' at 452.'
Last_SQL_Errno: 1778
Last_SQL_Error: Error 'Cannot execute statements with implicit commit inside a transaction when @@SESSION.GTID_NEXT != AUTOMATIC or @@SESSION.GTID_NEXT_LIST != NULL.' on query. Default database: ''. Query: 'FLUSH ERROR LOGS'

FLUSH ERROR LOGS でレプリケーションが止まってしまいます。これは logrotate するときに発行されていて、1日経つと(深夜に)レプリケーションが止まるという、とても困った状態になりました。

調べたところこれは 5.6.11 固有のバグでした。公式に MySQL Bugs: #69045: replication was broken while executing flush tables としてレポートされています。

gtid_next が automatic ではないときに、暗黙にトランザクションを発生させてコミットするようなステートメントを禁止した副作用で、FLUSH LOGSなどのステートメントがうまく動かなくなってしまったらしいのです。

5.6.12 以降ではこのパッチは差し戻されて、正常に戻っています。

tar は圧縮形式を指定しなくても展開できる

tar は最もよく使われるコマンドの一つですが、意外と知られていないことがあります。それは、展開するときに圧縮形式を指定しなくても展開できるということです。

よくtarを使ってファイルを展開するときに紹介されるコマンドは

tar xzvf archive.tar.gz
tar xjvf archive.tar.bz2
tar xJvf archive.tar.xz

というふうに、圧縮形式を指定しているものだと思います。ところが広く使われている GNU tar (Linux)も、BSD tar (OSX)も、展開するときは圧縮形式を自動判別します。つまり、

tar xvf archive.tar.gz
tar xvf archive.tar.bz2
tar xvf archive.tar.xz

とするだけで、すべての形式を自動判別して展開します。ちなみにファイルの一覧を出力してほしくない時は

tar xf archive.tar.gz
tar xf archive.tar.bz2
tar xf archive.tar.xz

とすると画面上には何も出力せず展開してくれます。

このことは、GNU tar であれば公式マニュアルBSD tar であればmanにかかれています。

GNU tar の場合
Reading compressed archive is even simpler: you don't need to specify any additional options as GNU tar recognizes its format automatically.
圧縮されたアーカイブを読むのはより簡単です。GNU tar が自動的に形式を認識するので、追加のオプションを指定する必要はありません。

BSD tar の場合
代表例として -z を抜粋しますが、他の形式のオプションのところにも同様のことが書かれています。
-z, --gunzip, --gzip
(c mode only) Compress the resulting archive with gzip(1). In extract or list modes, this option is ignored. Note that, unlike other tar implementations, this implementation recognizes gzip compression automatically when reading archives.
-z
 (cモードのみ) 生成されるアーカイブをgzip(1)で圧縮します。展開やリストモードでは、このオプションは無視されます。他のtarの実装と異なり、この実装ではアーカイブを読むときにgzip圧縮を自動的に認識します。

いかがでしょうか。特にBSD tarの場合は明確に「無視する」と書いています。

ちょっとしたトリビアですが、知ってるとだいぶ得した気分になれます。

2013年9月2日月曜日

各種圧縮ソフト 圧縮速度と圧縮率の比較(並列版含む)

Unix-like 環境でよく使われるアーカイバの圧縮速度、圧縮率を比較しました。

比較したツール

すべて CentOS 6.4 / EPEL のレポジトリのビルドを使用しました。

比較した環境

  • CPU: Intel Core i7 2600
  • SSD: Crucial m4
  • Memory: DDR3-1600 16GB

ベンチマーク内容

圧縮に使ったファイルは、数GBあるMySQL のダンプです。

cat original | command > original.compressed

という形でベンチマークしました。

下記の表は gzip の標準状態を 1 とした相対的な数値を示しています。 Software 欄の -1 や -9 は、コマンドに指定できる圧縮率です。 -1 が最低、 -9 が最高になっているコマンドが多いです。

並列に実行できるものに関してはすべて 8 スレッドで実行しています。

ベンチマーク結果

time real
実際の経過時間
time user
CPU user 時間
compression ratio
圧縮率の比。大きいほどファイルが大きい。
compression ratio (single/parallel)
並列版について、シングルスレッドに対する圧縮率の比
parallel overhead
シングルスレッド版と比較した CPU user時間の比


Softwaretime realtime usercompression ratiocompression ratio (single/parallel)parallel overhead
lzo0.220.191.55
lzo -94.914.931.25
gzip -10.500.491.15
gzip1.001.001.00
bzip2 -14.414.460.86
bzip25.875.940.79
xz -11.961.980.94
xz17.8618.140.72
pigz -10.100.771.151.001.56
pigz0.201.551.001.001.55
pbzip2 -10.957.600.861.001.70
pbzip21.5712.530.791.002.11
pxz -10.463.610.961.031.83
pxz4.1128.350.731.011.56

棒グラフが相対的な経過時間、緑の点が相対的な圧縮率です。


xz が飛び出てわかりづらいので、xz以外のシングルスレッド系圧縮ソフトを並べました。

lzo が極めて高速ですがgzipに比べ1.5倍程度のサイズになりました。 lzo の最大圧縮はとても速度が遅いにもかかわらず gzip -1 より圧縮率が悪くなりました。
bzip2 は -1..-9 は厳密には圧縮率ではないので、他のソフトに比べて差が小さかったです。圧縮速度と圧縮率のバランスが良いように思います。
xz はさすがの遅さでした。ただ、 xz -1 や(今回は測っていませんが) xz -2 であれば、bzip2 より高速にもかかわらず肉薄する圧縮率を出すので、かなり優秀だと思います。
gzip は圧縮速度と圧縮率のバランスが取れています。

次にマルチスレッド系圧縮ソフトです。棒グラフが相対的な経過時間、緑の点が並列化のオーバーヘッド(シングルスレッド版に対するCPU user timeの比)、赤い点がシングルスレッド版に対する圧縮率の比です。


ご覧のように、シングルスレッド版に対して圧縮率はほとんど変わりません。シングルスレッド版に対する実行時間は bzip2 が若干高く2倍を超えましたが、その他は1.5倍~1.8倍程度でした。

まとめ

圧縮速度と圧縮率のバランスが取れているのは gzip で、並列版の性能も優秀でした。速度をある程度要求される環境下においても、 lzo には並列版がないので、CPUをたくさん使えるのであればこれで決まりな気がします。

xz は最高の圧縮率でした。 ただ、時間をかけて圧縮する用途にしても、さすがに時間がかかりすぎの気もします... 今回は測っていませんが、bzip2 より展開は早い(らしい)ので、ファイルを配布するなどの用途には向いているのでしょう。

bzip2 は圧縮率こそ xz に叶いませんが、実行速度とのバランスは優れていると思います。展開に時間が掛かるのがデメリットですが、一応保存しておく系のログファイルなどには使えるのではないでしょうか。

lzo の高圧縮モードは今回の測定だと出番がないように見えますが、展開が gzip に比べてメモリや時間が少なくて済むので、組込み用途では活躍しそうです。

補足

xz のマルチスレッド版には pixz というのもありますが、これは圧縮アルゴリズムにも少し手を加えており、 xz とファイルの互換性がありません。 環境によってはビルドが失敗するなど、これからに期待です。 ファイルの互換性はあるようです。また、私の環境でビルドが失敗したのは単にSDKが古いから説が浮上したので、今度追試します。

pxz は xz を単純にマルチスレッドにしたもので、圧縮が終わってからファイルを連結するので、メモリとディスクの使用量がかなり大きくなります。

今回は展開速度に関しては測っていませんので、展開を頻繁に行う場合はそちらも考慮する必要があります。

2013年9月1日日曜日

Linux Kernel Updates の Kindle 版が出ました!

おまたせしました!

コミックマーケット83で頒布した Linux Kernel Updates 2012.12版と、コミックマーケット84で頒布した Linux Kernel Updates 2013.08版のKindle版を出版しました。

Linux Kernel Updates 2012.12


目次

  • What's New in Linux 3.7?
  • TCP Fast Open
  • Load Average の落とし穴
  • Completely Fair Scheduler
本文試し読み(冊子版のキャプチャです)。

Linux Kernel Updates 2013.08版

目次

  • What's New in Linux 3.8?
  • What's New in Linux 3.9?
  • What's New in Linux 3.10?
  • カーネルを更新するには
  • Modern Socket Progarmming
  • カーネルソース読書ガイド
  • マルチコアを使いこなす

本文試し読み(冊子版のキャプチャです)。

2013年8月22日木曜日

/etc/hosts はホスト数が増えるとDNSより遅くなる

/etc/hosts にホスト名を書いて配るというのは、数台のマシンを管理する状況では誰しもやったことがあると思います。DNSクエリが発生しないのでとても早く、また単一障害点が発生しないメリットがあります。その反面、台数が増えてくると全部を更新するのがとても大変になるだけでなく、致命的な速度低下をもたらします。

今回は /etc/hosts と dnsmasq でどの程度速度が変わるのかをベンチマークしました。

テスト環境は

  • OS: CentOS 6.4 64bit, Linux 3.10.2
  • CPU: Intel Core i7-2600 @ 3.4GHz
です。

テストにはひたすら getaddrinfo(3) し続けるプログラムを作成し、名前を解決しました。 /etc/hosts には

10.234.130.1 host1301
10.234.130.2 host1302
10.234.130.3 host1303

のように適当なアドレスとホスト名を並べたものを作り、利用しました。なお端数の2件はIPv4とv6のlocalhostです。

比較対象に dnsmasq をローカルに立てて同じ内容の hosts ファイルを読ませたものを使いました。

結果は次のとおりです。単位は秒で、10万クエリあたりの所要時間です。

#hostshostsdnsmasq
21.5164.8068
1022.65984.9224
2524.44744.9286
100213.23764.831


結果は一目瞭然で、ホストのエントリ数が増加するに従って、hosts を引く時間はほぼ線形に増加しています。今回の構成では損益分岐点はおよそ250エントリ程度となりました。なお hosts に見つからなかった場合は hosts の検索時間に加えて DNS を引く時間がかかります。

こうなる理由は、hosts の中身はライブラリ(libc)によって処理されていて、毎回 fopen(3) して線形に検索しているからです。dnsmasqをはじめとする多くのネームサーバーはファイルから読み込んだあと、ハッシュなどを使って高速に検索を行います。

実際には1リクエストあたりの時間に換算すると0.05マイクロ秒程度で、hostsに1000エントリ書いた場合でも0.14マイクロ秒なので大した時間ではありません。ですが、場合によってはhostsを引くよりきちんとDNSを使ったほうが早くなる場合があるということは覚えておいて損はありません。

測定に用いたプログラムは下記のとおりです。
2013/08/23 追記: タイトルが「急激に遅くなる」というのは煽っていると指摘を受けたので変更しました。 測定ポイント数が少ないのは単なる手抜きです...
「そんな多数のホストがある状態で /etc/hosts にすべて書くのはありえない」的な意見も見受けられましたが、実際にあるんですよ... そういう状態に対してきちんとエビデンスを示す目的で書かれました。 DNSで実際に速度や冗長性を担保するには別の工夫が必要になりますが、それはまた別の記事で。

あと nscd 使えばっていう話があったので参考までに1002エントリhostsで走らせたところ
$ ./a.out 100000 host127183
Resolved 100000 times. Elapsed time = 0.740 seconds, 0.007 us per host.

こんくらいの速度だったので、何も考えずに200倍早くなります。

2013年7月27日土曜日

Growth Hacker Andrew Johns Meetup に参加してきました

Open Network Lab で開催されたGrowth Hacker Andrew Johns Meetup に参加して来ました。Facebook、Quoraのユーザー獲得チームで働いていた方です。

講演内容


講演の内容は3つでした。

1. ユーザー獲得は家計と同じ
  • 数パーセントの違いが複利で効いて、1年後には大きな違いを産む
  • 収入(ユーザー)を増やすことと、負債(技術的負債)を減らすことのどちらも重要
  • 一ヶ月で100%の成長が一回きりと、毎週3%の成長が1年間では後者のほうが効果を生む
  • 毎週1%の成長で年1.7倍、毎週3%だと1年で5倍の成長になる
2. 成長は個人だけでやることではなく、会社の変革が必要
  • 会社の文化が成長を求めるよう、文化を変える
  • 社内で積極的に情報発信し、チームを変え、会社のDNAを変える
  • "Growth Hack"の対象には会社自身も含まれる
3. シンプルさが大事
  • 機能を追加すると複雑さが増し、ユーザーは減少する(特に資金を得た後が危ない)
  • ユーザーを追うメトリックも単純なものを選ぶ
  • ゴールやチームのミッションもシンプルで共有しやすいものにする
そして大事なこととして「ダメなサイトを持続的に成長させることは不可能。プロダクトが優れていることは絶対条件。」が示されました。良いプロダクトの目安として、例えば1000人の新規登録ユーザーのうち2~3割が翌月も使い続けているとすると、そこそこ良い線だということです。

話の途中、いくつかの事例が示されました。

KPIとしては K + sqrt(abc) を使う。変数はそれぞれ

  • K: バイラルでの成長
  • a: プロダクト数の増加
  • b: プロダクトあたりのトラフィック
  • c: 売上のコンバージョン率
例えばamazonでは、aは極めて大きく、bも「プロダクトごとにpermalinkがあり、検索エンジンから流入するし、口コミでリンクを貼れる」などと工夫しています。Qiitaのようなサイトではaは記事数、bは記事あたりのトラフィック、cをサインアップする人の割合と読み替えると良いでしょう。
そして単純なKPIを決定したら、それぞれの部分、K, a, b, cごとにチームを組み、ミッションを割り当てるのが重要とのことです。例えばaを増やすのに専念する渉外チーム、bに専念するエンジニアチーム、cに専念するデザイナーチームという感じです。
この中でKを増やそうとするのは危険だそうです。というのも、口コミはコントロール出来ないし、企業が展開すると「押し付け」のようになってしまうからだそうです。

劇的な改善ができた例として、Twitterのサインアップページの例がありました。
Twitterでは、ユーザーが増加するに従いユーザー名の衝突が起きやすくなりました。そこで、サインアップページで氏名を入力すると、自動的に衝突しないユーザー名を提案し、フォームに自動入力する機能をつけました。そうすると、毎日6万人の新規登録が増えたそうです。

企業のDNAが重要な例として、MySpaceのトップページが挙げられました。
MySpaceでは収益を重視して、トップページに広告を掲載しました。すると新規登録が減少したというのです。逆にFacebookはユーザー増加が最重要ということで、トップページは新規登録に必要な情報に絞った結果、ユーザー数が増加するようになったとか。

実験を簡単に、多数できるようにする環境づくりも重要だそうです。
Quoraでは新しいことをすぐ実験、数値解析ができるプラットフォームに投資し、200以上の実験を行なってくることができたと示されました。とにかく実験しないと、例えば70個ぐらいのアイデアのうち多少なりともうまく行ったのは15個、大成功したのは3個程度という打率で、やってみないとわからないことも多そうです。

感想


今までのKPIはDAU, ARPUなど「ストック」に注目するものが多かったところ、「フロー」に着目して成長を定量化するという視点が新鮮でした。いかにユーザーが登録までに遭遇する障害を取り除くかというところに着目するとこれだけ新規登録が増えるということは、変なフォームで諦めてしまう人も多いのかなと思いました。
最近どのようなKPIを取ればプロダクトの状態がわかるかというのが話題になっていますが、この「フロー」をよく見るいうのはひとつの答えだと思いました。

2013年7月26日金曜日

コミケ84、3日目に参加します!(東5 ヘ-46b)

8月12日に、コミケ84に参加します!
スペースは東5ホール ヘ-46bです。通路すぐなのでわかりやすいと思います。

販売予定の本は

Linux Kernel Updates, Vol. 2013.08

内容は、
  • Linux 3.8~3.10の新機能
  • カーネルを更新するには
  • Modern Socket Programming
  • カーネルソース読書ガイド
  • マルチコアを使いこなす
です。
表紙はきのとなおとさんに描いていただきました。

冬コミで頒布した本も増刷して持っていきます。こちらは3.7の話と、主にスケジューラーについてまとめてあります。

みなさまとお会いできることを楽しみにしています!

2013年6月28日金曜日

グリーを退社しました

本日がグリー株式会社での最終出社日でした。実際の退職は月末ですが、事実上もう会社に行くことはありません。 ... 前にパナソニックの退職エントリを書いてから1年ちょっとしか経っていませんが、新しい仕事に挑戦したくなり、退職を決めました。

組み込みエンジニアからWebのインフラエンジニアへの転身という「どうしてこうなった」的なキャリアパスでしたが、コンピュータサイエンスやプログラミングの知識そのものは共通で使えました。カーナビのブートローダーやデバイスドライバを書いた経験なんてどれぐらい役に立つのかなと思っていましたが、案外 Linux のカーネルレベルでの解析やチューニングに携わることが多く、また Apache や PHP も C言語で書かれているので、直接経験が生かされた感じです。本当に幸運でした。 でも PHP は結局書けないままです...

働いてみて一番よかったと思ったのが、書籍や勉強会などで積極的に発表している人が身近にいたということです。グリーで働くまでは結構遠い存在のように思っていたのですが、入ってみると隣の机だったりすることがあり、とても良い刺激になりました。 また社内での勉強会もあり、仕事に関係があってもなくてもとにかく「学ぶ」ことに意欲的な人が多かったです。

相変わらず女性エンジニアはレア度が高く、これはもう業界にいる限り仕方がないかなという気がします... でもそんな中、以前掲載されたTech総研でのインフラ女子特集に載っている人たちが同僚で、とても楽しかったです。

転職の理由で一番大きいのは、もっと小さなところから新しいものを作り上げる過程に挑戦してみたいということです。 次は社員数二桁、設立2年ちょっとの会社で働きます。

狭い業界なので会社が変わってもお付き合いする人は変わらないと思いますし、次も東京で働くので今後ともよろしくお願いします。

2013年4月3日水曜日

SimCity がプレイできるようになるまで

EA/Maxis から新しい SimCity が発売されました。私はこのシリーズのファンなので、昨年の11月に予約し、発売を今か今かと待っていました。2月17日のβテストにも参加しました。発売日にはダウンロードしてプレイし、サーバーに接続できない苦しみも味わいました。
ところが、その後3月8日に異変が起こります。注文がキャンセルされ、6日後の14日にはプレイできない状況になります。その後再びプレイできるようになるまで、いろいろな問い合わせを行い、最後は国際電話をしましたので、その記録です。

2012年11月にゲームを予約注文します。しかし、その後注文に使ったクレジットカードが不正使用され、新しい番号に切り替えてもらっていました。SimCity の注文を切り替えてはいませんでした。

3月7日、SimCity が日本で発売されたのでプレイを始めました!

3月8日、「注文がキャンセルされました」というメールが届いたので、カードに請求がないことを確認の上もう一度購入しようとしました。すると「すでに購入したことがあります」と表示され購入出来ません。EAのサポートにフォームで問い合わせました。この時点ではゲームはプレイできていました。

3月14日に、SimCity をプレイしようとすると「アカウントのシムシティが有効になっていません。 Origin でシムシティを有効にしてください。」というメッセージが現れました。終了するをクリックするとゲームが終了し、全くプレイ出来ません。EA から返答がないので、再びフォームから問い合わせました。

3月15日。全く返事がないので電話しました。意外とあっさりつながったので要件を伝えました。問題を認識したのでエスカレーションすると言われ、電話は終了しました。

3月18日、ためしてみると SimCity が購入できるようになっていたので、もう一度購入しました。すると、購入してマイゲームには現れたのですが、相変わらず「有効になっていません」という表示が出ます。カードの請求も発生しました。状況が変わったのですでに問い合わせていたフォームのチケットにコメントを書き込みました。その一方で、このままでは埒があかないので、Origin の言語設定を英語にすると現れる Live Chat を使って問い合わせました。事情を一から説明すると「処理が遅れてるので、少し待ってほしい。すぐにプレイできるようになるはず」と言われました。

3月19日、相変わらずプレイできないので、もう一度 Live Chat で問い合わせました。問い合わせ番号を伝えたのですが、もう一度最初から説明させられました。すると「ゲームをプレイする権利が何らかの理由で付与されていない。これを解決する専門の部署があるので、電話してほしい」と言われ、アメリカの電話番号を伝えられました。要件を転送して解決できないのかと言いましたが、転送はするが電話も必要だと言われました。日本の窓口に電話したのですが、混雑しているという録音とともに切断されました。

その日の深夜に電話をしたのですが、30分経ってもつながらなかったので諦めました。

3月20日、時間を確保して電話しました。1時間20分待たされてつながりました。問い合わせ番号を伝えましたがまた最初から説明する必要がありました。 20分ほどかかって問題を解決してくれ、その場でゲームを有効にしてくれました。もう一度電話するのは嫌だったので、その場でプレイできるか確認し、電話を切りました。

結局フォームから問い合わせたものは、電話で解決するまでに返事はありませんでした。Live Chat の待ち時間はだいたい50分ぐらいで、こちらは残り時間が出るのでいいのですが、電話で待ち時間が出ないまま延々待たされるのはつらかったです。 また、タイムゾーンが東海岸なのでそれに合わせて電話しなければならないのと、秘密の質問を日本語で記入していたためこれを英語で説明するのに戸惑った、というのが日本からアメリカへの電話ならではの苦労でしょうか。

EA のゲームはプレイするまでもゲームというのを身を持って体験しました。結局1週間弱プレイできなかったのですが、その間にそこそこサーバーは安定し、プレイできるようになってました。バグはいっぱい残ってますが... その後は睡眠不足になるぐらいに楽しんでます。

メインは東欧3でプレイしてます。アカウントは Yuryu-Haruka です。ぜひ誰かと一緒にプレイしたいです!

2013年1月4日金曜日

Plextor PX-256M5P vs 東芝 DT01ACA300BOX

初SSD記念でベンチマーク取りました。

両方ともシステム入れて使ってたり、いろんなデータすでに置いている状態なので、理想状態よりは遅くなっているであろうことを申し添えておきます。

SSD: Plextor PX-256M5P

-----------------------------------------------------------------------
CrystalDiskMark 3.0.2 Shizuku Edition x64 (C) 2007-2013 hiyohiyo
                           Crystal Dew World : http://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 byte/s [SATA/300 = 300,000,000 byte/s]

           Sequential Read :   513.421 MB/s
          Sequential Write :   446.646 MB/s
         Random Read 512KB :   381.395 MB/s
        Random Write 512KB :   427.883 MB/s
    Random Read 4KB (QD=1) :    28.854 MB/s [  7044.4 IOPS]
   Random Write 4KB (QD=1) :    50.956 MB/s [ 12440.3 IOPS]
   Random Read 4KB (QD=32) :   388.745 MB/s [ 94908.5 IOPS]
  Random Write 4KB (QD=32) :   348.163 MB/s [ 85000.8 IOPS]

  Test : 1000 MB [C: 24.1% (57.3/238.0 GB)] (x5)
  Date : 2013/01/04 0:36:10
    OS : Windows 8  [6.2 Build 9200] (x64)

HDD: 東芝 DT01ACA300BOX(3TB, 7200rpm)

-----------------------------------------------------------------------
CrystalDiskMark 3.0.2 Shizuku Edition x64 (C) 2007-2013 hiyohiyo
                           Crystal Dew World : http://crystalmark.info/
-----------------------------------------------------------------------
* MB/s = 1,000,000 byte/s [SATA/300 = 300,000,000 byte/s]

           Sequential Read :   174.792 MB/s
          Sequential Write :   174.704 MB/s
         Random Read 512KB :    48.242 MB/s
        Random Write 512KB :    71.147 MB/s
    Random Read 4KB (QD=1) :     0.554 MB/s [   135.2 IOPS]
   Random Write 4KB (QD=1) :     0.620 MB/s [   151.4 IOPS]
   Random Read 4KB (QD=32) :     1.516 MB/s [   370.2 IOPS]
  Random Write 4KB (QD=32) :     0.641 MB/s [   156.5 IOPS]

  Test : 1000 MB [D: 25.3% (707.1/2794.4 GB)] (x5)
  Date : 2013/01/04 0:42:54
    OS : Windows 8  [6.2 Build 9200] (x64)

文字通り桁が違います。システムドライブはもう SSD 以外考えられません。

2013年1月3日木曜日

コミケ83報告

コミケ83で Linux Kernel Updates を出します!(31日東X-58b)の事後報告です。

予想外に好評をいただき、50部持っていったのですが11時半ごろに完売してしまいました。「どうせ余るだろうから、ゆっくりいらしてください」と事前にアナウンスしていたので、午後にいらっしゃった方々、申し訳ありませんでした。

いただいたご意見の中に「Linux の変更点を最近追いかけているサイトがないので、まとめてもらえるなら実は需要あるんじゃない」というものがありました。実は KernelNewbies.org がすごくよくまとまっているので、そこを見ながら、自分が気になった新機能についてはまとめていく、なんてことが出来ればいいなぁと思います。

夏コミにも応募します。もし受かれば内容は若干古くなってしまいますが、同じ物を再販して持っていきます。そして、新しい本も出します。今度は調子に乗ってもう少し多めに持っていくつもりです。中身はまだ決定はしていませんが、Linux Virtual Server の中身と、スケジューラーの SMP 対応コードの解説なんかを考えてます。

なお、冬コミ本の中身のうち What's New in Linux 3.7? については、旬を過ぎるとおもしろくないのでBlogに掲載しました。買ってくださった方には少し恐縮ですが、もともとが Web に載っている情報なのでご容赦いただければと思います。

What's New in Linux 3.7?

コミケ83でLinux Kernel Updatesという同人誌を出したのですが、予想外の好評をいただき11時半ごろに完売となってしまいました。

次の夏コミに受かれば再販する予定ですが、Kernel 3.7 のニュースは古くなってしまうので、こちらに掲載します。

What's New in Linux 3.7?

Linux 3.7 に含まれる主な変更点を kernelnewbies.org の記事から翻訳しました。

ARM Multi-platform support

x86 では一つのカーネルイメージが複数の PC 上で動作しますが、ARM は基本的にボードやプラットフォームごとにカスタムのカーネルを作成します。いわゆる組み込み文化です。ところがそのままだと Debian のような distributor が ARM 用の distribution を配布するのが大変なので、複数のプラットフォーム上で動作するカーネルイメージを作成可能にしました。 ただし、単に起動するだけといったレベルですので、実用的な使用には現時点ではボードごとの定義が必要です。

ARM 64-bit support

ARMv8 では 64bit コードの実行がサポートされましたので、Linux でも 64bit 版 ARM コードの生成をサポートしました。 x86 と異なり、 64bit ARM は 32bit ARM と全く互換性がないので、別のソースツリーで管理されることになりました。

Btrfs の改善

fsync() の改善: fsync() はデータをディスクにフラッシュするシステムコールです。btrfs はこれまで fsync() が遅かったのでいくつかのアプリケーションでのボトルネックになっていましたが、これが改善されました。 SATA の遅いドライブでも2割~5割、Fusion IO や RAMディスクなどの高速なドライブでは最大7倍程度の性能改善になります。

ディレクトリあたりのハードリンク数上限の解除: Btrfs は従来ディレクトリ内にはハードリンクを20しか許しませんでしたが、今回のバージョンから6万5000個のハードリンクを作成できるようになりました。また、これに伴いディスク上の構造に拡張が加えられました(古いバージョンのカーネルとは互換性がありません)。

Hole punching: ファイルのある一定の領域を未割り当てな状態とする、FALLOC_FL_PUNCH_HOLE オプションをサポートしました。蛇足ですがこのパッチは fusion-io の方からポストされています。やはり SSD にとっては TRIM されているかどうかは重要な様子です。

chattr による ファイルごとの NOCOW 属性のサポート: btrfs ではデフォルトでは COW(copy-on-write) を使用しますが、従来は nodatacow マウントオプションにより COW を無効にすることができました。COW は負荷によっては性能が悪化します。この変更では、ファイル単位で COW を無効にすることができます。ただし、すでに内容があるファイルの属性を変更することはできず、空のファイルにのみ適用できます。すでに中身があるファイルを変更したい場合は、一度テンポラリファイルを作成して属性を変更し、中身をコピーする必要があります。また、COW を無効にすると、チェックサムも無効になります。

perf trace, strace の代替

strace の代替として、新しい "perf trace" が perf profiling infrastructure に追加されました。従来 strace は ptrace() を使っていましたが、perf trace は Linux profiling infrastrcture を使用します。

まだ開発の初期バージョンでシステムコールのみ表示できますが、今後ページフォールト、task のライフタイムイベント、スケジューリングイベントなどをサポートする予定です。また、現在は live で表示することしか出来ませんが、 perf.data のようなファイルを出力して事後の解析ができるようになる予定です。

サーバー側 TCP Fast Open

3.6 ではクライアント側での TCP Fast Open のみサポートされていましたが、3.7 でサーバー側のサポートも追加され、 Linux の TCP Fast Open サポートが完了しました。

実験的な SMBv2 プロトコルサポート

CIFS ネットワークファイルシステムが SMB プロトコル version 2 をサポートしました。 SMB2 はよく使われている CIFS と SMB によるファイル共有の後継で、2006 に Windows Vista により導入されました。 SMBv2 は前のバージョンに比べて高い性能、セキュリティと多くの機能が提供されます。 ちなみに Samba 4.0 では SMB 2.1 がサポートされ、また Windows 8 からサポートされる SMB 3.0 のサーバー実装も進んでいます。需要がどれほどあるのか、少し不安なところもありますが、新しいプロトコルのサポートに期待です。

NFS v4.1 の「実験的」が取れました

NFS v4.1 (RFC5661) は長い時間をかけてサポートされてきましたが、今回はじめて「実験的(experimental)」ラベルが取れました。

NFC v4.1 の主な機能は pNFS (parallel NFS) です。pNFS を用いると、ファイルシステムやファイルを複数のサーバーに分散して配置し、並列にアクセスすることが可能になります。

拡張性のある VLAN トンネリングプロトコル

vxlan という、L2 ethernet over UDP のトンネリングプロトコルが Linux に追加されました。 vxlan はしばしば仮想化環境で仮想ネットワークをトンネリングするために使われます。

VXLAN プロトコルそのものは RFC ドラフトで、VLAN の数が 4096 に制限されていることを解決するためのトンネリングプロトコルです。 vxlan では識別子が 24bit に拡張されます。また、使用するUDPポートは一つです。他のほとんどのトンネリングプロトコルとは異なり、VXLAN は 1:1 だけではなく 1:n の接続もサポートしています。VXLAN デバイスは接続先のIPを自動識別してブリッジを自動構成することも可能ですし、または静的に転送設定を記述することもできます。 Open vSwitch のための VXLAN 実装もあります。

Intel SMAP のサポート

Intel SMAP (Supervisor Mode Access Prevention) は、将来の Intel プロセッサに導入されるセキュリティ拡張です。SMAP が有効になると、カーネルがユーザー空間のメモリにアクセスすることが禁止されます。いくつかの exploit の防止に役立ちます。

ext4 の改善

truncate / unlink が高速化されました。 あるベンチマークにおいて、60GB のファイルを rm する場合、従来 2.7秒かかっていたものが 0.6秒強まで短縮されています。

ディレクトリエントリのサイズを一定に制限することができるようになりました。

ネットワーク

loopback インタフェースのデフォルト MTU が 64kb に増えました。

まとめると、今回の目玉は ARM アーキテクチャの改善ですが、btrfs や ext4 のパフォーマンス改善など、実際に役に立つ変更も多数含まれています。また、 TCP Fast Open のサーバーサイドサポートも含まれましたので、Web アプリケーションの高速化には 3.7 以降が必須になってくるでしょう。

Part of the above article is translated from http://kernelnewbies.org/Linux_3.7, CC-BY Linux Kernel Newbies