본문으로 건너뛰기
cccskills
무료GitHub에 공개

starrocks-stream-load

StarRocks Stream Load — HTTP PUT API (curl/Python requests), CSV/JSON format parameters (column_separator/jsonpaths/strip_outer_array), columns mapping, partial_update for Primary Key tables, label idempotency, max_filter_ratio, timeout tuning, merge commit mode (3.4+), response JSON parsing, Python bulk loader pattern, error diagnosis

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ivanshamaev/de-agent-skills스타 22(GitHub 22 + cccskills 0)

실행 점수 미검증

설치 방법 보기

포함된 파일(1)

  • SKILL.md11.9 KB

SKILL.md(원문)

설치하기 전에 에이전트에게 전달되는 지시 내용을 확인할 수 있습니다.

StarRocks Stream Load

When to Use

  • Micro-batch loading from application code (Python/Java/Go)
  • Loading files from local disk or streaming buffers
  • Real-time CDC sinks with upsert/partial update semantics
  • ETL step that produces data in memory and needs to push to StarRocks
  • Alternative to COPY INTO for simple push-based ingestion

Not for: large S3/HDFS file ingestion (use Broker Load) or Kafka continuous ingestion (use Routine Load).


Core Concepts

Stream Load uses an HTTP PUT request directly to the FE (or BE) node. The request body is the data payload (CSV or JSON).

Client → PUT /api/{db}/{table}/_stream_load → FE → BE tablets
  • Transactional: commit or rollback atomically
  • Synchronous: response arrives after data is committed
  • Label: unique string per load for idempotency (retry-safe)

Basic CSV Load

# Load CSV from file
curl --location-trusted \
  -u root:password \
  -H "label:order_load_20240115_001" \
  -H "Expect:100-continue" \
  -H "column_separator:," \
  -H "columns:order_id,customer_id,amount,created_at" \
  -T /data/orders_20240115.csv \
  -XPUT \
  "http://fe-host:8030/api/sales/orders/_stream_load"

CSV with Custom Separator

# Tab-separated
curl ... -H "column_separator:\t" ...

# Multi-char separator (up to 50 bytes)
curl ... -H "column_separator:|" ...

# Null value representation
curl ... -H "null_values_indicator:\N" ...

JSON Load

Single JSON Object Per Line (NDJSON)

curl --location-trusted \
  -u root:password \
  -H "label:json_load_001" \
  -H "Expect:100-continue" \
  -H "format:json" \
  -H "jsonpaths:[\"$.order_id\",\"$.customer_id\",\"$.amount\"]" \
  -H "columns:order_id,customer_id,amount" \
  -T /data/orders.ndjson \
  -XPUT \
  "http://fe-host:8030/api/sales/orders/_stream_load"

JSON Array (Strip Outer Array)

# Input: [{"id":1,"val":"a"},{"id":2,"val":"b"}]
curl ... \
  -H "format:json" \
  -H "strip_outer_array:true" \
  -H "jsonpaths:[\"$.id\",\"$.val\"]" \
  ...

JSON with Computed Columns

# Map JSON fields to table columns with expressions
curl ... \
  -H "format:json" \
  -H "jsonpaths:[\"$.ts\",\"$.user_id\",\"$.amount\"]" \
  -H "columns:ts_str,user_id,amount,ts=str_to_date(ts_str,'%Y-%m-%dT%H:%i:%s')" \
  ...

All Key Headers Reference

HeaderDefaultDescription
label—Required. Unique load label for idempotency
column_separator\tField delimiter for CSV
row_delimiter\nRow separator for CSV
columnsall columnsColumn mapping / computed expressions
where—Filter rows to load
formatcsvcsv / json / avro
jsonpaths—JSON field paths array
strip_outer_arrayfalseStrip outer [...] in JSON
max_filter_ratio0Max fraction of bad rows allowed (0=reject any error)
strict_modefalseReject rows with type mismatch
timeout600Job timeout in seconds
timezoneUTCTimezone for datetime parsing
partial_updatefalseOnly update specified columns (PK table)
merge_condition—Conditional MERGE for PK table
enable_merge_commitfalseBatch concurrent loads (3.4+)

