Railsでバッチ処理を書く場合、rakeタスクとrails runnerのどちらにすべきか

Railsバッチ処理を書く仕事があって、どちらにするべきか迷った。 迷ったのでググったら以下の記事を見つけた。

stackoverflow.com

要約すると

  • script/runner は実行時にRailsアプリを起動する。これは rake:environment と似ている
  • Railsの起動は時間が掛かるので避けられるならrakeにして避けるべき
  • それ以外はほぼ同等

ということなので、Railsのモデルを使うバッチはrunnerで、それ以外はrakeにする方が良さそう。

個人的には、

  • -e で環境を指定できる
  • クラスのメソッドを直接呼べるのでテストが書きやすい(rakeだと結局処理を別のクラスに起こさなければいけない)

という点からrails runnerを使うことにした。

adtech x scala meetupに参加してきた #adtech_scala

2016/5/16に開催された「adtech x scala meetup」に参加してきました。

adtechstudio.connpass.com

「頑張らないでScala 〜VOYAGE GROUPにおけるアドネットワーク開発の戦略〜」 VOYAGE GROUP 岩永 賢明

スタートアップらしく技術はサービス開発を加速できる必要最低限で抑え、しっかり前に進むための地に足を付けた戦略だと思った。 「頑張らないこと」を主眼においているが、いずれ来る困難を先読みし退路を確保しておく、ということはとても重要だと説いていた。

「Dynamic Movie Ad x Scala」 adtech studio 大野 裕太

※資料待ち

広告の配信と同時に動的に広告動画を生成するアーキテクチャについて紹介された。 使用しているミドルウェアSplay/Kafka/Spark/Go/Aerospike/Mysql/S3あたり。 動画生成部分にGoを使っているのは書いている人が得意だった、クロスコンパイルしてLinux/Windows両方動かせるようにしたかった、などから。

Aerospikeを初めて知ったので調べてみたところ、データモデルも指定でき集計もできる高機能なKVSといったものだった。

www.aerospike.jp

「CyberZにおけるScalaの立ち位置」 CyberZ 鈴木 雄登

PHPで構築された管理画面部分をリプレースしたい、かつ共有DBから引き剥がしデータストアAPIを作りたい、というところをScalaで実装したお話。 Scalaを選定したのはそもそもJava開発者が多く、アンケート結果からScalaやりたい人が多かったからとのこと。 Scala複数可能な記述法、ノウハウの不足、読めない記号などに苦しめられたそうだが、「アドテクは連携が多く、統一的な規約がなく汎用的に作る必要がある。言語レベルで抽象化できるScalaは理想的」という言葉が印象的だった。

読めない記号問題は、この発表の最中にTLで流れてきたscala-search.orgが記号にも対応していて便利そうだった。 (なおfoldLeftを意味する /: は ドミノの畳込みをイメージしたものらしい)

LT

speakerdeck.com

Scala.jsの話かと思ったら違った。JVM上でJavascriptを動かすランタイムらしい。Scala.jsより幸せになるんだろうか。

Scalaの歴史振り返り。Scalaコミニュティは徐々に拡大傾向にあるとのこと。ちょこちょこ入るxuwei氏情報が面白かった。

さいごに

登壇された皆様、会場提供のサイバーエージェント様ありがとうございました! お寿司おいしかったです🍣

Atomでファイルを生成せずに素早くRubyコードを実行する

スクリプト書いて連番の文字列を大量に出したい時とか、Rails書いててRubyの挙動を確かめたい時にさっとRubyのコードが実行できたら嬉しいと思います。

で、大抵の場合irbpryを使って書くわけですが、コードを何度か書き直しながら実行したり、複数行にまたいだりするとこれらのツールだと結構面倒くさくなってくるんですね。

そんな時、僕はメインエディタにAtomを使用しているのでatom-runnerRubyコードを走らせています。

というわけで、とっととatom-runnerをインストールします。

$ apm install atom-runner

atom-runnerが無事インストールできたら、atomを立ち上げて

f:id:Peranikov:20160411235008p:plain

Control + Shift + L で Select Grammar からruby とEnterを打ち

f:id:Peranikov:20160411235009p:plain

お好みのRubyコードを書いて

f:id:Peranikov:20160411235016p:plain

