Real-scale validation post-G0: configurable ingest cap + workers_500k metrics
Validated G0 substrate against the production workers_500k.parquet dataset (18 cols × 500,000 rows). Findings + one applied fix: Finding #1 (FIXED): ingestd's hardcoded 256 MiB cap rejected the 500K CSV (344 MiB) with 413. Cap fired correctly, no OOM. Extracted to [ingestd].max_ingest_bytes config field; default 256 MiB, override per deployment for known-large workloads. With cap bumped to 512 MiB, 500K ingest succeeds in 3.12s with ingestd peak RSS 209 MiB. Finding #2 (deferred): ingestd doesn't release memory between ingests. Go runtime conservative; long-running daemon, fine. Finding #3: DuckDB-via-httpfs is healthy at 500K. GROUP BY 45ms, count(*) 24ms, AVG 47ms, schema introspection 25ms. Sub-linear scaling vs 100K — the s3:// read path is not a bottleneck. Finding #4: ADR-010 type inference correctly handled real staffing data. worker_id → BIGINT, numeric scores → DOUBLE, multi-line resume_text → VARCHAR. 1000-row sample sufficient. Finding #5: Go's encoding/csv handles RFC 4180 quoted-comma fields and multi-line quoted text without LazyQuotes — confirming the D4 scrum's dismissal of Qwen's BLOCK on this point. Net: substrate handles production-scale data with one config knob. No correctness issues, no OOMs, no silent type errors. All 6 G0 smokes still PASS after the cap-config change. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -31,10 +31,18 @@ type Config struct {
|
||||
// IngestConfig adds ingestd-specific knobs. ingestd needs to PUT
|
||||
// parquet to storaged AND register manifests with catalogd, so it
|
||||
// holds two upstream URLs in addition to its own bind.
|
||||
//
|
||||
// MaxIngestBytes caps the multipart body size. CSVs are typically
|
||||
// 4-6× larger than the resulting Snappy-compressed Parquet, so 256
|
||||
// MiB CSV → ~50 MiB Parquet — well under storaged's 256 MiB PUT
|
||||
// cap. Real-scale validation (2026-04-29) showed 500K workers ×
|
||||
// 18 cols = 344 MiB CSV → 71 MiB Parquet; bumping this knob to
|
||||
// 512 MiB is the documented path for that workload.
|
||||
type IngestConfig struct {
|
||||
Bind string `toml:"bind"`
|
||||
StoragedURL string `toml:"storaged_url"`
|
||||
CatalogdURL string `toml:"catalogd_url"`
|
||||
Bind string `toml:"bind"`
|
||||
StoragedURL string `toml:"storaged_url"`
|
||||
CatalogdURL string `toml:"catalogd_url"`
|
||||
MaxIngestBytes int64 `toml:"max_ingest_bytes"`
|
||||
}
|
||||
|
||||
// GatewayConfig adds the upstream URLs the reverse proxy fronts.
|
||||
@@ -106,9 +114,10 @@ func DefaultConfig() Config {
|
||||
Storaged: ServiceConfig{Bind: "127.0.0.1:3211"},
|
||||
Catalogd: CatalogConfig{Bind: "127.0.0.1:3212", StoragedURL: "http://127.0.0.1:3211"},
|
||||
Ingestd: IngestConfig{
|
||||
Bind: "127.0.0.1:3213",
|
||||
StoragedURL: "http://127.0.0.1:3211",
|
||||
CatalogdURL: "http://127.0.0.1:3212",
|
||||
Bind: "127.0.0.1:3213",
|
||||
StoragedURL: "http://127.0.0.1:3211",
|
||||
CatalogdURL: "http://127.0.0.1:3212",
|
||||
MaxIngestBytes: 256 << 20, // 256 MiB; bump per deployment via lakehouse.toml
|
||||
},
|
||||
Queryd: QuerydConfig{
|
||||
Bind: "127.0.0.1:3214",
|
||||
|
||||
Reference in New Issue
Block a user