generated at
freee Tech Night 「freeeにおけるモノリシック」

会計freeeのデプロイを10倍早くした話
SREチーム
アジェンダ
会計freeeのデプロイ
日に1,3回
使用料金が高い…
直列で
LBから抜く必要があるので並列デプロイできない
サーバー台数が多いと50minかかる
検討した選択肢
EKSへの以降
kubernetesを使える
モノリシックなものを移行したことはない
セキュリティ対策周りが弱かった
マイクロサービスを中心に本番運用したことある
サーバー台数2倍にする
イミュータブル・インフラストラクチャの実現
AWSがプロビジョンする時間がボトルネック
サーバー台数が希望数確保できる保証がない
アプリケーション・サーバーへのホットデプロイ
デプロイの中にあたらしいインスタンスを用意する
圧倒的に早い
Capistranoの資産を再利用できる
イミュータブル・インフラストラクチャからは遠ざかる
Unicornによるホットデプロイを選択
デプロイ、ロールバック時間
影響範囲の観測が少ない
モノリスへのアプローチ
課題
アプリケーション・サーバーを安全に入れ替えたい
完全検証が困難
対象ドメイン全体を把握するのが困難
アプローチ
プランBの確保
変更対象を理解する
Unicornのライブラリを理解
リクエストをさばくまでの流れ
リクエストをさばいているかの処理をチェック
パラメータの使われ方と影響範囲
forkの処理も合わせて抑える
PreloadによるFIle Descriptorの共有
Redisにリクエストを毎回おくる問題
各ワーカープロセス側でつなげる
段階的リリース
パフォーマンス劣化やバグを検知する仕掛けを多層で容易
テスト環境での負荷試験
負荷試験コトハジメ
インクリメンタルに負荷試験を行う
ほかサービスでのリリース
規模の小さいサービスで先行リリース
本番環境へのカナリアリリース
本番リクエストを2%程度
ngnixログからレスポンスタイムを集計
移行してどうだったか
25分 => 2,3分へ短縮できた
一部本番に流出してしまった問題
Redis connection, Releasesの消失
時間・規模が必要そうな事象は発見しづらい
リプレイテストの仕組みなど
Capistranoの面察を感じる日々
明らかに重くなったという部分はなくなった
今後
モノリスがEKSへ以降
モノリスの分割が進行中
自動カナリアリリースを準備中

データの構造から再検討するパフォーマンスチューニング
会計チーム
アジェンダ
freeeの監視周りについて簡単に
Slackに通知
ボトルネックのエンドポイント確認
Query
リアルタイム監視
redashにデータをあつめる
indexの効率
フルスキャン
実行回数
メール通知
最近始めた
DB周りのパフォーマンス改善
indexのチューニング
貼る必要がある
必要なカラムにindexを貼る
利用できていない
実行計画を見て適切なindexを利用できていないクエリの修正
なぜ漏れるのか
ActiveRecordのscopeを利用
仕訳modelと事業所modelとの関連がある
joinのときは事業所情報が入らないので改善前のクエリになる
注意していること
通常でやるか・ホットデプロイでやるか
無駄にindexをはらない
本番相当のデータで検討
クエリ変更でチューニング
対象データのrowが大きい
2000万行もある
rowをしぼってテーブルをクエリに加える
注意してること
テーブルのデータ増加の角度
クエリの結果が変わらないか
nullで減ってるときがある
アプリケーションの処理を入れる
データの持ち方の見直し
idではなくStringでjoin
関連のカラムを追加
マスタデータと共存する情報が存在する
UNION
ユーザ側にコピーしreadはユーザーデータのpみ
注意していること
マスタデータコピーのタイミング
大きくなってからだと修正コストが大
頻繁に変更するテーブルの場合
最初からクエリを分ける
テーブル構成の見直し
大量データを都度集計して表示している
集計テーブルを作成
圧縮率の高いテーブルを作成
画面上表示するパフォーマンスは上がる
新たな問題
登録時パフォーマンス劣化
ロックエラー
ギャップロックのロック待ち
データの不整合
対策
トランザクション
競合がおきないようにした
注意していること
集計テーブルのデータの切り方
登録時のコストが増える
集計データ表示のリアルタイム性を損なうのでユーザーへの告知
改善にはかなりの時間がかかる
機能の見直し
必要以上に実行されている可能性を疑う
集計データがHome画面アクセスで呼ばれる
全ユーザが必要とはしていない情報
対応
ユーザーアクションベースでの取得
非同期化
注意していること
ビジネスサイド(ユーザー)とのコミュニケーション
ユーザーメリットと運用個押すと
その他
Slaveへ逃がす
N+1の解消
bulletの導入
検索のElastic Search
まとめ
チューニングは適時実施
マスターデータとの共存は可能な限り、避けましょう
構成の見直しは早めにしよう