Control + Rで実行できます。

f:id:Peranikov:20160411235020p:plain

GrammarでRubyを選ばずとも#! /usr/bin/env ruby とシバンを書いてあげても実行できますがこの方法が速いのでこれでやっています。

なお、atom-runnerが対応している言語であればRubyに限らず実行が可能です。(画像はJavascriptを選択しnode.jsを実行している)

f:id:Peranikov:20160411235902p:plain

JAWS-UGコンテナ支部 #4 に参加してきました #jawsug_ct

2016年2月5日に開催されたJAWS-UGコンテナ支部 #4 に参加してきました。

jawsug-container.connpass.com

「好きです ECR (仮)」 @orih_y さん

ECRの特徴としては

  • フルマネージドDockerレジストリ
  • デフォルトHTTPS
  • Docker Registry HTTP API V2
  • バックエンドはS3
  • IAMと連携したアクセスコントロール

ということだという。

気になる料金だが、DockerHubと比べてもかなり安いとのこと。(詳細忘れた)

「お前のDockerイメージはまだ重い〜体脂肪一桁のDockerイメージを目指して〜」 株式会社サイバーエージェント @stormcat24 さん

ちょうどDockerイメージの軽量化に取り組んでいて、一番聞きたかったセッション。RUNをチェーンしたり、ビルドのためにインストールしたパッケージやファイル(産業廃棄物)を消すという地道な作業が重要ということだった。

このイベントに参加する前にこの記事をちょうど読んでいて自分もAlpine Linuxを触っていた。後から質問したところ、とくにネックになっていることもなくいつでも本番に投入したいと言っていたので、十分に採用することはできそうだった。

「実践ECS-CLI(デモ)」 @pottavaさん

ECS-CLIを使って実際にEC2上にコンテナを立てるデモ。ECS-CLIを使えば、docker-composeを使っているかのようにEC2上にコンテナを立てることができるとのこと。実際にECS-CLIを本番環境で使うには難しく、aws-cliやシェルのサポートが必要とのこと。

「ECSを使ったAutoScalingの実装Tips」 クラスメソッド株式会社 千葉 淳さん

ECSのAutoScalingはコンテナごとのスケールにはまだ対応しておらず、EC2ごとのスケールをしなければならない。それをCloudwatchEventのトリガーを使って頑張った話。

CloudwatchEventのトリガーはほとんどのサービス網羅してそうで、なんでもできそうなイメージだった。

はじめましてJAWS-UGコンテナ支部

_人人人人人人人人人人人_
> 突然のトニーモリス <
 ̄Y^Y^Y^Y^Y^Y^Y^Y^Y^Y ̄

HANDSLABさんでもDockerを本番環境に投入しており、十分に安定しているとのこと。

Docker で Deep Learning

さいごに

JAWS-UGの方々、会場提供のサイバーエージェントさん、ありがとうございました!

「DDD Alliance! ドメイン駆動設計のためのオブジェクト指向入門」に参加してきた #DDDAlliance

2015年1月21日に開催された、「DDD Alliance! ドメイン駆動設計のためのオブジェクト指向入門」に参加してきました。

ddd-alliance.connpass.com

以下から現地で書いたメモ

ドメインモデルとは

ドメインモデル = 関心事を集めたもの。サブセットと呼んでもいい

ドメイン駆動設計

ドメインを分析する人がコードを書く コードを書く人がドメインを分析する 毎日分析し、毎日コードを書く

コードを書くためにはクラスを見つけなければいけない 問題領域を分析することでクラスが見つかる 分析者 = 実装者 とならなければならない

モデルを見つけることとクラスを見つけることは一緒。人を別にしてはいけない。

ソフトウェアを立ち上げる時はフェーズと人を分けるけど、 保守フェーズでは分析と実装者が一緒。立ち上げ時もそれをやればいい。

ドキュメントを書いてからコードを書くという方法は大概無駄になる。

ドメインを学び学んだことをコードで表現することが大前提

ドメイン

ドメイン層はどこにも依存しない(プレゼン、アプリケーション、データベース) Springで実装

ドメイン層はPOJOフレームワークは導入しない。

ドメイン層のオブジェクト ドメインにGetter/Setterは使わない 業務の関心事の表現 知りたいこと 誰が、いつ、なぜ。。。 業務ルール 制約、閾値、手順。。。 業務ルールが破られた時の業務ルール

