AI SREClickHouse Workshops

07 Uji, gagal, dan perbaiki

Catatan instruktur untuk modul 07 — waktu, alur pembicaraan, kegagalan umum, dan langkah reset.

Your computer
macOS terminal: Run workshop commands in Terminal using zsh or bash.

Pendamping fasilitator untuk pelajaran pembelajar 07 Uji, gagal, dan perbaiki.

Waktu

Sekitar 20 menit. Ini lab insiden; lindungi cukup ruang agar diagnosisnya mendarat sebelum modul 08 dan penutup. Lab menjalankan fault 01 (diagnosis 5-15 menit). Fault 02 (5-10 menit) dan 03 (10-20 menit, dan hanya dengan dataset penuh sekitar 30 juta baris) tetap tersedia sebagai insiden tambahan opsional untuk ruangan yang cepat. Tetapkan hard-stop saat gladi bersih agar penutup tidak terhimpit.

Alur pembicaraan

  • Ini bagian hasilnya: gunakan semua yang dibangun sejauh ini untuk menjalankan insiden nyata.
  • Deskripsikan gejalanya, bukan penyebabnya, dan biarkan agen bertemu jawaban dari telemetri.
  • Pertimbangkan menampilkan diagnosis beberapa peserta bersebelahan di proyektor.
  • Lab menjalankan fault 01. Jika waktu memungkinkan satu ronde tambahan, tambahkan fault 02 (dan fault 03 hanya ketika dataset penuh sudah di-seed sebelumnya); gunakan reset stash-and-switch bersama di bawah di antara fault.

Kunci jawaban

Jangan bagikan bagian ini kepada pembelajar; bagian ini hidup hanya di playbook dan tidak pernah dicommit ke repo aplikasi. Setiap fault adalah satu perubahan kecil di branch-nya sendiri dari build-workshop-v1; perbaikannya adalah membalikkannya. Jalankan satu fault sekali waktu. Insiden lab ini adalah fault 01 (5-15 menit, curveball — backend tidak bersalah). Tambahan opsional untuk ruangan yang cepat: fault 02 (5-10 menit, pemanasan, trace menjelaskan semuanya) dan fault 03 hanya ketika dataset penuh tersedia (10-20 menit, penalaran ClickHouse yang lebih dalam).

Reset bersama untuk setiap fault (stash mempertahankan hasil edit peserta dan menghindari pergantian branch yang terhalang):

git stash push --include-untracked -m "module-07-fix"
git switch build-workshop-v1
docker compose --env-file .env.workshop \
  -f docker-compose.workshop.yml -f docker-compose.otel.yml up -d --build

Fault 02 — zone stats 500 (fault/02-zone-stats-500)

Pesan commit yang dilihat peserta: "backend: align zone stats column names with API params" (hanya menyentuh zone_stats_sql di backend/app/query_builders.py). Ia mengelompokkan berdasarkan pickup_zone_id, kolom yang tidak ada di taxi_trips, alih-alih pickup_location_id.

  • Gejala: choropleth pada peta kosong (poligon ter-render, tapi setiap zona berada di bucket paling terang) dan caption "Query Nms" hilang; ledakan 500 pada GET /api/metrics/zone_stats (React Query mencoba ulang tiga kali). Semua kartu lainnya normal.
  • Di mana sinyalnya: span clickhouse.query di ClickStack dengan error=True, error.category="query_failed", dan db.statement yang memuat pickup_zone_id AS zone_id; exception yang terekam adalah ClickHouse Code 47 UNKNOWN_IDENTIFIER. Log ERROR yang cocok: "ClickHouse query failed (category=query_failed, elapsed_ms=...): ... | sql=...".
  • Jalur diagnosis: temukan span 500 -> baca db.statement -> UNKNOWN_IDENTIFIER pada pickup_zone_id -> DESCRIBE taxi_trips (atau bandingkan query builder sekerabat) -> kolom yang sebenarnya adalah pickup_location_id.
  • Perbaikan: ubah pickup_zone_id kembali menjadi pickup_location_id di zone_stats_sql (atau git revert commit fault-nya); build ulang backend.
  • Reset: reset bersama di atas.

Fault 03 — dashboard lambat (fault/03-slow-dashboard)

Pesan commit: "backend: window the trend series by bucket in HAVING" (menyentuh timeseries_sql). Ia memindahkan predikat jendela waktu dari WHERE ke HAVING pada alias bucket, sehingga WHERE menjadi 1. ClickHouse tidak lagi bisa memangkas berdasarkan primary key (car_type, pickup_datetime) dan memindai penuh taxi_trips dengan dua state quantileTDigest, melewati max_execution_time 5s.

  • Gejala: hanya kartu tren "What's happening now?" yang gagal — ia berputar, lalu menampilkan "504 Query timed out...". Setiap kartu sekerabat tetap cepat.
  • Di mana sinyalnya: span clickhouse.query dengan error.category="timeout", db.elapsed_ms sekitar 5000, dan db.statement menampilkan WHERE 1 ... GROUP BY ts HAVING ts >= ...; exception-nya adalah Code 159 TIMEOUT_EXCEEDED. Kontrasnya dengan span 200 yang cepat pada endpoint lain adalah petunjuknya.
  • Jalur diagnosis: satu kartu lambat di antara kerabat yang cepat -> buka span timeout -> baca SQL-nya -> filter waktu ada di HAVING dan WHERE tidak punya rentang pickup_datetime -> sebuah anti-pola pemangkasan primary key / predicate pushdown (kerabatnya menaruh jendela waktu di WHERE).
  • Perbaikan: kembalikan jendela waktu ke WHERE (balikkan commit fault-nya); build ulang backend.
  • Reset: reset bersama di atas.
  • Catatan untuk instruktur: tingkat keparahan berskala dengan volume data dan ukuran service. Pada dataset penuh yang di-seed (~30 juta baris) di service tier workshop (yang mungkin baru bangun dari idle), timeout 5s menyala secara andal; pada seed sampel kecil ia hanya lebih lambat, bukan 504 keras. send_receive_timeout di klien dan max_execution_time di server keduanya 5s, jadi perlombaan socket-timeout kadang bisa muncul sebagai 500 alih-alih 504 yang bersih — itu sifat dari setelan baseline, bukan dari fault-nya.

