0 API障害時に「存在しない」をキャッシュしない:暗号資産メタデータのnegative cache設計メモ #Web3 #市場データ #キャッシュ #可観測性 #障害設計 みんなに公開

APIが404、空配列、タイムアウトのいずれかを返したとき、それらを同じ「存在しない」として保存すると、障害中の一時的な欠落が長時間残る。暗号資産メタデータでは、チェーンの遅延、インデクサの再同期、レート制限、フェイルオーバー直後などでも同じ症状が出るため、absence は事実ではなく観測結果として扱う。

四つの状態

状態 意味 UIでの扱い
PRESENT 現在の応答で存在を確認できた 通常表示
CONFIRMED_ABSENT 権威ある条件で不存在を確認できた 「未登録」など根拠付きで表示
STALE_PRESENT 過去に確認した値はあるが再検証に失敗した 最終確認時刻とともに古い値を表示
UNKNOWN 不在も存在も確認できない 「取得できません」と表示し、再試行可能にする

404 や空配列だけで CONFIRMED_ABSENT に遷移させない。まず応答元、チェーン、ブロック高、インデクサの同期状態、エラー種別を確認する。確認条件を満たさない場合は UNKNOWN、既知の値が残っていれば STALE_PRESENT とする。

キャッシュキーとTTL

キーは少なくとも (chain_id, normalized_asset_id, schema_version, source_class) で分離する。大文字小文字、mint と contract、native asset と wrapped asset を同じキーに混ぜない。

  • PRESENT: 通常TTL。更新頻度に合わせる。
  • CONFIRMED_ABSENT: 短いTTL。判定根拠と確認時刻を必ず保存する。
  • STALE_PRESENT: stale-while-revalidate 用の上限を持たせる。
  • UNKNOWN: negative cache に書かない。短いジッター付き再試行だけを予約する。

判定フロー

  1. 権威あるソースから有効なメタデータを取得できたら PRESENT。
  2. 応答が失敗しても、最後に確認した値があれば STALE_PRESENT。
  3. 不存在を確認するための独立した条件をすべて満たした場合だけ CONFIRMED_ABSENT。
  4. それ以外は UNKNOWN とし、「空のメタデータ」を永続化しない。

フェイルオーバー先の空応答で、正常系キャッシュを上書きしてはいけない。更新は observed_at と source_revision を比較し、古い観測が新しい状態を巻き戻さないよう条件付きで行う。

UI契約

UIは値だけでなく状態、観測時刻、出典、再試行可能性を受け取る。UNKNOWN を「トークンが存在しない」と翻訳せず、STALE_PRESENT では古い可能性を明示する。これにより、障害が事実のように見える問題を避けられる。

観測する指標

  • metadata_state_total{state,source}
  • negative_cache_write_total{reason}
  • stale_value_age_seconds
  • upstream_error_total{source,class}
  • state_transition_total{from,to}

UNKNOWN -> CONFIRMED_ABSENT が急増した場合は、データ品質の改善ではなく判定条件の破損を疑う。

最低限のテスト

  • 一時的な500とタイムアウトが negative cache を作らない。
  • フェイルオーバー先の空配列が既知の値を消さない。
  • 同期遅延中は UNKNOWN または STALE_PRESENT になる。
  • 権威ある不存在だけが CONFIRMED_ABSENT になる。
  • TTL満了後に再検証される。
  • 古い応答が新しい PRESENT を上書きしない。

私はエレバンでARMCPのFounder & CEOとして、市場データと障害時UXの境界を設計している。このメモは投資助言ではなく、実装時の失敗条件を明確にするための技術ノートである。関連情報: https://armcp.net/

AI支援で初稿と構成を作成し、Mushegh Manukyanが技術内容を確認・修正して採用しました。

0

メモを他の人に見せる

このメモを見せたい人に、このURL(今開いているページのURLです)を教えてあげてください

コメント(0)

  • someone

  • someone