業務サービスの実行役 判断の結果 計算の結果 加工の結果 (基本データ型は返さない)

独自の型を作ることがドメイン指向設計

オブジェクト指向のメリット: コードの整理

クラス単位に関連するコードを整理する どこに何が書いてあるか特定しやすくなる 変更が飛び火しない - データと機能を分けると飛び火しやすい 変更した箇所のテストがOKなら全体もOK

アンチパターン:変更コストが高くなる設計

ふるまいを持たない、いわゆるデータクラス

データクラスがレイヤーを跨いで使われている

どこで使われているか特定しにくくなる

変更コストが下がる設計

役に立つクラスを作る(判断・加工・計算ロジックを持たせる) クライアントは使うだけ

オブジェクト指向ドメイン層の構造

主要な関心事をアグリゲートに組む

オブジェクト指向アーキテクチャ

構造

オブジェクトの集合体

強く関連する部品は集約する

アグリゲート同士は分散性を高め必要最小限につなげる

「変更」を前提にしたネットワーク構造

メタファ:LANアグリゲートとインターネット(全体)

工法

「変更」を前提にする

インクリメンタルに開発

少しずつ成長する全体

毎日変化させていく

オブジェクトの設計

独自の型を設計

オブジェクトのコラボレーションを設計

実現手段の隠蔽

独自の型を設計する

ドメイン層は独自の型だらけにする

独自の方=利用者の関心事

基本データ型=コンピュータの関心事

オブジェクトのコラボレーションの設計

契約による設計、責任駆動設計、擬人化。。。

結局は「オブジェクト」と「オブジェクト」が協力して設計することが大事

コラボレーションの設計原則

オブジェクト同士の契約(顧客と供給者の関係)を意識する

相手のことを深く知りすぎてはいけない

書籍:契約による設計

「契約による設計」

契約ってなんだ?技術者にはいいメタファじゃないよね

契約はビジネスルールの関心事。業務ルールの基本。

業務知識を学べば業務ロジックも契約による設計も学べて美味しい

オブジェクト指向:実現手段の隠蔽

Java標準の(コンピュータよりの)メソッドを徹底的に隠す

業務の関心事の表現手段として「不適切」

int string LocalDate => 値オブジェクトで包む

for while List => ファーストコレクションで包む

列挙型でswitchを減らす

事例の研究

「転職支援サービス」を例に

転職アドバイザ

求職者

求人

応募

スカウト

職務依頼

ドメイン層の隔離

初級

フレームワークと規約 貧血ドメインモデル

中級

ドメインロジックを(プレゼン層、アプリケーション層などから)ドメイン層に移動する

浅いリファクタリング

上級

知識豊富になったドメイン層の見通しを良くする

深いリファクタリング

主要な関心事(コア)の隠蔽

主要な関心事(コア)の抽象化

各層の実装

プレゼンテーション層

標準的なSplingの機能を使う

サービスをインジェクションする

サービス層

渡されたIDに対してデータをリポジトリから取得する

ドメインの型を受け取り、ドメインの型を返す

データソース層

SQL Mapperのインジェクション

SQLとオブジェクトをマッピング

ドメインの型を返す

メトリクス

ざっくり20ヶ月、100人月くらい

アグリゲートに対して10くらいのドメイン(平均なのであくまでイメージ)

ドメイン層のクラスの行数はだいたい100行くらいで収まっている

30行〜60行がほとんど

クラス数が1000~2000あっても、関心事が集約されているのでたいして困らない

ドメインオブジェクト「善い部品」

ドメイン駆動設計のEntityパターン:参照オブジェクト

Entityと呼ぶのではなく参照オブジェクトと呼んだ方がいい

主要な関心事への参照点

顧客との会話の語彙の起点となる

JPAの@Entity

ただのデータの入れ物クラス

テーブルと対応する

ドメイン駆動のEntityとは無関係(むしろ逆に位置する)

値オブジェクト

業務の関心事と基本語彙(日付、期間、数量、金額、単位...)

目的に特化して制約をかける

暗黙の業務ルールをコードで表現する

コードを読んで業務ルールがわかるようにする

ロジックを集約する

