Passenger が高負荷時に 503 Server Temporarily Unavailable を返すとき

Apache + Passenger で運用している Rails のサービスにアクセスが集中し、503 Server Temporarily Unavailable が出るようになった。まずはサービスを数分止めてでも復旧させようと、2倍の性能を持つインスタンスに変更してみた。が、それでは足りず。結局、元の8倍の性能を持つ(と思われる)インスタンスに変更して、なんとか画面が表示されるようになった。ELB や autoscale は導入していないサービスなので、インフラ的にはこれが最も手っ取り早かった。

復活はしたものの、じりじりと遅くなっていく感じがする。まずい。すると同僚が「PassengerMaxRequestQueueSize っていうパラメタがあるよ」と教えてくれた。標準的な conf には書かれておらず、設定されていないときのデフォルト値は 100。これは、処理しきれないリクエストをいくつまでキューに貯めておくかという値。100 で足りなきゃ 500 にしてみよう。

症状は良くなったものの、まだ足りない。とはいえサービスは遅いながらも動いているので、いろいろ調べる余裕ができてきた。passenger.conf をじっと見る。そこで目に止まったのが PassengerMaxInstancesPerApp 4 という設定。これって、アプリケーションあたりの passengerプロセスが 4個までってことだ。それじゃ全然足りない。20にしてみた。

すると、劇的に軽くなった。これか! 今回のケースでは、PassengerMaxPoolSize を大きくすれば、PassengerMaxRequestQueueSize を増やすのは必要なかったかもしれない。キューに入れるというのは、どちらにしても待たせることになるのだから、処理しきれないリクエストを500も抱えても嬉しくない気がする。

AWS Startup Tech 夏のLT大会 at dots.

http://eventdots.jp/event/567770

Schoo 岩田さん

  • オンプレミスで始めた。
  • RDS read replicat は DNS round robin.
  • 画像サイズの変更は ngix で変換して cloudfront でキャッシュ。
  • バッチは SQS。授業コンテンツの画像変換、メール送信、ランキング。それぞれのサーバが cron で処理を投げる。処理を投げるだけ。SQS が受け取る。スケールさせやすいのではないか。

vivit 小川さん

  • Vue.js採用
  • AWSクレジットをもらったので贅沢な構成にしていたが、クレジットが切れたので、運用費と可用性を天秤に掛けて、お金を取った。今は最小構成で動かしている。

トランスリミット 松下さん

  • スマホアプリ:Brain Dots
  • オフライン前提、可能な限りサーバレス、シェア機能を充実
  • ダウンロードした状態で基本的に全てプレイできる。
  • イベントなど必要なときだけサーバを用意
  • Google Play Saved Games, iCloud KVS でユーザデータを保持。かなり低コスト。
  • デバイスの言語ではなく、アプリ内で言語を切り替えられる。
  • グローバル対応:プッシュ通知を Timezone ベースに。
  • プレイ動画の共有 everyplay を使っている
  • ゲームプラットフォームのログインを推奨。

Ashley Madison の月別売上推移

カードトランザクションデータを月別に集約してグラフを描いてみた。

> # DBで月毎の売上を集計する
> con <- dbConnect(MySQL(), dbname='xxx', user='xxx', password='xxx)
> rs <- dbSendQuery(con, 'select date_format(date, "%Y%m") yyyymm, sum(amount) amount from creditcard_transactions group by date_format(date, "%Y%m")')
> data <- fetch(rs, n=-1)

> # データの概要を確認する
> summary(data)
    yyyymm              amount        
Length:89          Min.   :      79  
Class :character   1st Qu.: 3585339  
Mode  :character   Median : 4942854  
                   Mean   : 7093373  
                   3rd Qu.: 7363206  
                   Max.   :23430359

> # データの先頭を確認する
> head(data)
  yyyymm     amount
1   <NA>      79.00
2 200803   97676.25
3 200804  266162.40
4 200805 1310610.90
5 200806 1610211.16
6 200807 2324480.04

> # データの末尾を確認する
> tail(data)
   yyyymm   amount
84 201501 21414885
85 201502 19140610
86 201503 21420715
87 201504 21376923
88 201505 23430359
89 201506 10823819

> # NA の入ったデータを取り除く
> data <- subset(data, complete.cases(data))

> # 軸が指数表示にならないようにする
> options(scipen=5)

> # プロットする
> barplot(data$amount, names=data$yyyymm)

Monthly Sales of Ashley Madison

直近では月に2,000万ドル超えですか。女性会員がほとんどいなくても、2,000万ドルですか。2013年夏ころから急激に売上を増やしてますね。

Gitlab を Apache と共存させてサブディレクトリで動かす

だいたいはこの記事の通りで大丈夫だった。

GitLabをサブディレクトリ(Subdirectory)でインストールしてWordPressと共存させる

この記事は、こちらの記事を参考に書かれている。

GitLab omnibus をサブディレクトリで運用する

で、このままだと Font Awesome のアイコンが表示されていなかったので、Apache の設定を以下のようにした。

<IfModule mod_proxy.c>
  ProxyRequests off
  ProxyPass /gitlab http://127.0.0.1:8000/gitlab
  ProxyPassReverse /gitlab http://127.0.0.1:8000/gitlab
  ProxyPass /assets http://127.0.0.1:8000/gitlab/assets
  ProxyPassReverse /assets http://127.0.0.1:8000/gitlab
</IfModule>

たぶん、どこか一カ所変えれば、URL の名前空間 /assets を汚さなくてもいいのだと思うけど。

Ashley Madison のダンプデータを MySQL にインポートする

AWS の m4.10xlarge に MySQL をインストールし、デフォルト設定のままでインポートを実施した。

$ time mysql -uroot am < am_am.dump
real  22m23.287s
user  1m59.696s
sys 0m1.292s

$ time mysql -uroot aminno < aminno_member.dump
real  207m36.535s
user  2m45.308s
sys 0m1.900s

$ time mysql -uroot aminno < aminno_member_email.dump
real 65m30.872s
user 0m20.640s
sys  0m0.540s

$ time mysql -uroot aminno < member_details.dump
real  52m8.523s
user  0m26.888s
sys 0m0.932s

$ time mysql -uroot aminno < member_login.dump

real  125m25.691s
user  0m40.116s
sys 0m1.456s

m4.large で aminno_member が数時間(6-8時間くらい?)だったように思うので、m4.10xlarge にしたのはムダだった。

たぶんこういうことをすると速くなる。

たった3秒でInnoDBのデータローディングが快適になるライフハック http://nippondanji.blogspot.jp/2010/03/innodb.html