Upgrade to Pro — share decks privately, control downloads, hide ads and more …

終了の危機にあった15年続くWebサービスを全力で存続させる - phpcon2024

yositosi
December 21, 2024

終了の危機にあった15年続くWebサービスを全力で存続させる - phpcon2024

〜Twilog・Togetter統合の舞台裏〜
by 吉田俊明、青山民人|トゥギャッター株式会社

Twilog https://twilog.togetter.com/
Togetter https://togetter.com/

yositosi

December 21, 2024
Tweet

More Decks by yositosi

Other Decks in Technology

Transcript

  1. 自己紹介
 吉田俊明 @yositosi
 2009年ヤフー在籍中に趣味でTogetterを開発、2010年会社化。経営も嗜みつ つ、エンジニアとしてコードもガンガン書いている。Twilogの移管に際してはかなり の部分のコードを書いている。
 2人の男の子の育児中
 青山民人(アオヤマ ミント) @MintoAoyama


    SIer・コンテンツ変換ソリューションのITベンチャー・モバイルゲーム会社などを経 て、2015年にTogetter社に入社。以降、Togetterのインフラをほぼ1人で見てい る。
 最近はモータースポーツ観戦や YouTube Live での音声配信が楽しい 

  2. フェーズ0:ドメインのみ統合 
 • 2023年4月にTwilogの Twitter API が停止 
 • 早期に復旧させるため、ログイン機能の回復を試みる


    • 専用のログイン機能をTwilog側に提供し、Twitterのアクセストーク ンを安全に交換する仕組みを実装
 • twilog.org から twilog.togetter.com に切替・リダイレクト
 • 5月末に復活 👏

  3. Twilog 統合前(2023年4月時点)のシステム構成 
 「さくらの専用サーバ PHY 」* 2 … 月額 6万円

    程度 
 • 物理専有ホスティングサービス
 ◦ スペックに対するコスパは良い
 ◦ クラウドサービスほど柔軟な課金体系ではない
 • スペックとソフトウェア構成
 ◦ 8コア 1CPU / 32GBメモリ / 7TB SSD / 100 Mbps
 ◦ Apache + Ruby (rbenv) + MySQL MyISAM
 ◦ MySQLレプリカを含め、合計2台稼働
 • 合理的かつシンプルな印象

  4. 6TB超・32GB mem の MySQL を AWS に移すと? 
 storage だけでざっくり見積もっても

    月間
 • Aurora Standard … 720 USD = 約 11万円
 • 汎用 SSD (gp3) … 576 USD = 約 9万円
 • スループット最適化 HDD (st1) … 324 USD = 約 5万円
 • S3 標準 … 150 USD = 約 2.3万円
 compute でざっくり見積もると 更に 月間
 • Aurora RDS(db.r7g.xlarge) … 354 USD = 約 5.4万円
 • EC2(t4g.2xlarge / reserved)… 150 USD = 約 2.3万円

  5. フェーズ1:アプリケーションコードを統合 
 • AWSにそのまま移行するとコストが月6万円から数十万円超に増 えることが予想
 • まずはAWSから さくら に対してDB接続することを検討
 •

    Rubyを全てPHPに書き換え Togetterの一部 として稼働
 Togetter Twilog(旧) Twilog(フェーズ1) 運用環境 AWS さくら専用サーバ AWS 言語 PHP Ruby PHP データベース Aurora(MySQL) MySQL MySQL DBサーバ AWS さくら専用サーバ さくら専用サーバ
  6. フェーズ2:データベース移行の課題 
 • メンテ時間を最小にしながら、破損なくデータを移行できるか
 • 6TBを超える15年に渡り溜め込まれたツイートのログを Aurora に 移行するとストレージ料金も嵩み、月数十万に
 ◦

    RDS for MySQL を選択しても大きくは変わらない
 • Twilogのツイート検索はMyISAMの全文検索機能に依存していた が、AuroraのストレージエンジンはMyISAMを非サポート

  7. フェーズ2:AWS↔さくら間でのレプリケーション 
 sqldump の “生成・転送” をより速くするために
 • mydumper + pzstd

    で作成!
 ◦ 並列処理でより速く、圧縮でより(サイズを)軽く
 ◦ 動作しない場合は mysqldump などもオススメ
 • 「さくら → EC2 → Aurora」と経由して転送する
 ◦ 転送元のグローバルネットワーク帯域を使い切るか増やす
 ◦ ローカルネットワーク上の別マシンを活かしてもいい
 ▪ 対象ファイルを分割・並行転送で倍近くに改善👍

  8. フェーズ2:AWS↔さくら間でのレプリケーション 
 sqldump の “生成・転送” をより速くするために
 • EC2 及び Aurora

    のスペックを “盛れる” だけ “盛る”
 ◦ vCPU / メモリ / EBS / ネットワーク帯域 など
 • サイズ・スペックによっては全工程が長期に及ぶこともある
 ◦ 可能な限りスクリプトで自動化する
 ▪ 進行状況、異常発見のためのロギングも必要
 ◦ 処理が停止した時のために途中再開可能にする
 ◦ 一つ一つの処理を極力早く終わらせるために工夫を重ねる

  9. フェーズ2:ストレージコスト増大に対する対策 
 • 案1:S3にログデータをテキストとして保存し、S3 Selectを使って全 文検索を実現
 ◦ 事前の予測でS3 Selectのコストが月に数百万円になる想定のためNG
 •

    案2:S3にログデータをテキストとして保存し、ローカルでgrepなどを 用いて全文検索を実行する
 ◦ 実装は可能なもののデータの取り扱いが不便
 • 案3:S3にログデータをSQLiteでユーザ毎に保存し、SQLiteの全文 検索機能を利用
 ◦ データの巨大なユーザでも高速に全文検索可能で、RDBの機能も活用できる

  10. フェーズ2:SQLiteの採用を決定 
 • 1ユーザ、1SQLiteファイルとし、100万を超えるユーザ分のSQLiteを 全てS3上に設置することに
 Togetter Twilog(旧) Twilog(フェーズ2) 運用環境 AWS

    さくら専用サーバ AWS 言語 PHP Ruby PHP データベース Aurora(MySQL) MySQL Aurora(MySQL)+ SQLite DBサーバ AWS さくら専用サーバ AWS
  11. フェーズ2:MySQLからSQLiteへの変換 
 • Twilog全体をSQLiteに変換するには数日かかる
 ◦ Twilog全体を止めずに可能な限り最小の時間で本番を切り替えたい
 ◦ どのユーザのどのレコードにCRUDが行われたのか、MySQLだけから検知す るのは困難
 ◦

    旧Twilog側のユーザレコードに、last_update_atを追加してもらい、何か更新が 発生したらこの値を更新してもらう実装を依頼
 ◦ そこの値を常にチェックして、更新が入ったユーザのSQLiteを再生成するプロ セスを実行して、常に最新が取り込まれるように

  12. フェーズ3:SQLite + MySQL “Cache” 戦略へ 
 • SQLiteはマスターデータとして残しつつ、さらにMySQL(MyISAM)を 各サーバのローカル環境に立てて、そこをCache&全文検索エンジ ンとして利用


    • SQLiteのSync機構に追加して、ローカルのMySQLにCacheを非同 期にCacheを展開する機能を実装
 ◦ SQLiteに対して直接クエリーを投げないので、先の全文検索が 正しく動作しない問題は解消
 ◦ ローカルに設置してあるMySQLからデータを取るのでレスポン スタイムも早い

  13. フェーズ3:Twitter (X) API v2 対応 
 • 開発中に Twitter(X)API v1.1

    の廃止がアナウンスされたため、並 行してTogetter / Twilog の API v2 対応を実施
 • 一部のAPIが廃止になるなどしていたため、仕様変更などにも対応

  14. フェーズ3:デプロイ(2024年3月) 
 
 • Twitter (X) API v 1.1 の終了が月末に予定されていたため、旧

    Twilogは事実上動作しなくなり、タイムリミットとなる
 • 高速にデプロイするために「ハイスペックなインスタンスを用意して、 そこでCacheの生成を行って都度rsyncする」などのテクニックを要す る
 ◦ lsyncd (GitHub) … inotify や fsevents などを活用して「目的の ファイルに対する更新」をリアルタイム検知し、「任意の処理を実 行できる」仕組み

  15. フェーズ4:SQLiteの廃止 
 • Twilogの移行は完了したものの、内部的な課題が残る
 ◦ SQLiteのマルチマスター機能は動作しているものの、複数台構成での本番適用がで きていなかった(壊れる可能性が否定できない)
 ◦ 結果、ハイスペックなサーバ1台でWebとDBを兼ねて動作させている状態 


    ▪ ソースコードデプロイの際も瞬断が避けられない状態に
 ◦ 高いサーバコストと高負荷に弱い状態になっており、良い状態ではなかった 
 • Cache 用 MySQL が安定して動作していることを確認
 ◦ Cache的に導入した MySQL on EC2 が、速度・検索性能の面で問題ないことが明ら かになった(ページキャッシュが無くても十分速い!)
 ◦ Cacheの役割から昇格しMasterへ、SQLiteを破棄することに 

  16. フェーズ4:MySQL on EC2(MyISAM)の運用 
 • Writer + Reader の2台構成
 •

    Reader は定期的に物理バックアップ
 ◦ レプリケーションの一時停止
 ◦ /var/lib/mysql 配下を zstd 圧縮 + s3 転送
 • Writer 側の binlog も定期的に s3 バックアップ
 
 ⇒ TB(テラバイト)級のストレージ利用は実現できるのか? 

  17. 大容量ストレージによる MySQL を d3 / d3en で 実現 
 d3

    / d3en には大容量HDD(最小 6TB 、最大 336TB)がインスタンス ストアとして付属する!
 • 今回は d3en.xlarge (28 TB / 4vCPU / 16GiB)を選択
 ◦ 一定期間の binlog を保持して半分程度の使用率
 ◦ リザーブドなら 月額 4.6 万円 程度 と現実的
 • 複数に分割して提供されるので RAID0 などで利用
 ◦ 耐障害性がないが、再起動で揮発するインスタンスストアとは 相性が良い(?)

  18. フェーズ4:SQLiteの廃止 
 • キャッシュ用途から独自運用のMySQL(マスター)へと昇格
 • Togetterが動作しているサーバでTwilogも動かす
 • サーバも共有になり実質のWebサーバ費用がゼロに
 Togetter Twilog(旧)

    Twilog(フェーズ2) 運用環境 AWS さくら専用サーバ AWS 言語 PHP Ruby PHP データベース Aurora(MySQL) MySQL Aurora(MySQL)+ MySQL on EC2 DBサーバ AWS さくら専用サーバ AWS
  19. フェーズ4:事前の負荷テスト 
 • 新Twilogで処理しているリクエストを Mirroring して、フェーズ4環境 (Togetter本番)に直接流し込みテスト
 ◦ Mirroring は

    nginx の post_action で実現
 • TwilogおよびTogetterがそれらのリクエストを受けても、正常に動作 することを事前に確認
 • 安心して環境切り替えが可能に

  20. 反省点
 • AWS↔さくら間の通信コストの見積もり
 ◦ データを取得しにいく処理のコストをデプロイ前に検証、可能ならもっと前もっ てテストし現実的かどうか確認しておくべき
 ◦ サーバ間のレイテンシーだけでなく、クエリー結果が大きい場合にどの程度の 遅延になるかも見ておくべきだった
 •

    SQLiteの採用
 ◦ ストレージコストが安いS3を利用したいという思いが強すぎて、SQLiteを諦め るという発想ができなかった
 ◦ 複雑さが増しているにも関わらず、技術や運用でカバーできるという過信があ り、判断を鈍らせた