コードの重複がなくなり変更が楽になる

値オブジェクトの実装パターン

完全コンストラクタ

不変なオブジェクト

何もしないgetterはNG

例えば、求人者の転職回数というのは今後関心事となることが予想される。そういったものを値オブジェクト化するのは有効。

値オブジェクトの効果

コードにドメインの言葉が増える => コードが仕様を語れる

一覧オブジェクト(ファースクラストコレクション)

ListやSetをラップ

コレクションの操作はコードがごちゃごちゃしやすく、変更の副作用が多い

クラスとして独立させ、そのクラスに閉じ込める

一覧オブジェクト vs SQL問い合わせ

SQLの抽出条件を単純にし、微妙な抽出を一覧オブジェクトにやらせる選択肢もある

どちらのやり方が関心事をうまく表せられるか

メモリとトレードオフ

区分オブジェクト

場合ごとのルールを理解し表現する道具

列挙を有効活用しifやswitchを削減する(ポリモフィズム)

区分オブジェクトの効果

関心事の明示的なコード表現

複雑なif文の削除

どこに何があるかわかりやすくなる

区分の追加や削除時の変更の副作用が少ない

How より What でコードを記述する

業務の関心事を明示的に表現する

より業務に寄せたメソッド名にする

深い洞察に向かうリファクタリング

お客さんの要望からやりたいこと、関心事を洞察し、コードに反映させるようにリファクタリングをしていく

関心事をより強調されるようにドメインオブジェクトを捻出していく

オブジェクト指向設計の学び方

本やスライドで用語を学ぶ

実際にコードを書く

元の本やスライドを読みなおす

変更作業が学びの絶好のチャンス

既存コードを変更しながらコードを読んだ範囲、変更箇所の数、テストの範囲を意識

オブジェクト指向設計に書き換えてから変更してみる

変更の際にリファクタリング

既存のコードの設計と比較して成功を実感する

ドメイン駆動設計とは

ドメインを学び、学んだことをコードで表現すること

QA

Q: リポジトリトランザクションやロックするの難しくない?
A: 最近はトランザクションなしでの開発にチャレンジしている(現場はトランザクション使う)

Q: リポジトリから特定の値オブジェクトだけを取るのはあり?
A: 業務として必要であるのであれば全然あり。(ただし業務として成立している場合)

Q: コンストラクタは隠した方が良いか?
A: 隠したほうが良い。ファクトリメソッドで生成する考え方は推奨。

Q: DDDによって開発スピードが落ちないか?
A: ビジネスががらっと変わることはなく、既存のサービスをどんどん成長させていくケースがほとんどで、
ビジネスと開発に大きなスピードのギャップは生まれない。
開発スピードがでないのであれば、それを判断材料にオブジェクト指向を習得していくべき。

Q: ドメインエキスパートが不在、もしくはまだビジネス未成熟の場合どうすれば?
A: ドメインエキスパートなんてものは存在しない!ビジネスの全てを知っている人はいないので、技術者が積極的にキャッチしにいくべき。ドメインの知識をためていく。

2015年を振り返る

2015年も最後の日になってしまったので今年を振り返ってみようと思います。

Kawasaki.rbとの出会い

Kawasaki.rb | Doorkeeper

1月に参加した、神奈川Ruby会議の中でRubyの地方コミュニティとして紹介されていた、Kawasaki.rbに通い始めました。

Kawasaki.rbは文字通りれっきとしたRubyのコミュニティですが、土地柄からかWeb系でない人の参加も多く、Ruby以外の言語(Python,Julia,Go,Scala,etc...)に精通している人も多数おり、とてもバラエティに富んだコミュニティで、毎回参加しては刺激を受けることができました。そういえばDoorKeeperを遡ってみたら僕は今年の1月から12月まで全て参加している皆勤賞者でした。誰も言ってくれないので自分で言います。

Kawasaki.rbでは毎回誰かがLTをする時間が設けられており、とくにスライドがなくてもブログ記事などで軽く喋るくらいの空気感で良いので、自分も何度か発表させてもらいました。そういう意味ではここに来て自分のLT力が心なしか向上したような気がします。*1

また、Kawasaki.rbには公式ブログがありますが、#23から記事を寄稿するという形で微力ながらコミュニティに貢献させていただいています。