Partial Update (Primary Key Table)

Update only specific columns without touching others:

# Only update `status` and `updated_at` columns
curl --location-trusted \
  -u root:password \
  -H "label:partial_update_001" \
  -H "Expect:100-continue" \
  -H "format:json" \
  -H "partial_update:true" \
  -H "columns:order_id,status,updated_at" \
  -H "jsonpaths:[\"$.order_id\",\"$.status\",\"$.updated_at\"]" \
  -d '{"order_id":12345,"status":"shipped","updated_at":"2024-01-15 10:30:00"}' \
  -XPUT \
  "http://fe-host:8030/api/sales/orders/_stream_load"

Partial update requires: table must be Primary Key type; columns header must list only the columns being updated (must include PK columns).


Error Handling and Response

Success Response

{
    "TxnId": 1234567,
    "Label": "order_load_20240115_001",
    "Status": "Success",
    "Message": "OK",
    "NumberTotalRows": 10000,
    "NumberLoadedRows": 10000,
    "NumberFilteredRows": 0,
    "NumberUnselectedRows": 0,
    "LoadBytes": 1048576,
    "LoadTimeMs": 1250,
    "BeginTxnTimeMs": 5,
    "StreamLoadPutTimeMs": 10,
    "ReadDataTimeMs": 800,
    "WriteDataTimeMs": 435
}

Partial Failure Response

{
    "Status": "Success",
    "NumberFilteredRows": 50,
    "ErrorURL": "http://be-host:8040/api/_load_error_log?file=error_log_xxx"
}

Fetch error details:

curl "http://be-host:8040/api/_load_error_log?file=error_log_xxx" | head -50

Common Status Values

StatusMeaning
SuccessAll rows loaded
Publish TimeoutLoad committed but tablets still publishing; data will be visible soon
Label Already ExistsDuplicate label — check if previous load succeeded before retrying
FailLoad failed — check Message field

Python Client Pattern

import requests
import json
import hashlib
import time
from typing import List, Dict, Any


class StarRocksStreamLoader:
    def __init__(self, host: str, port: int, user: str, password: str, database: str):
        self.base_url = f"http://{host}:{port}/api/{database}"
        self.auth = (user, password)

    def load_json(
        self,
        table: str,
        records: List[Dict[str, Any]],
        label: str | None = None,
        columns: List[str] | None = None,
        partial_update: bool = False,
    ) -> dict:
        if not label:
            content_hash = hashlib.md5(
                json.dumps(records, default=str).encode()
            ).hexdigest()[:8]
            label = f"{table}_{int(time.time())}_{content_hash}"

        ndjson = "\n".join(json.dumps(r, default=str) for r in records)

        headers = {
            "label": label,
            "Expect": "100-continue",
            "format": "json",
            "strip_outer_array": "false",
        }
        if columns:
            col_str = ",".join(columns)
            headers["columns"] = col_str
            headers["jsonpaths"] = json.dumps([f"$.{c}" for c in columns])
        if partial_update:
            headers["partial_update"] = "true"

        url = f"{self.base_url}/{table}/_stream_load"
        resp = requests.put(
            url,
            headers=headers,
            data=ndjson.encode("utf-8"),
            auth=self.auth,
            timeout=120,
        )
        resp.raise_for_status()
        result = resp.json()

        if result["Status"] not in ("Success", "Publish Timeout"):
            raise RuntimeError(
                f"Stream load failed: {result['Status']} — {result.get('Message', '')}\n"
                f"Error URL: {result.get('ErrorURL', 'none')}"
            )

        return result

    def load_csv(
        self,
        table: str,
        csv_data: str,
        label: str,
        columns: str | None = None,
        separator: str = ",",
        max_filter_ratio: float = 0.0,
    ) -> dict:
        headers = {
            "label": label,
            "Expect": "100-continue",
            "format": "csv",
            "column_separator": separator,
            "max_filter_ratio": str(max_filter_ratio),
        }
        if columns:
            headers["columns"] = columns

        url = f"{self.base_url}/{table}/_stream_load"
        resp = requests.put(
            url,
            headers=headers,
            data=csv_data.encode("utf-8"),
            auth=self.auth,
            timeout=300,
        )
        resp.raise_for_status()
        result = resp.json()

        if result["Status"] not in ("Success", "Publish Timeout"):
            raise RuntimeError(f"Stream load failed: {result}")
        return result


