SlideShare a Scribd company logo
indeed Indeed〜 実際のとこどうなの?Indeed さん! 〜
Toru Ochiai
Software Engineer @ Indeed Tokyo
自己紹介
自己紹介
● 東京理科大学工学部電気工学科卒
○ ちゃんと 4 年
● 中堅 SIer
○ 2.5 年
● 入社当時十数人だったネット系ベンチャー
○ 5 年
● 独立系受託開発会社
○ 3.5 年
● リクルート
○ じゃらんゴルフ開発 1 年
○ Indeed エンジニア 2 年
自己紹介
…は
いったん
置いておいて
自己紹介
唯一
重要な
キーワード
自己紹介
お っ ち ー
“otchy”
自己紹介
otchy
自己紹介
.net
Twitter
Qiita
.com
自己紹介
全部
ぼくです
Indeed
エンジニアの
一日
朝
● 9時〜11時の間に出社する人が多い
● スタンドアップミーティング
○ 昨日やったこと / 今日やること
○ 作業の調整
■ 「あ、そこんとこお互い関係あるね」「この後詳しく話
そうか」
○ 10 分で終了
● 早速コーディング
昼
● フリーランチ
○ いまのところ火・水・木の週3日
○ 月・金はガーデンプレイス周辺を散策中
● 最近の流行りは将棋とビリヤード
○ 他にも卓球、ピンボール、ぷよぷよ、マリカー、ラジコン
などなど
○ 要するに好きなことしてると
● がっつりコーディング
夕方
● 引き続きコーディング
● ウィークリーミーティング
○ 今週やったこと / 来週やること
○ ビール
○ 唯一の定例ミーティング - 1 時間 / 週
● ハッピーアワー
○ 毎週金曜 17 時頃からゆるりと
○ ビール
■ ビール以外のお酒、ソフトドリンクもあるよ
● 17時〜19時の間に帰る人が多い
Indeed エンジニアの一日
要するに
Indeed の
エンジニアは
Indeed エンジニアの一日
コーディングと
ビールから
出来ています
Indeed エンジニアの一日
じゃあ実際
どんなコード
書いてんの?
Indeed
エンジニアの
コード
Indeed エンジニアのコード
Indeed エンジニアのコード
…って
話じゃなくて
Indeed エンジニアのコード
● 超アルゴリズムなコードばかり?
○ そういうのもある
○ でも Web なんでバックエンドもフロントエンドもその間あ
たりも色々ある
● AB テストめっちゃする
○ 何でもデータで評価する
○ CEO ですらデータ出さないと周りが納得しない
● 基礎重要
○ “無駄に” 重いのはだめ
○ データ構造選びはきちんとね
● 何か課題があってそれをどう解決するかの繰り
返し
Indeed エンジニアのコード
具体例を紹介
…の前に
所属するチームの紹介
● カンパニーデータチームに所属
● Indeed の持つたくさんの会社情報を表示する
ページ
○ 概要・口コミ・写真・給与情報などなど
● それらのデータを Indeed 内の別チームに提供
する API
○ 検索結果に表示される口コミ評価など
所属するチームの紹介
● 会社情報ページ
所属するチームの紹介
● 会社情報 API
具体例1
ABテスト
具体例1:ABテスト
課題:最近追加した給与情報ページのアクセスを
増やしたい
答え:目立たせる!
本当の課題:どんなデザインが一番効果的か?
イケてるデザイナが考える??
否、AB テストが知っている!
具体例1:ABテスト
● グループ A:new! アイコン
具体例1:ABテスト
● グループ B:概要ページでチラ見せ
具体例1:ABテスト
● グループ C:サイドバーでチラ見せ
具体例1:ABテスト
● 結果 (給与情報ページの PV)
何も無し(既存)
グループA
グループB
グループC
具体例1:ABテスト
● 結果
○ A:new! アイコン → 8.86% PV アップ
○ B:概要ページチラ見せ → 4.24% PV アップ
○ C:サイドバーチラ見せ → 6.97% PV アップ
● new! アイコン採用!
…?
具体例1:ABテスト
● 結果 (給与情報ページの PV)
?
具体例1:ABテスト
● 結果
○ new! アイコン → 8.86% PV アップ
○ 概要ページチラ見せ → 4.24% PV アップ
○ サイドバーチラ見せ → 6.97% PV アップ
○ 全部乗せ → 97.14% PV アップ
● 当たり前の結果でもちゃんとテストする
○ 仮説に確信を持つため
○ 将来の決定に情報を残すため
■ 他の機能の都合上どうしても給与ページの露出を減
らす場合は?
■ 概要ページが一番インパクト少ない!
具体例1:ABテスト
● ちなみにこれ、実装、分析から世界中100% の
ユーザにリリースするまで、わずか 8 営業日の
出来事
○ 意志決定が早い
○ リリースが早い
○ AB テストフレームワークが早い
○ 分析ツールが早い
具体例1:ABテスト
スピード重要
具体例1:ABテスト
何度もテストを
繰り返し
最適解に近づく
具体例2
会社情報 API
具体例2:会社情報 API
● 検索ページのフロントエンド
フロントエンド
検索 API 会社情報 API認証 API などなど
フロントエンド
具体例2:会社情報 API
● 検索ページのフロントエンド
○ 複数のサービス (= API) に平行してリクエストを投げる
○ 全部の結果を待ってから情報をまとめて表示する
…と思うじゃないですか
具体例2:会社情報 API
(再び)
スピード重要
具体例2:会社情報 API
● 検索ページのフロントエンド
○ 複数のサービス (= API) に平行してリクエストを投げる
○ 全部の結果を待ってから情報をまとめて表示する
○ 最低限、検索結果さえあれば他の API のレスポンスは
そんなに待たない
○ 全体のスピードが全てに影響する
■ クリック率
■ SEO
○ サイトが “生きてること” も超重要
■ 仮に API サーバが落ちてもサイト自体は落ちない
具体例2:会社情報 API
● 通常の検索結果
関連会社情報
オートコンプリート
5つ星評価
ログインリンク
具体例2:会社情報 API
● 検索ページのフロントエンド
フロントエンド
検索 API 会社情報 API認証 API などなど
フロントエンド
タイムアウト
具体例2:会社情報 API
● 調子悪い時の検索結果
関連会社情報
表示されない
オートコンプリート
出来ない
5つ星評価表示されない
ログイン出来ない
具体例2:会社情報 API
課題:検索フロントエンドの要求に応じて会社の 5
つ星評価を 200msec 以内に返す
CPU 時間で見ると膨大な時間に見えるが…
1. ネットワークのレイテンシを含む
2. 評価値以外のメタデータも含めて返す
3. MAX 200 なので普段は 50 以下にしたい
4. 5000万件の会社情報から検索する
フツーにやったら間に合わない
具体例2:会社情報 API
● 答え1:MySQL (RDB)
○ フツーの Web っぽい。
○ 5000万件からの検索を数msec で返せるモンスタークラ
スタを用意する?
○ オーバースペック。却下。
● 答え2:mongoDB (NoSQL/KVS)
○ いまどきの Web っぽい。
○ 要するにディスク上に構築された巨大なハッシュテーブ
ルなので検索はまあまあ早い。
○ ネットワークオーバーヘッドが追加になる。
○ MySQL と平行してデータのメンテが必要。
○ 面倒くさい。却下。
具体例2:会社情報 API
そもそも
ディスクIO(~10ms)が
遅い
具体例2:会社情報 API
メモリ(~100ns)と
105
も
オーダーが違う
具体例2:会社情報 API
● 答え3:memcached (インメモリキャッシュ)
○ フツーの大規模 Web っぽい。
○ スピードは申し分ない。
○ キャッシュが無ければ通常速度。
○ 初回アクセス時は星が表示されない?
○ 惜しい!イケてない。却下。
● 答え4:インメモリ DB
○ 今ならありかも。
○ プロジェクト発足当時 (4 年前) に選択するにはアグレッ
シブ過ぎた。
具体例2:会社情報 API
Indeed の答え
具体例2:会社情報 API
意外なほど単純
具体例2:会社情報 API
● ソート済みの会社 ID 配列をメモリに持つ
○ static int[] CMP_ID_ARR = [1, 2, 3, … 5×108
];
○ 実際には永続化されてるデータを読んでる
● Java の int は符号付き 32 bit 整数
○ 5000万件でも高々 200MB
○ 4bytes × 50M = 200MB
● 1インスタンスに 256GB メモリ積む時代にケチ
ケチしない
○ 全てのインスタンスにこの int 配列を持つ
○ memcached サーバアクセスのオーバヘッドも無い
具体例2:会社情報 API
● 会社 ID 配列と同じ順で評価値配列を持つ
○ static float[] CMP_RAT_ARR = [3.2, 4.3, 3.8, ...];
○ 同じく全部メモリ上
● こういう関係
[ 1, 2, 3, … 1000 … ]
[3.2, 4.3, 3.8, … 3.4 … ]
か ら の
具体例2:会社情報 API
おもむろに
バイナリサーチ
具体例2:会社情報 API
● 会社 ID を見つけたら同じ index を参照
[ 1, 2, 3, … 1000 … ]
[3.2, 4.3, 3.8, … 3.4 … ]
● いくつかの主要メタデータは全部こう
[ 1, 2, 3, … 1000 … ]
[ a, b, c, … x … ]
具体例2:会社情報 API
難しい問題を
シンプルに解く
具体例2:会社情報 API
常にシンプルな
方法を考える
具体例3
ABテスト
フレームワーク
具体例3:AB テストフレームワーク
課題:アクセスしてくるユーザを複数のテストグ
ループにランダムに振り分ける
● 同じユーザはずっと同じグループ
● 数学的に (ある程度) 正しくランダム
● 違う種類のテストにおいて相関はなし
具体例3:AB テストフレームワーク
3つの要求を
満たす実装を
考えてみる
具体例3:AB テストフレームワーク
● 同じユーザはずっと同じグループ
○ 少なくとも各ユーザを識別するユニークキーが必要
● ログイン中のユーザ
○ ユーザ ID (=メールアドレス)
● 非ログイン中のユーザ
○ Indeed 全体で共有しているトラッキングクッキーの値
同じユーザの識別については問題なし
具体例3:AB テストフレームワーク
● 同じユーザはずっと同じグループ
○ ユニークキーごとにどのグループに所属しているか覚え
ておく必要がある
○ テストをリセットする時には過去のグループを削除して振
り分け直す
● しかし常時 100 以上のテストを実施
○ 1ユーザあたり 100 レコード保持?
○ 1億5000万ユーザ / 月いるのに?
具体例3:AB テストフレームワーク
● 数学的に (ある程度) 正しくランダム
○ 正しいシードを使って乱数を発生させる
○ 例えば、現在時刻 XOR hash(ユニークキー) とか
● 違う種類のテストにおいて相関なし
○ 乱数の使いまわしはせず、グループ振り分けを行う度に
異なる乱数を発生させる
○ 疑似乱数発生器が十分確からしくランダムなら、シード
の再設定までは要らない (はず)
● しかし常時 100 以上のテストを実施
○ 毎回 100 回以上も乱数発生させるの?
○ 1億5000万ユーザ / 月いるのに?
具体例3:AB テストフレームワーク
つまり
難しいのは
ここ
具体例3:AB テストフレームワーク
100テスト
1億5000万ユーザ
具体例3:AB テストフレームワーク
ここで再び
シンプルな方法を
考える
具体例3:AB テストフレームワーク
Indeed の答え
具体例3:AB テストフレームワーク
● 同じユーザはずっと同じグループ
○ ユニークキーごとにどのグループに所属しているか覚え
ておく必要がある
○ 100×1億5000万も覚えておかない
● 数学的に (ある程度) 正しくランダム
● 違う種類のテストにおいて相関なし
○ 正しいシードを使って乱数を発生させる
○ 乱数の使いまわしはせず、グループ振り分けを行う度に
異なる乱数を発生させる
○ そもそも乱数使わない
具体例3:AB テストフレームワーク
それで実現可能?
具体例3:AB テストフレームワーク
できます!
具体例3:AB テストフレームワーク
● 各テストごとにユニークな Salt を持つ
● ユーザのユニークキー×Salt のハッシュを計算
する
● ハッシュ値を 100 で割ったあまりをとる
● 0~49 → グループA、50~99 → グループB
hash(unique_key XOR test_salt) % 100
※だいたいの概念。本当はもうちっと複雑。
具体例3:AB テストフレームワーク
● 十分に “良い” ハッシュ関数があれば
○ ユーザのユニークキーが決定した瞬間に、ユーザのグ
ループは潜在的に決定済み
○ グループの振り分けは十分にランダム
○ 振り分けの計算は常に O(1)
○ Salt が変わればグループ分けに相関なし
○ あえて Salt を同じにすることで、異なるテストのグルー
プ分けをあえて同じにすることもできる
○ グループ分けの割合を変更した場合も、なんら再計算の
必要が無い
いいことづくめ!
具体例3:AB テストフレームワーク
難しい問題を
シンプルに解く
具体例3:AB テストフレームワーク
ちなみに
具体例3:AB テストフレームワーク
● このフレームワーク
● Proctor という名前でオープンソース化済み
http://indeedeng.github.io/proctor/
● AB テスト結果の分析に適したツールも
● Imhotep という名前で同じくオープンソース化済
み
http://indeedeng.github.io/imhotep/
結 論
エンジニアにとっての Indeed
取り組むべき
課題が
いっぱい
エンジニアにとっての Indeed
コードで解決
エンジニアにとっての Indeed
データで証明
エンジニアにとっての Indeed
めっちゃ
楽しい
Q & A
※ #askindeed で Twitter 検索すると質疑応答のおおよそが見れます

More Related Content

indeed Indeed - a presentation for Indeed なう -