転職した

9月1日をもって新しい会社に移籍しました(3年ぶり2回目)

前の職はいわゆる受託系の会社で、Webをまともに開発したことの無い状態からRailsを触ったり、iOSアプリ開発、node.jsとMongoDBでスマホ向けゲームアプリのサーバサイドを開発したりと様々な仕事をやらせていただきました。

新しい職はスタートアップで、今は主にScalaを使って自社サービスを作っています。

これを作って欲しい!と最初から言われる受託系から、サービスを自ら考え物にしていきスピード感も違うスタートアップへの転職で、最初は発想の転換にとまどっていましたが最近ようやく慣れてきた気がします。

なお転職に興味ある方はこちらのエントリーもどうぞ

norizabuton.hateblo.jp

初めてのRubyKaigi

Rubyistを名乗っているくせにRubyKaigiに参加したことはなく、今年始めて参加してきました。

rubykaigi.org

Rubyの魅力はその言語だけでなく、周りをとりまくコミュニティによって強く支えられていると聞いていましたが、RubyKaigiに参加することでそれが実感できたかと思います。みんな本当にRubyが好きなのだなと。

参考: MINASWAN - Wikipedia, the free encyclopedia

なお来年は早速ScalaMatsuriもあるので今から楽しみですね:)

scalamatsuri.org

横浜道場スプリント! そして...

2年以上通っていたアジャイルサムライ横浜道場ですが、実際にアジャイルのプラクティスを実践しながら開発をするという「横浜道場スプリント!」に1年通して参加していました。

yokohama-dojo.doorkeeper.jp

Webの開発を一切やったことがないメンバー*2を交えながらなんとか動くアプリを実装し、12月の横浜道場忘年会で無事発表することができました。

そんな横浜道場ですが、悲しいことに今年をもって休止となりました。

takubon.hatenablog.com

アジャイルサムライ横浜道場は僕が参加した最初の勉強会で、よりアジャイルを深く知ること、アジャイルのコミュニティの広さを教えてくれましたし、何より現場を変えたいと強く思う人達と多く知り合えた素敵な場でした。心より感謝致します。

まとめ

今年成し遂げたことなんてあっただろうかと思いながら書き始めてみたら、様々なコミュニティにお世話になった、という形になりました。

とくに来年の豊富などを思いついているわけではありませんが、エンジニアとしてより一層成長するためにプライベートを有意義に使えればいいな、と思うしだいです。

*1:当者比

*2:経験はなかったが最終的に一番の功労者であった

