「非Railsアプリケーションのマルチデータベース対応と高速化の取り組み」が面白かった

RubyWorld Conference 2015の動画を見ています。
18分ほどの短めのセッションでしたが、とても面白かったです。

MySQLにしか製品していなかった製品を大人の事情でPostgreSQLにも対応したというお話。 ORMとしてSequel を導入したがいろいろ問題があり、それらをいかにして乗り越えたという心温まるおエピソードでした。


A-5-1 「非Railsアプリケーションのマルチデータベース対応と高速化の取り組み」

Sequel導入

結果

遅くなった!

原因

  • ARパターンでDB接続時にテーブル構造を取得
  • Unixデーモンモデル(接続ごとに子プロセスをfork)

マルチスレッド化

結果

遅くなった!!

原因

  • Rubyは1プロセスが同時に1CPUしか使えない
  • 複数スレッドを作成しても同時に動けるのは1個だけ
  • クライアントから大量の接続があると、サーバーの全てのCUを使い切ってないのに頭打ち

マルチプロセス&マルチスレッド

ParallelServer導入

結果

改善。でもまだ以前より遅い!

原因

メモリ使用量抑えるため、GC.startしていた
マルチスレッドプレセスだと全スレッドが停止してしまう
(ruby1.8.6の頃のコード)

GC.start廃止

結果

以前より早くなった!!

でも

メモリ使用量は多くなった

メモリ使用量削減

  • Sequelのスキーマキャッシュを使用
    テーブル構造をlocal fileとして置いておける(DB接続しない)
  • object作らない、無駄な処理を見直し
  • Timeout削減
    Timeout時にスレッド生成されていた
msgs.each do |msg|
  Timeout.timeout(999) do
    socket.write data
  end
end
  • jemalloc マルチスレッド時にメモリを食うようになっていた(原因は不明)

結果

スループット、メモリ使用量ともに改善!!

Sequeよさそう

昔、ActiveRecordのパフォーマンスを気にして、Sequelの導入検討したことがありましたが、
今見ても、なかなか良さそうです。
jeremyevans/sequel
ActiveRecordパターンも利用できるし、構文もきれいな印象です。