エンジニアがドメインロジックに集中するためのコアパッケージ整備
サービス基盤チーム
コアパッケージ
各サービスで共通して使われるパッケージ
アジェンダ
作成に至る背景
freeeにおけるサービスの変化
主要なサービスはRails
基本同じ構成
社内gemやOSSを使用
ファットなRails
デプロイ時間
コード全体の見通し
昨日の責任の境界が不明瞭
2018年マイクロサービス開発が進む
メモリフットプリント、学習のしやすさでGo
kubernetes強いひとが入社
サービスがどんどん出来た
Goのマイクロサービス
実装自体はサービスごとでバラバラな内容
モノリシックな問題を解決、それぞれで知見が溜まった
横のノウハウがあまりとれなかった
構成が若干違う気持ち悪さ
本来あるべき姿
ユーザに届けたい価値があって開発している
loggerやerrorも大事だが
各エンジニアがドメインロジックに集中できるようにする
使用策定、実装
機能の洗い出し
コードを全部読みドキュメント化
ヒアリング
気にかけた部分
contextを受け取れる場合、中継し後ろに渡している
異常系のときはerrorを返す、panic致命的な問題
goroutine safe
goのエコシステムを利用しているか
コアパッケージの作成
デファクトとしてのパッケージを作る
品質の保証と改修の恩恵を受けれるという意味でのデファクト
強制して使ってくれというものではない
利用者の技術剪定の余地は残す
拡張性
利用者側のユースケースで使えるように拡張性をもたせる
go-cloudを参考
HealthCheck pkg
簡単に組み込める
依存関係にある場所の解決は面倒
例:DBのコネクションを各パッケージに渡す
wireというパッケージを使う
wire
静的DIツール
パッケージから設定の値など依存にあたる部分を切り出して
あとから注入する
Provider
必要な引数(依存性)を受け取り返り値として特定の型を返す
基本的に入っている
Injector
Providerを組み合わせて依存関係を解決し、特定の型を返す
作成の改善点
使われていないものの最適解を見つけるのは難しい
迷わず作りきってFBをもらうのがよい
導入
アナウンス
Qiita Teamsにドキュメントを書く
チャンネルに告知を流す
Go好きには理解してもらえた
チュートリアルを作成
claatというツール
markdownでチュートリアル作成
課題
パッケージが多すぎてなにがあるかわからない
どういう利点があるか伝えられてない
使われるものを作れてなかった
対応
Godocを整備する
エンジニアが集まる場で宣伝して認知度をあげる
マイクロサービス委員会
freeeの独自の文化
マイクロサービスのデファクトとは何かを話し合う
感想や欲しい機能の話し合いをして方針をきめる
機能のデファクト方針ドキュメントを作成
エラー通知について
各チームの目標にのせる
Goのチームは8〜10
導入の目処は立ってきた
振り返り
散らばってたノウハウを吸い上げ
デファクトについて言語化
共通認識を作れた
既存サービスの基底を見直し。改善
爆速なマイクロサービス立ち上げができるように