Fault 01 — peta tidak memuat (fault/01-map-not-loading)

Pesan commit: "frontend: serve map geojson from /static asset path" (menyentuh path fetch di frontend/src/ui/ZoneMap.tsx). Ia mem-fetch /static/taxi_zones.geojson, yang tidak ada. Nuansa kunci: fallback SPA di nginx (try_files ... /index.html) mengembalikan HTTP 200 dengan dokumen HTML alih-alih 404, jadi r.ok lolos dan r.json() melempar SyntaxError seperti Unexpected token '<'.

  • Gejala: kartu peta mati — base tile ter-render tapi tidak ada poligon NYC atau choropleth, dan muncul error inline berwarna merah. Sisanya normal.
  • Di mana sinyalnya: tidak ada apa pun di ClickStack backend — aset itu tidak pernah mencapai FastAPI. Console browser menampilkan error parse JSON yang menyebut /static/taxi_zones.geojson; tab Network menampilkan request itu mengembalikan text/html dengan status 200; log akses nginx menampilkan fallback-nya.
  • Jalur diagnosis: trace backend bersih -> pindah ke console / tab Network browser -> sebuah request .geojson mengembalikan 200 text/html -> kenali jebakan fallback SPA -> file-nya sebenarnya berada di web root, /taxi_zones.geojson.
  • Perbaikan: balikkan path fetch (dua baris) atau git revert commit fault-nya; build ulang frontend.
  • Reset: reset bersama di atas.
  • Poin ajar: tidak setiap kegagalan muncul di trace backend, dan 404 bisa menyamar sebagai 200 di balik fallback SPA — jadi baca body respons dan content-type yang sebenarnya, bukan hanya kode statusnya.
  • Catatan (SDK browser): dengan SDK browser HyperDX aktif (overlay modul 05), frontend sekarang memunculkannya di ClickStack sendiri — kegagalan parse ZoneMap terekam sebagai span console.error di bawah ServiceName=nyc-taxi-frontend, berpasangan dengan span resource untuk 200 text/html itu. Jadi agen bisa melokalisasinya dari telemetri tanpa meninggalkan ClickStack; console / tab Network browser adalah cadangan, bukan satu-satunya jalan.

Contoh respons agen (fault 01, via ClickStack MCP):

Analisis akar masalah oleh agen untuk fault 01: ia menyebut /static/taxi_zones.geojson yang hilang mengembalikan index.html SPA sebagai 200 text/html, error parse JSON ZoneMap yang terekam sebagai span console.error nyc-taxi-frontend, membandingkannya dengan span /api dan backend yang sehat, menandai error self-test SDK sebagai derau, dan mengusulkan mengirimkan aset itu atau mengamankan proses parse

Diagnosis yang diharapkan: agen mengaitkan kegagalan itu dengan request geojson yang mengembalikan 200 text/html (fallback SPA), error JSON.parse yang timbul dan terekam di bawah nyc-taxi-frontend, lalu merekomendasikan mengirim aset itu ke /static/ atau mengamankan proses parse .json().

Kegagalan umum

  • Baseline telemetri tidak cukup bagi agen untuk melokalisasi; modul 05 harus sudah berjalan lebih awal.
  • Peserta melompat ke perbaikan sebelum memastikan akar masalah dari bukti.
  • Gejala fault belum terlihat karena stack baru saja dijalankan — atau, untuk fault 03, karena data historis yang dimuat terlalu sedikit. Terukur pada dry run: pada seed satu bulan default (~3,17 juta baris) fault WHERE-vs-HAVING tidak teramati — pemindaian penuh berjalan dalam ~300-560ms, tidak bisa dibedakan dari baseline. Seed beberapa bulan sebelum mendemokan fault 03, atau tetap pakai fault 01 (yang langsung tereproduksi) dan perlakukan fault 03 sebagai ilustrasi pada skala besar.
  • Fault 01 sama sekali tidak menghasilkan trace backend, dan request yang salah mengembalikan 200 text/html via fallback SPA alih-alih 404; peserta bisa mencari di trace tanpa akhir. Dorong mereka ke console / tab Network browser, tempat error parse JSON dan respons text/html terlihat.
  • Lupa --build setelah checkout branch fault, sehingga image lama tetap berjalan.

Langkah reset

  • Reset stash-and-switch bersama memulihkan aplikasi secara lengkap tanpa membuang upaya perbaikan seorang peserta.
  • Suntikkan ulang sebuah fault dengan checkout salah satu dari fault/01-map-not-loading / fault/02-zone-stats-500 / fault/03-slow-dashboard dan build ulang dengan file compose workshop plus otel.
  • Gejala, sinyal, dan perbaikan per fault ada di bagian Kunci jawaban di atas. Simpan kunci jawaban hanya di playbook ini; kunci itu tidak pernah dicommit ke repo aplikasi.

Di halaman ini

ID