【要約】Turso の「stream not found」で本番が静かに落ちた話 [Zenn_Python] | Summary by TechDistill
> Source: Zenn_Python
Execute Primary Source
// Problem
開発者が、FastAPIのパフォーマンス向上のため、Tursoへの接続を@lru_cacheでキャッシュした。しかし、この設計がTursoの仕様と衝突し、本番環境で深刻な問題を引き起こした。
- ・TursoのHranaプロトコルは、アイドル後にサーバー側でストリームを切断する。
- ・Python版libsqlには、切断されたストリームを自動で再接続する機能がない。
- ・/healthzがDB接続を確認していなかったため、Cloud Runが異常を検知できなかった。
- ・結果として、APIが500エラーを返し続ける「静かな障害」が発生した。
// Approach
開発者は、接続確立のオーバーヘッドを抑えつつ可用性を確保するため、接続層に自己回復ロジックを組み込んだ。ストア自体はキャッシュし、エラー発生時のみ再接続を行う手法を採用した。
- ・is_hrana_stream_error関数で、エラーが"stream not found"かを判定する。
- ・_retryメソッドを実装し、エラー検知時に_reconnectを実行する。
- ・再接続後、1回だけリトライを行う設計とした。
- ・これにより、SQL実行前のネットワーク層でのエラーに対処した。
// Result
開発者は、この実装により、ストリーム切断によるリクエスト失敗を自動的に解消した。これにより、システムの安定稼働を実現した。
- ・ストリームエラー発生時に、自動で新しい接続が確立されるようになった。
- ・接続確立のコストを最小限に抑えつつ、ステートフルなプロトコルの制約を克服した。
- ・ヘルスチェックの粒度に関する重要な教訓を得た。
- ・今後は、ヘルスチェックにDB接続確認を含める改善が検討されている。
Senior Engineer Insight
> ステートフルなプロトコルを扱う際、接続の「寿命」を考慮しない設計は致命的である。SQLite互換であっても、ネットワーク越しでは挙動が大きく異なる。特に、自動再接続機能のないライブラリでは、アプリ層での防御策が必須だ。また、ヘルスチェックが依存リソースの状態を反映していない点は、運用上の大きなリスクである。監視の死角をなくすため、ヘルスチェックの設計にも細心の注意を払うべきだ。