技術勉強会『開発エンジニアが知っておくべきwebサービスの負荷対策』[TECH VALLEY#6] #tv6

2015年11月18日に開催された技術勉強会『開発エンジニアが知っておくべきwebサービスの負荷対策』に参加してきました。

geechs-magazine.com

進化の読めないシステムの負荷対策 @Sansan社

サービスの目的

運用しているサービス

  • Sansan 3000社利用
  • Eight ユーザ数100万人

Eightの裏側にある名刺データ変換の負荷対策について

  • 名刺のデータ化: 30万枚/日
  • 400万タスク/日
  • 累計名刺データ数1億万枚以上
  • 600万PV/日
  • 1億6000万PV/月
  • 常に1600人が同時に利用
  • ひとつのタスクは5秒で終わる

インフラ

  • Rails
  • S3
  • RDS
  • Redis
  • Redshift
  • CloudSearch

20 Servers/3RDS & 15 databases

システム課題

依頼枚数が増えていく

増えるタスク 各種処理のスケール

UI応答性能の維持、向上

スケーラビリティの確保

DBシャーディング 失敗 データはかなりの両たまることはわかっていた 蓄積したデータは特定の項目

シャーディングうまくいくはず → いかなかった

リリース後

1年でスロークエリ出始める

シャーディングいやだ

  • 項目で検索、集計したい
  • 1億のテーブルスキーマ変更辛い

データ化中のデータ

  • 頻繁に参照、更新したい

データ化完了のデータ

  • 検索、集計したい

ただしいストレージ選択

  • データ化RDS
  • 検索にはCloudSearch
  • 集計はRedshift

十分な情報集まらないなら作りこみしない

データ状態の変化と使われ方

RDBで億行は十分捌ける

microservicesして良かった

データ化は複数の工程

工程をワークフロー化

SimpleWorkflow

利点

  • ソフトウェアを小さくできる
  • 拡張、保守
  • DBを意味のある物理的に分割

スケーラビリティの確保でだいじなこと

  • とり得る手法は複数。何を選択するか
  • 大事なことは複雑にしないこと

UI性能維持、向上

やったこと: モニタリング、改善

普段やってること

クエリの把握

ORMの発行クエリなんだっけ

クエリ正しいか?

  • N + 1
  • インデックス

重たい複雑なクエリを分割

  • ID取得とデータ取得にわけるとか

ネクストキーロック

  • 更新対象行のみがロックされるわけではない

複合インデックスの順番

インデックス効いているかチェック

スロークエリ

  • 0.5sで監視
  • 1日で見た時の総処理時間が大きい物を優先

サービス応答性能のモニタリング

New Relic

  • 応答性能の異常検知
  • 異常時の詳細情報
  • 傾向の把握

これから

  • 無駄な通信の排除したい
  • 画面をシンプルに
  • キャッシュ
  • 画面の部分更新

まとめ

  • 正しく把握、設計、実装
  • 小さくシンプルに
  • SQLコツコツチューニング
  • サービス応答性能

Supership社 DSP 「ScaleOut」の成長と負荷対策

今日話すこと

DSPaspサービスの成長過程で起こったこと

DSPとは

  • 広告枠をオークション形式で購入する広告配信プラットフォーム
  • リクエストがとんでもなく多い
  • レスポンス速度の制約→0.1秒以内にレスポンス
  • ピークタイムは20~24時

インフラ

  • 配信にRDBは基本的に使わない
  • KVSを利用するのが一般的

インフラの変化

  • 全てオンプレ
  • 当初 配信サーバ48台
  • 現在 配信サーバ500台 + 集計サーバ150台

リクエスト数

  • 当初 8億/month
  • 現在 2000億強/month
  • 売上数十億/year

システム構成は当時と大して変わらない

  • 初期設計大事
  • 社長が元yahooでトラフィックさばいてた経験が生きた

サーバの熱問題

  • サーバ自作してた
  • 排熱性悪くcpuクロック悪化
  • サーバどうやって冷やすかを議論
  • 結論: 自作しない

オンプレだとサーバ急に足せない

  • 急なリクエスト増
  • 優先順位をつけて、売上に貢献しない処理から削る
  • 自分たちでサーバ負荷を減らす方法を用意しておく。SSPによっては管理画面からリクエストを止める
  • 優先順位が低い枠からオークションに参加する確率を下げる
  • ほぼ買えない枠や買っても広告効果を期待できない枠はCPU時間の無駄
  • 60msを超えたら処理を打ち切る
  • ほとんど配信されない案件にはペナルティを与える
  • 案件を無駄に登録出来ないように
  • 事前に案件の脚切りを行う
  • 特定のユーザは極力同じサーバで処理→キャッシュヒット率をあげる
  • 配信時の価格決定に必要な計算をシンプルに

集計系も時間かかる

  • Hadoop150台
  • Resource Managerで優先度に応じてqueueを分ける
  • 集計基盤に、サンプリングされたデータが入るテーブルも用意する
  • 概算だけ分かれば良いケースも
  • uu数を計算するためのサンプリングを用意する
  • ユーザをn個の集合に分割

まとめ

なぜ負荷対策重要?

  • 怠るとサービス止まる
  • 利用者が増えると負荷は勝手に上がるので定期的に対策が必要
  • 重要なのは対策に開発リソースを一定量以上とられないこと

競争力激しい

  • googleやFBとも戦わなければいけない
  • 開発リソースは新機能に使いたい。

GunosyGunosyの高負荷アクセスを支える技術

  • 2年前にGo言語を導入
  • 日本だとGoogleの次に導入した会社では
  • 既にGoで書いた負債返している段階

RailsからSinatra

  • Railsを用いたシンプルなWebサーバ群
  • ユーザは数十万人程度

インフラ

出来る限りサーバを小さく、コストをかけないように

  • DBに対するIOから疑う
  • メモリを効率的に
  • CPUを使い切れてるか
  • 同時コネクション受け入れられているか

キャッシュ

  • ページキャッシュ
  • DBキャッシュ

フレームワーク

  • RailsのオーバヘッドをSinatraを組み合わせてカバー
  • 場所によってはRackアプリを直接書く

基本的な対応でも通常の負荷は対応可能

TVCMとGoの導入

  • TVCMの開始
  • 大幅なUI変更 → ユーザが見れる記事数が数倍に、通知の配信頻度も増加
  • Rails/SInatra→ 1台あたり200req/sec、札束で殴った(インフラエンジニアいない)

短期間・小リソースで性能を向上させる必要性

Goの特徴

Nginx-luaHaskell, node,jsと比較した

高パフォーマンス

  • 安定性
  • Goroutineとchannel
  • CPU使いきれる
  • 比較的省メモリ

** 独立性の高さ * 依存関係は全て1バイナリ * クロスコンパイル良い

安定運用の実績

  • Einhornと組み合わせて安全に再起動
  • GoogleSoundcloudによる実績
  • 最近Githubのライブラリ急増

ひとつ上を行く負荷対策

プロセスキャッシュ

  • DBにアクセスをしないAPIが作れる
  • データフローに不整合が起きないように設計

ChannelをQueueとした非同期処理

  • Channelのキャパシティを利用
  • 直列化と処理効率の両立が可能に

Goとプロセスキャッシュについて

syncパッケージで競合防げる

GoroutineとChannelによる簡易MessageQueue

時間のかかる処理を非同期に、かつ直列に流していく

似非microservices

GunosyをPlatform化

  • 予測できない負荷
  • 機能ごとのに求められる要件が大きく変わる
  • 画面単位(機能単位ごと)で分割することに

Opsworkでの効率化

負荷対策大切なこと

目標設定大事 ボトルネックを見極めること ツールを見極めること→問題に突き当たる前に調査しておこう

まとめ

適切な技術を選び適切にスケールさせていこう

質疑応答

Q. Opsworks使ってて、コード乖離したときにどうしてるか、新機能デプロイ時に設定どう変えているか

  • ピーク時がわかっているのでそのタイミングにスタンバイさせている。CustomJsonにすべて設定持たせている

Q.シングルページアプリケーションにした方が良いのでは

  • Sansan: 今後の項目によっては考えていく。入力のパフォーマンスあげることは課題

Q シンプルなクエリであればRDSでも捌ける クエリのリファクタリングをしたのか、そもそも設計段階でシンプルだったのか

  • Sansan 最初からシンプルなクエリだった。AR使っているので非正規化もけっこうある

Q RailsをGOに移行するの大変じゃない?

  • Gunosy nginxの後ろにRailsとGO置いてた。少しずつ変えていたがE2Eテストあるのが理想。UIがないところはGoおすすめ。UIがあるならRailsやDjungoなど。Sessionの共有ちょっと大変だった。

Q Channellを使った通知だとプロセス間通信難しくない?Redisでやってみてるがコレジャナイ感

  • Gunosy: RabitMQやNSQueueというオープンソース使うのおすすめ。Dockerのリブチャンはプロセスまたいでアクセスできたかも

Q クエリ監視どうしてる?

  • Sansan スローログとAppの例外で頑張ってた。クエリのレビューはやってる。

Q Redshift高くない?予算の基準ある?

  • Sansan: 基準はないけど、名刺1枚あたりのコスト感でジャッジしてる。安定稼働に注力している。クオリティ、コスト、デリバリーの中ではコストが一番動かしやすい

Q どんなエンジニア求めてる?

  • SanSan: 全般的に求めてる。インフラからアプリから。
  • Gunosy: 全て、マネジメント含めて求めてる。Go書こうぜ!
  • ScaleOut: 一番緊急で欲しいのはデータマイニングエンジニア。オークションの最適価格決定したい。

Q 今の設計の正解をどのように導き出しているか

  • SanSan: 一人で考えない。チームでよく揉む。複雑な部分に違和感をもつ。
  • Gunosy: データフローをいかに構築するか。データの持ち方や配信を思考実験から。まずはサービスを作りきるところが大事では。
  • ScaleOut: 初期から大きく変えていない。問題が起こりつつあるログ転送にKafka使ったり、KVSは集約化した方が良いかもと思っている