# Usage
loader = StarRocksStreamLoader("fe-host", 8030, "root", "pass", "sales")

orders = [
    {"order_id": 1, "customer_id": 101, "amount": 99.99, "created_at": "2024-01-15"},
    {"order_id": 2, "customer_id": 102, "amount": 149.99, "created_at": "2024-01-15"},
]

result = loader.load_json("orders", orders)
print(f"Loaded {result['NumberLoadedRows']} rows in {result['LoadTimeMs']}ms")

Idempotency with Labels

Labels provide at-least-once with idempotency:

def load_with_retry(loader, table, records, label, max_retries=3):
    for attempt in range(max_retries):
        try:
            return loader.load_json(table, records, label=label)
        except Exception as e:
            error_msg = str(e)
            if "Label Already Exists" in error_msg:
                # Previous load succeeded — check result
                print(f"Label {label} already exists — load previously succeeded")
                return {"Status": "Success", "NumberLoadedRows": len(records)}
            if attempt == max_retries - 1:
                raise
            time.sleep(2 ** attempt)

Label format recommendation: {table}_{date}_{batch_id} — deterministic and debuggable.

Labels expire after label_keep_max_second seconds (default 3 days).


Merge Commit Mode (StarRocks 3.4+)

For high-concurrency micro-batch loads, merge commit batches many small requests into one transaction:

curl ... \
  -H "enable_merge_commit:true" \
  -H "merge_commit_interval_ms:1000" \
  -H "merge_commit_async:true" \  # return immediately, don't wait for commit
  ...

Merge commit reduces write amplification from many small loads. Use when:

  • 100 concurrent stream load requests per second

  • Each request < 1MB
  • Latency tolerance > 1 second

Performance Tuning

Optimal Batch Size

Data SizeRecommended Approach
< 1 MBEnable merge_commit_mode
1 MB – 100 MBStandard stream load
100 MB – 1 GBSplit into 100 MB chunks
> 1 GBUse Broker Load instead

Parallelism

# Load multiple files in parallel using ThreadPoolExecutor
from concurrent.futures import ThreadPoolExecutor, as_completed

def load_file(path: str) -> dict:
    label = f"batch_{path.stem}_{int(time.time())}"
    with open(path) as f:
        return loader.load_csv("orders", f.read(), label)

with ThreadPoolExecutor(max_workers=8) as pool:
    futures = {pool.submit(load_file, p): p for p in csv_files}
    for fut in as_completed(futures):
        result = fut.result()
        print(f"{futures[fut]}: {result['NumberLoadedRows']} rows")

Timeout Calculation

timeout_seconds = data_size_bytes / (cluster_load_speed_bytes_per_sec * 0.7)

Typical cluster load speed: 100-300 MB/s per BE.


Anti-Patterns

  1. No label — cannot safely retry; duplicates on transient failures.
  2. max_filter_ratio=1 in production — silently ignores all bad data; keep ≤ 0.01 for production.
  3. Loading 10GB files — stream load holds entire payload in memory; split into ≤ 1GB chunks.
  4. strict_mode=false for schema changes — type mismatches silently truncate values; enable strict_mode in staging.
  5. Not checking ErrorURL — NumberFilteredRows > 0 means data loss; always fetch error log.
  6. Sending requests to BE directly — send to FE for proper load routing and monitoring; BE direct is only for internal optimization.
  7. No Expect:100-continue — without it, curl sends all data before getting auth failure; wastes bandwidth.

References

  • Stream Load docs: docs.starrocks.io/docs/loading/StreamLoad/
  • Partial update: docs.starrocks.io/docs/loading/Load_to_Primary_Key_tables/
  • Related skills: [[starrocks-routine-load-kafka]], [[starrocks-cdc-pipeline]], [[starrocks-ddl-table-types]]

