26Z07f5

Young-Kyoo Kim·2026년 8월 7일

HTTP Stream Load(8030 포트)만 강제되는 것은 아닙니다. Primary Key 테이블의 특성StarRocks의 S3 파일 직접 참조 기능을 활용하면 HTTP Ingress 없이 MySQL 포트(9030)만으로 Upsert를 구현할 수 있습니다.


대안 1. MySQL 포트(9030)로 배치 INSERT INTO 실행 (가장 직관적)

StarRocks의 Primary Key 테이블은 일반 INSERT INTO 구문을 실행하면 자동으로 Upsert(덮어쓰기) 처리됩니다.

requests.put 대신 기존에 연결되어 있던 PyMySQL(9030 포트)을 사용하여 1,000~5,000건씩 배치로 INSERT를 날리는 방식입니다.

def mysql_batch_upsert(conn, df: pd.DataFrame, batch_size: int = 2000):
    """MySQL 포트(9030)를 통해 배치 INSERT (Primary Key 자동 Upsert)"""
    if df.empty:
        return

    # 튜플 리스트 생성
    records = df[[
        'object_id', 'bucket', 'object_key', 'prefix', 
        'size_bytes', 'etag', 'event_time', '__deleted'
    ]].to_records(index=False).tolist()

    sql = """
        INSERT INTO object_current_state 
        (object_id, bucket, object_key, prefix, size_bytes, etag, event_time, __deleted)
        VALUES (%s, %s, %s, %s, %s, %s, %s, %s)
    """

    with conn.cursor() as cursor:
        for i in range(0, len(records), batch_size):
            batch = records[i:i + batch_size]
            cursor.executemany(sql, batch)
    print(f" -> Successfully Upserted {len(records)} rows via MySQL Protocol.")

대안 2. StarRocks S3 Table Function 사용 (추천: 가장 빠름)

Python에서 Parquet을 직접 받아올 필요 없이, StarRocks가 AIStor S3에 있는 Parquet을 직접 읽어서 테이블로 바로 Upsert하도록 명령하는 방식입니다. HTTP Stream Load를 아예 안 쓰며, MySQL 포트(9030)로 SQL 한 문장만 날리면 끝납니다.

-- StarRocks CLI 또는 PyMySQL(9030)에서 실행
INSERT INTO object_current_state (object_id, bucket, object_key, prefix, size_bytes, etag, event_time, __deleted)
SELECT 
    md5(concat('my-bucket', ':', unquote(Key))) AS object_id,
    'my-bucket' AS bucket,
    unquote(Key) AS object_key,
    if(locate('/', unquote(Key)) > 0, left(unquote(Key), length(unquote(Key)) - length(split_part(unquote(Key), '/', -1)) - 1), '') AS prefix,
    cast(Size as BIGINT) AS size_bytes,
    coalesce(ETag, '') AS etag,
    '2026-08-07 07:28:00' AS event_time,
    0 AS __deleted
FROM FILES(
    "path" = "s3://system-inventory-bucket/2026-08-07T07:28Z/files/*.parquet",
    "format" = "parquet",
    "aws.s3.endpoint" = "http://aistor-s3-service:9000",
    "aws.s3.access_key" = "YOUR_ACCESS_KEY",
    "aws.s3.secret_key" = "YOUR_SECRET_KEY",
    "aws.s3.enable_ssl" = "false",
    "aws.s3.use_instance_profile" = "false"
);

대안 3. K8s 내부 도메인(Cluster IP) 활용

만약 이 스크립트나 서비스가 Kubernetes 파드(Pod) 내부에서 실행되고 있다면, Ingress 필요 없이 K8s 내부 Service DNS 명으로 HTTP 8030 포트에 바로 접근할 수 있습니다.

  • HTTP Host URL 예시:
    [http://starrocks-fe-service.namespace.svc.cluster.local:8030](http://starrocks-fe-service.namespace.svc.cluster.local:8030)

요약 및 권장 사항

  1. In-Cluster 실행 환경인 경우: 대안 3 (K8s Service DNS로 기존 Stream Load 계속 사용)
  2. K8s 외부 실행 + Ingress 없음: 대안 2 (S3 Table Function) 또는 대안 1 (MySQL Batch Insert) 사용

0개의 댓글