리뷰

아직 리뷰가 없습니다. 사용해 본 소감을 남겨 주세요.

댓글

로그인 없이 쓸 수 있습니다. 사용 후기, 질문, 작동하지 않은 환경 등을 편하게 남겨 주세요.

아직 댓글이 없습니다. 첫 댓글을 남겨 보세요.

보내면 바로 공개됩니다. 이메일 주소나 전화번호 같은 개인 정보는 쓰지 마세요. URL은 2개까지입니다.

0 / 1,000자

이 양식은 reCAPTCHA로 보호되며 Google 개인정보처리방침 및 서비스 약관이 적용됩니다.

같은 저장소의 스킬

AIOps autonomous incident response agent — LLM-driven diagnosis loop (Claude tool-use agent with kubectl/SQL/Prometheus tools), alert-to-action pipeline (PagerDuty webhook → agent trigger), automated RCA generation (failure taxonomy + log correlation), self-healing action executor with approval gate, incident severity classification, runbook automation (structured YAML runbooks executed by agent), escalation logic, incident timeline auto-generation, Slack integration for human-in-the-loop approvals

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ivanshamaev/de-agent-skills222026년 5월 20일 업데이트

AIOps capacity planning agent — predictive resource forecasting (Prophet/linear regression on Prometheus metrics), Kubernetes HPA/VPA right-sizing recommendations, node capacity headroom calculator, Kafka partition and broker capacity model, Spark executor sizing from job history, data lake storage growth forecast (S3/GCS), cluster autoscaler simulation, automatic HPA threshold tuning, cost-per-job attribution, capacity planning report generator

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ivanshamaev/de-agent-skills222026년 5월 20일 업데이트

AIOps infrastructure anomaly detection — statistical baseline (z-score/IQR/seasonal decomposition), Prometheus anomaly rules (predict_linear/stddev_over_time/MAD), ML-based detection (Isolation Forest/Prophet/LSTM autoencoder on metrics), metric correlation clustering, automated alert threshold tuning from historical data, Kubernetes resource anomaly detection, data pipeline anomaly signals (row count z-score/freshness drift/throughput drop), Python sklearn/Prophet integration, Grafana anomaly panel

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ivanshamaev/de-agent-skills222026년 5월 20일 업데이트

AIOps observability copilot — natural language to PromQL/LogQL translation, alert explanation in plain English (what fired/why/impact), Grafana dashboard auto-generation from service topology, anomaly narrative generation from metric patterns, on-call context enrichment (related alerts/recent deploys/runbook links), log pattern clustering for noise reduction, SLO status explanation, automated weekly observability health digest

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ivanshamaev/de-agent-skills222026년 5월 20일 업데이트

AIOps continuous platform optimization agent — autonomous optimization loop (observe→analyze→recommend→apply), Kubernetes resource rightsizing (VPA recommendation reader + apply), Kafka consumer lag auto-scale, Spark job configuration tuning from history, idle resource detection (unused deployments/PVCs/topics), compaction and VACUUM scheduling, auto-ANALYZE stale statistics, cost savings attribution, optimization audit trail, human approval gate for high-risk changes

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ivanshamaev/de-agent-skills222026년 5월 20일 업데이트

AIOps autonomous query cost analyzer — Trino system.runtime.query_history cost SQL (CPU time/peak memory/bytes scanned), ClickHouse system.query_log top expensive queries, Spark UI cost attribution by user/job/DAG, BigQuery INFORMATION_SCHEMA.JOBS cost analysis, LLM-driven query rewrite recommendations (missing partition filters/broadcast hints/aggregation pushdown), cost anomaly detection (user over daily budget), automated query tagging, chargeback report by team/project

한국어 요약은 준비 중입니다. 원문 설명을 표시하고 있습니다.

ivanshamaev/de-agent-skills222026년 5월 20일 업데이트

ivanshamaev의 스킬 모두 보기

이 스킬의 문제 신고