SQL 기반 수집

SQL 기반 수집 (SQL-based ingestion) API

druid-multi-stage-query 확장을 사용한 SQL 기반 배치 수집 API를 다룹니다. MSQ 태스크 엔진에 쿼리를 제출하고 상태·리포트를 확인하며 취소하는 방법을 설명해요.

출처: 문서

본문

이 페이지는 Druid 24.0에서 새로 추가된 druid-multi-stage-query 확장을 사용한 SQL 기반 배치 수집을 설명합니다. 어떤 수집 방법이 적합한지 결정하려면 ingestion methods 표를 참고하세요.

웹 콘솔의 Query 뷰는 multi-stage query 태스크 엔진(MSQ 태스크 엔진)과 multi-stage query 아키텍처에 친숙한 경험을 제공합니다. 프로그래밍 인터페이스가 필요 없으면 웹 콘솔 사용을 권장합니다.

MSQ 태스크 엔진에 API를 사용할 때, 취하려는 동작에 따라 사용하는 엔드포인트가 달라집니다.

  • /druid/v2/sql/task: 수집을 위한 쿼리를 제출합니다.
  • /druid/indexer/v1/task: 쿼리와 상호작용합니다. 여기에는 상태나 세부 정보를 가져오거나 쿼리를 취소하는 것이 포함됩니다. 이 페이지는 MSQ 태스크 엔진과 함께 사용할 수 있는 Overlord Task API 몇 가지를 설명합니다. Druid API에 대한 자세한 내용은 Druid의 API reference를 참고하세요.

이 문서에서 http://ROUTER_IP:ROUTER_PORT는 여러분의 Router 서비스 주소와 포트를 위한 자리표시자입니다. 이를 배포 정보로 교체하세요. 예를 들어 quickstart 배포라면 http://localhost:8888을 사용합니다.

쿼리 제출

MSQ 태스크 엔진에 쿼리를 제출합니다.

/druid/v2/sql/task 엔드포인트는 다음을 받습니다.

  • query, context, parameters 필드를 사용하는 JSON-over-HTTP 형식의 SQL 요청. 이 엔드포인트는 resultFormat, header, typesHeader, sqlTypesHeader 필드는 무시합니다.
  • INSERT 및 REPLACE 문.
  • SELECT 쿼리 (실험적 기능). SELECT 쿼리 결과는 controller가 워커에서 수집해 배열의 배열 형태로 태스크 리포트에 기록합니다. INSERT나 REPLACE 없는 일반 SELECT 쿼리의 동작과 결과 형식은 변경될 수 있어요.

URL

POST /druid/v2/sql/task

응답

  • 200 SUCCESS — 쿼리를 성공적으로 제출함
  • 400 BAD REQUEST — 잘못된 쿼리로 인한 오류. 다음 형식의 오류를 자세히 설명하는 JSON 객체를 반환합니다.
{
    "error": "A well-defined error code.",
    "errorMessage": "A message with additional details about the error.",
    "errorClass": "Class of exception that caused this error.",
    "host": "The host on which the error occurred."
}
  • 500 INTERNAL SERVER ERROR — 예상치 못한 조건으로 요청이 전송되지 않음. 다음 형식의 오류를 자세히 설명하는 JSON 객체를 반환합니다.
{
    "error": "A well-defined error code.",
    "errorMessage": "A message with additional details about the error.",
    "errorClass": "Class of exception that caused this error.",
    "host": "The host on which the error occurred."
}

샘플 요청

다음 예시는 외부 JSON 소스에서 데이터를 가져와 wikipedia라는 테이블에 삽입하는 쿼리를 보여줍니다. 예시는 두 개의 쿼리 컨텍스트 파라미터를 지정합니다.

  • maxNumTasks=3: 최대 병렬 태스크 수를 3으로 제한합니다.
  • finalizeAggregations=false: Druid가 수집 중에 집계의 중간 타입을 저장하도록 보장합니다. 자세한 내용은 Rollup을 참고하세요.

HTTP

POST /druid/v2/sql/task HTTP/1.1
Host: http://ROUTER_IP:ROUTER_PORT
Content-Type: application/json

{
  "query": "SET maxNumTasks=3;\nSET finalizeAggregations=false;\nINSERT INTO wikipedia\nSELECT\n  TIME_PARSE(\"timestamp\") AS __time,\n  *\nFROM TABLE(\n  EXTERN(\n    '{\"type\": \"http\", \"uris\": [\"https://druid.apache.org/data/wikipedia.json.gz\"]}',\n    '{\"type\": \"json\"}',\n    '[{\"name\": \"added\", \"type\": \"long\"}, {\"name\": \"channel\", \"type\": \"string\"}, {\"name\": \"cityName\", \"type\": \"string\"}, {\"name\": \"comment\", \"type\": \"string\"}, {\"name\": \"commentLength\", \"type\": \"long\"}, {\"name\": \"countryIsoCode\", \"type\": \"string\"}, {\"name\": \"countryName\", \"type\": \"string\"}, {\"name\": \"deleted\", \"type\": \"long\"}, {\"name\": \"delta\", \"type\": \"long\"}, {\"name\": \"deltaBucket\", \"type\": \"string\"}, {\"name\": \"diffUrl\", \"type\": \"string\"}, {\"name\": \"flags\", \"type\": \"string\"}, {\"name\": \"isAnonymous\", \"type\": \"string\"}, {\"name\": \"isMinor\", \"type\": \"string\"}, {\"name\": \"isNew\", \"type\": \"string\"}, {\"name\": \"isRobot\", \"type\": \"string\"}, {\"name\": \"isUnpatrolled\", \"type\": \"string\"}, {\"name\": \"metroCode\", \"type\": \"string\"}, {\"name\": \"namespace\", \"type\": \"string\"}, {\"name\": \"page\", \"type\": \"string\"}, {\"name\": \"regionIsoCode\", \"type\": \"string\"}, {\"name\": \"regionName\", \"type\": \"string\"}, {\"name\": \"timestamp\", \"type\": \"string\"}, {\"name\": \"user\", \"type\": \"string\"}]'\n  )\n)\nPARTITIONED BY DAY"
}

cURL

curl --location --request POST 'http://ROUTER_IP:ROUTER_PORT/druid/v2/sql/task' \
  --header 'Content-Type: application/json' \
  --data '{
  "query": "SET maxNumTasks=3;\nSET finalizeAggregations=false;\nINSERT INTO wikipedia\nSELECT\n  TIME_PARSE(\"timestamp\") AS __time,\n  *\nFROM TABLE(\n  EXTERN(\n    '\''{\"type\": \"http\", \"uris\": [\"https://druid.apache.org/data/wikipedia.json.gz\"]}'\'',\n    '\''{\"type\": \"json\"}'\'',\n    '\''[{\"name\": \"added\", \"type\": \"long\"}, {\"name\": \"channel\", \"type\": \"string\"}, {\"name\": \"cityName\", \"type\": \"string\"}, {\"name\": \"comment\", \"type\": \"string\"}, {\"name\": \"commentLength\", \"type\": \"long\"}, {\"name\": \"countryIsoCode\", \"type\": \"string\"}, {\"name\": \"countryName\", \"type\": \"string\"}, {\"name\": \"deleted\", \"type\": \"long\"}, {\"name\": \"delta\", \"type\": \"long\"}, {\"name\": \"deltaBucket\", \"type\": \"string\"}, {\"name\": \"diffUrl\", \"type\": \"string\"}, {\"name\": \"flags\", \"type\": \"string\"}, {\"name\": \"isAnonymous\", \"type\": \"string\"}, {\"name\": \"isMinor\", \"type\": \"string\"}, {\"name\": \"isNew\", \"type\": \"string\"}, {\"name\": \"isRobot\", \"type\": \"string\"}, {\"name\": \"isUnpatrolled\", \"type\": \"string\"}, {\"name\": \"metroCode\", \"type\": \"string\"}, {\"name\": \"namespace\", \"type\": \"string\"}, {\"name\": \"page\", \"type\": \"string\"}, {\"name\": \"regionIsoCode\", \"type\": \"string\"}, {\"name\": \"regionName\", \"type\": \"string\"}, {\"name\": \"timestamp\", \"type\": \"string\"}, {\"name\": \"user\", \"type\": \"string\"}]'\''\n  )\n)\nPARTITIONED BY DAY"
}'

Python

import json
import requests

url = "http://ROUTER_IP:ROUTER_PORT/druid/v2/sql/task"

payload = json.dumps({
  "query": "SET maxNumTasks=3;\nSET finalizeAggregations=false;\nINSERT INTO wikipedia\nSELECT\n  TIME_PARSE(\"timestamp\") AS __time,\n  *\nFROM TABLE(\n  EXTERN(\n    '{\"type\": \"http\", \"uris\": [\"https://druid.apache.org/data/wikipedia.json.gz\"]}',\n    '{\"type\": \"json\"}',\n    '[{\"name\": \"added\", \"type\": \"long\"}, {\"name\": \"channel\", \"type\": \"string\"}, {\"name\": \"cityName\", \"type\": \"string\"}, {\"name\": \"comment\", \"type\": \"string\"}, {\"name\": \"commentLength\", \"type\": \"long\"}, {\"name\": \"countryIsoCode\", \"type\": \"string\"}, {\"name\": \"countryName\", \"type\": \"string\"}, {\"name\": \"deleted\", \"type\": \"long\"}, {\"name\": \"delta\", \"type\": \"long\"}, {\"name\": \"deltaBucket\", \"type\": \"string\"}, {\"name\": \"diffUrl\", \"type\": \"string\"}, {\"name\": \"flags\", \"type\": \"string\"}, {\"name\": \"isAnonymous\", \"type\": \"string\"}, {\"name\": \"isMinor\", \"type\": \"string\"}, {\"name\": \"isNew\", \"type\": \"string\"}, {\"name\": \"isRobot\", \"type\": \"string\"}, {\"name\": \"isUnpatrolled\", \"type\": \"string\"}, {\"name\": \"metroCode\", \"type\": \"string\"}, {\"name\": \"namespace\", \"type\": \"string\"}, {\"name\": \"page\", \"type\": \"string\"}, {\"name\": \"regionIsoCode\", \"type\": \"string\"}, {\"name\": \"regionName\", \"type\": \"string\"}, {\"name\": \"timestamp\", \"type\": \"string\"}, {\"name\": \"user\", \"type\": \"string\"}]'\n  )\n)\nPARTITIONED BY DAY"
})
headers = {
  'Content-Type': 'application/json'
}

response = requests.post(url, headers=headers, data=payload)

print(response.text)

샘플 응답

{
    "taskId": "query-431c4a18-9dde-4ec8-ab82-ec7fd17d5a4e",
    "state": "RUNNING"
}

응답 필드

필드 설명
taskId Controller 태스크 ID. Druid의 표준 Tasks API를 사용해 이 controller 태스크와 상호작용할 수 있습니다.
state 쿼리의 초기 상태.

쿼리 태스크의 상태 가져오기

쿼리 태스크의 상태를 가져옵니다. 태스크의 상태 코드, runner 상태, 태스크 타입, 데이터소스 및 기타 관련 메타데이터가 담긴 JSON 객체를 반환합니다.

URL

GET /druid/indexer/v1/task/{taskId}/status

응답

  • 200 SUCCESS — 태스크 상태를 성공적으로 조회함
  • 404 NOT FOUND — ID로 태스크를 찾을 수 없음

샘플 요청

다음 예시는 ID가 query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e인 태스크의 상태를 가져오는 방법을 보여줍니다.

HTTP

GET /druid/indexer/v1/task/query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e/status HTTP/1.1
Host: http://ROUTER_IP:ROUTER_PORT

cURL

curl --location --request GET 'http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/task/query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e/status'

Python

import requests

url = "http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/task/query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e/status"

payload={}
headers = {}

response = requests.post(url, headers=headers, data=payload)

print(response.text)
print(response.text)

샘플 응답

{
  "task": "query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e",
  "status": {
    "id": "query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e",
    "groupId": "query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e",
    "type": "query_controller",
    "createdTime": "2022-09-14T22:12:00.183Z",
    "queueInsertionTime": "1970-01-01T00:00:00.000Z",
    "statusCode": "RUNNING",
    "status": "RUNNING",
    "runnerStatusCode": "RUNNING",
    "duration": -1,
    "location": {
      "host": "localhost",
      "port": 8100,
      "tlsPort": -1
    },
    "dataSource": "kttm_simple",
    "errorMsg": null
  }
}

쿼리 태스크의 리포트 가져오기

쿼리의 태스크 리포트를 가져옵니다. 리포트는 스테이지, 경고, 오류 같은 쿼리 태스크에 대한 상세 정보를 제공합니다.

태스크 API로 리포트를 볼 때는 다음을 염두에 두세요.

  • 전체 작업에 대한 태스크 리포트는 query_controller 태스크와 연결됩니다. query_worker 태스크는 자체 리포트가 없으며, 그 정보는 controller 리포트에 포함됩니다.
  • 태스크가 시작되는 동안 태스크 리포트 API가 일시적으로 404 Not Found를 보고할 수 있습니다.
  • 실험적 기능으로, MSQ 태스크 엔진은 SELECT 쿼리 실행을 지원합니다. SELECT 쿼리 결과는 multiStageQuery.payload.results.results 태스크 리포트 키에 배열의 배열로 기록됩니다. INSERT나 REPLACE 없는 일반 SELECT 쿼리의 동작과 결과 형식은 변경될 수 있어요.
  • multiStageQuery.payload.results.resultsTruncated는 리포트가 비대해지는 것을 막기 위해 결과가 잘렸는지 여부를 나타냅니다.
  • 리포트의 필드에 대한 설명은 Report response fields를 참고하세요.

URL

GET /druid/indexer/v1/task/{taskId}/reports

응답

  • 200 SUCCESS — 태스크 리포트를 성공적으로 조회함

샘플 요청

다음 예시는 태스크 ID query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e인 쿼리의 리포트를 가져오는 방법을 보여줍니다.

HTTP

GET /druid/indexer/v1/task/query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e/reports HTTP/1.1
Host: http://ROUTER_IP:ROUTER_PORT

cURL

curl --location --request GET 'http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/task/query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e/reports'

Python

import requests

url = "http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/task/query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e/reports"

headers = {}

response = requests.post(url, headers=headers, data=payload)

print(response.text)
print(response.text)

샘플 응답

응답은 쿼리의 리포트 예시를 보여줍니다.

{
  "multiStageQuery": {
    "type": "multiStageQuery",
    "taskId": "query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e",
    "payload": {
      "status": {
        "status": "SUCCESS",
        "startTime": "2022-09-14T22:12:09.266Z",
        "durationMs": 28227,
        "workers": {
          "0": [
            {
              "workerId": "query-3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e-worker0_0",
              "state": "SUCCESS",
              "durationMs": 15511,
              "pendingMs": 137
            }
          ]
        },
        "pendingTasks": 0,
        "runningTasks": 2,
        "segmentLoadWaiterStatus": {
          "state": "SUCCESS",
          "dataSource": "kttm_simple",
          "startTime": "2022-09-14T23:12:09.266Z",
          "duration": 15,
          "totalSegments": 1,
          "usedSegments": 1,
          "precachedSegments": 0,
          "onDemandSegments": 0,
          "pendingSegments": 0,
          "unknownSegments": 0
        },
        "segmentReport": {
          "shardSpec": "NumberedShardSpec",
          "details": "Cannot use RangeShardSpec, RangedShardSpec only supports string CLUSTER BY keys. Using NumberedShardSpec instead."
        }
      },
      "stages": [
        {
          "stageNumber": 0,
          "definition": {
            "id": "71ecb11e-09d7-42f8-9225-1662c8e7e121_0",
            "input": [
              {
                "type": "external",
                "inputSource": {
                  "type": "http",
                  "uris": [
                    "https://static.imply.io/example-data/kttm-v2/kttm-v2-2019-08-25.json.gz"
                  ],
                  "httpAuthenticationUsername": null,
                  "httpAuthenticationPassword": null
                },
                "inputFormat": {
                  "type": "json",
                  "flattenSpec": null,
                  "featureSpec": {},
                  "keepNullColumns": false
                },
                "signature": [
                  {
                    "name": "timestamp",
                    "type": "STRING"
                  },
                  {
                    "name": "agent_category",
                    "type": "STRING"
                  },
                  {
                    "name": "agent_type",
                    "type": "STRING"
                  }
                ]
              }
            ],
            "processor": {
              "type": "scan",
              "query": {
                "queryType": "scan",
                "dataSource": {
                  "type": "inputNumber",
                  "inputNumber": 0
                },
                "intervals": {
                  "type": "intervals",
                  "intervals": [
                    "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z"
                  ]
                },
                "resultFormat": "compactedList",
                "columns": [
                  "agent_category",
                  "agent_type",
                  "timestamp"
                ],
                "context": {
                  "finalize": false,
                  "finalizeAggregations": false,
                  "groupByEnableMultiValueUnnesting": false,
                  "scanSignature": "[{\"name\":\"agent_category\",\"type\":\"STRING\"},{\"name\":\"agent_type\",\"type\":\"STRING\"},{\"name\":\"timestamp\",\"type\":\"STRING\"}]",
                  "sqlInsertSegmentGranularity": "{\"type\":\"all\"}",
                  "sqlQueryId": "3dc0c45d-34d7-4b15-86c9-cdb2d3ebfc4e",
                  "sqlReplaceTimeChunks": "all"
                },
                "granularity": {
                  "type": "all"
                }
              }
            },
            "signature": [
              {
                "name": "__boost",
                "type": "LONG"
              },
              {
                "name": "agent_category",
                "type": "STRING"
              },
              {
                "name": "agent_type",
                "type": "STRING"
              },
              {
                "name": "timestamp",
                "type": "STRING"
              }
            ],
            "shuffleSpec": {
              "type": "targetSize",
              "clusterBy": {
                "columns": [
                  {
                    "columnName": "__boost"
                  }
                ]
              },
              "targetSize": 3000000
            },
            "maxWorkerCount": 1,
            "shuffleCheckHasMultipleValues": true
          },
          "phase": "FINISHED",
          "workerCount": 1,
          "partitionCount": 1,
          "startTime": "2022-09-14T22:12:11.663Z",
          "duration": 19965,
          "sort": true
        },
        {
          "stageNumber": 1,
          "definition": {
            "id": "71ecb11e-09d7-42f8-9225-1662c8e7e121_1",
            "input": [
              {
                "type": "stage",
                "stage": 0
              }
            ],
            "processor": {
              "type": "segmentGenerator",
              "dataSchema": {
                "dataSource": "kttm_simple",
                "timestampSpec": {
                  "column": "__time",
                  "format": "millis",
                  "missingValue": null
                },
                "dimensionsSpec": {
                  "dimensions": [
                    {
                      "type": "string",
                      "name": "timestamp",
                      "multiValueHandling": "SORTED_ARRAY",
                      "createBitmapIndex": true
                    },
                    {
                      "type": "string",
                      "name": "agent_category",
                      "multiValueHandling": "SORTED_ARRAY",
                      "createBitmapIndex": true
                    },
                    {
                      "type": "string",
                      "name": "agent_type",
                      "multiValueHandling": "SORTED_ARRAY",
                      "createBitmapIndex": true
                    }
                  ],
                  "dimensionExclusions": [
                    "__time"
                  ],
                  "includeAllDimensions": false
                },
                "metricsSpec": [],
                "granularitySpec": {
                  "type": "arbitrary",
                  "queryGranularity": {
                    "type": "none"
                  },
                  "rollup": false,
                  "intervals": [
                    "-146136543-09-08T08:23:32.096Z/146140482-04-24T15:36:27.903Z"
                  ]
                },
                "transformSpec": {
                  "filter": null,
                  "transforms": []
                }
              },
              "columnMappings": [
                {
                  "queryColumn": "timestamp",
                  "outputColumn": "timestamp"
                },
                {
                  "queryColumn": "agent_category",
                  "outputColumn": "agent_category"
                },
                {
                  "queryColumn": "agent_type",
                  "outputColumn": "agent_type"
                }
              ],
              "tuningConfig": {
                "maxNumWorkers": 1,
                "maxRowsInMemory": 100000,
                "rowsPerSegment": 3000000
              }
            },
            "signature": [],
            "maxWorkerCount": 1
          },
          "phase": "FINISHED",
          "workerCount": 1,
          "partitionCount": 1,
          "startTime": "2022-09-14T22:12:31.602Z",
          "duration": 5891
        }
      ],
      "counters": {
        "0": {
          "0": {
            "input0": {
              "type": "channel",
              "rows": [
                465346
              ],
              "files": [
                1
              ],
              "totalFiles": [
                1
              ]
            },
            "output": {
              "type": "channel",
              "rows": [
                465346
              ],
              "bytes": [
                43694447
              ],
              "frames": [
                7
              ]
            },
            "shuffle": {
              "type": "channel",
              "rows": [
                465346
              ],
              "bytes": [
                41835307
              ],
              "frames": [
                73
              ]
            },
            "sortProgress": {
              "type": "sortProgress",
              "totalMergingLevels": 3,
              "levelToTotalBatches": {
                "0": 1,
                "1": 1,
                "2": 1
              },
              "levelToMergedBatches": {
                "0": 1,
                "1": 1,
                "2": 1
              },
              "totalMergersForUltimateLevel": 1,
              "progressDigest": 1
            }
          }
        },
        "1": {
          "0": {
            "input0": {
              "type": "channel",
              "rows": [
                465346
              ],
              "bytes": [
                41835307
              ],
              "frames": [
                73
              ]
            },
            "segmentGenerationProgress": {
              "type": "segmentGenerationProgress",
              "rowsProcessed": 465346,
              "rowsPersisted": 465346,
              "rowsMerged": 465346
            }
          }
        }
      }
    }
  }
}

다음 표는 /druid/indexer/v1/task/{taskId}/reports 엔드포인트로 MSQ 태스크 엔진용 리포트를 가져올 때의 응답 필드를 설명합니다.

필드 설명
multiStageQuery.taskId Controller 태스크 ID.
multiStageQuery.payload.status 쿼리 상태 컨테이너.
multiStageQuery.payload.status.status RUNNING, SUCCESS, 또는 FAILED.
multiStageQuery.payload.status.startTime ISO 형식의 쿼리 시작 시간. 쿼리가 실행을 시작했을 때만 존재합니다.
multiStageQuery.payload.status.durationMs 쿼리가 실행을 시작한 후 경과한 밀리초. -1은 쿼리가 아직 시작되지 않았음을 뜻합니다.
multiStageQuery.payload.status.workers controller 태스크의 워커.
multiStageQuery.payload.status.workers. 재시도를 포함한 워커 태스크 배열.
multiStageQuery.payload.status.workers.[].workerId 워커 태스크의 ID.
multiStageQuery.payload.status.workers.[].status RUNNING, SUCCESS, 또는 FAILED.
multiStageQuery.payload.status.workers.[].durationMs 워커 태스크가 처음 요청된 시점과 완료된 시점 사이의 경과 밀리초. 상태가 RUNNING인 워커 태스크에서는 -1입니다.
multiStageQuery.payload.status.workers.[].pendingMs 워커 태스크가 처음 요청된 시점과 완전히 RUNNING이 된 시점 사이의 경과 밀리초. 실제 작업 시간은 actualWorkTimeMS = durationMs - pendingMs로 계산할 수 있습니다.
multiStageQuery.payload.status.pendingTasks 완전히 시작되지 않은 태스크 수. -1은 현재 그 수를 알 수 없음을 뜻합니다.
multiStageQuery.payload.status.runningTasks 현재 실행 중인 태스크 수. controller가 포함되므로 최소 1이어야 합니다.
multiStageQuery.payload.status.segmentLoadStatus 세그먼트 로딩 컨테이너. 세그먼트가 게시된 후에만 존재합니다.
multiStageQuery.payload.status.segmentLoadStatus.state INIT, WAITING, SUCCESS, FAILED 또는 TIMED_OUT 중 하나.
multiStageQuery.payload.status.segmentLoadStatus.startTime controller가 세그먼트가 로딩을 끝내기를 기다린 시점 이후의 시간.
multiStageQuery.payload.status.segmentLoadStatus.duration controller가 세그먼트가 로드되기를 기다린 밀리초 단위 기간.
multiStageQuery.payload.status.segmentLoadStatus.totalSegments 작업이 생성한 총 세그먼트 수. tombstone 세그먼트(있다면)를 포함합니다.
multiStageQuery.payload.status.segmentLoadStatus.usedSegments 로드 규칙에 따라 used로 표시된 세그먼트 수. unused 세그먼트는 언제든 정리될 수 있습니다.
multiStageQuery.payload.status.segmentLoadStatus.precachedSegments 로드 규칙에 따라 precached로 표시되고 historical이 서비스하는 세그먼트 수.
multiStageQuery.payload.status.segmentLoadStatus.onDemandSegments 로드 규칙에 따라 어떤 historical에도 로드되지 않은 세그먼트 수.
multiStageQuery.payload.status.segmentLoadStatus.pendingSegments 로드할 남은 세그먼트 수.
multiStageQuery.payload.status.segmentLoadStatus.unknownSegments 상태가 알려지지 않은 세그먼트 수.
multiStageQuery.payload.status.segmentReport 세그먼트 리포트. 쿼리가 수집일 때만 존재합니다.
multiStageQuery.payload.status.segmentReport.shardSpec 선택된 shard spec을 담습니다.
multiStageQuery.payload.status.segmentReport.details 선택된 shard spec에 대한 추가 근거를 담습니다.
multiStageQuery.payload.status.errorReport 오류 객체. 오류가 있었을 때만 존재합니다.
multiStageQuery.payload.status.errorReport.taskId 오류를 보고한 태스크(알려진 경우). controller 태스크일 수도 워커 태스크일 수도 있습니다.
multiStageQuery.payload.status.errorReport.host 오류를 보고한 태스크의 호스트네임과 포트(알려진 경우).
multiStageQuery.payload.status.errorReport.stageNumber 오류가 특정 스테이지 실행 중 발생했다면 그 스테이지 번호.
multiStageQuery.payload.status.errorReport.error 오류 코드 테이블에 설명된 대로 errorCode를 최소한 포함하고 다른 필드도 포함할 수 있는 오류 객체. 오류가 있으면 항상 존재합니다.
multiStageQuery.payload.status.errorReport.error.errorCode 오류 코드 테이블의 오류 코드 중 하나. 오류가 있으면 항상 존재합니다.
multiStageQuery.payload.status.errorReport.error.errorMessage 사용자 친화적인 오류 메시지. 오류가 있어도 항상 존재하는 것은 아닙니다.
multiStageQuery.payload.status.errorReport.exceptionStackTrace 오류가 서버 측 예외 때문이었다면 문자열 형태의 Java 스택 트레이스.
multiStageQuery.payload.stages 쿼리 스테이지 배열.
multiStageQuery.payload.stages[].stageNumber 각 스테이지는 다른 스테이지와 구분하는 번호를 가집니다.
multiStageQuery.payload.stages[].phase NEW, READING_INPUT, POST_READING, RESULTS_COMPLETE, 또는 FAILED. 스테이지가 시작했을 때만 존재합니다.
multiStageQuery.payload.stages[].workerCount 이 스테이지가 실행되는 병렬 태스크 수. 스테이지가 시작했을 때만 존재합니다.
multiStageQuery.payload.stages[].partitionCount 이 스테이지가 생성한 출력 파티션 수. 스테이지가 시작하고 출력 파티션 수를 계산했을 때만 존재합니다.
multiStageQuery.payload.stages[].startTime 이 스테이지의 시작 시간. 스테이지가 시작했을 때만 존재합니다.
multiStageQuery.payload.stages[].duration 스테이지가 실행된 밀리초 수. 스테이지가 시작했을 때만 존재합니다.
multiStageQuery.payload.stages[].sort 스테이지가 실행의 일부로 정렬을 수행하면 true로 설정되는 boolean.
multiStageQuery.payload.stages[].definition 스테이지가 무엇을 하는지 정의하는 객체.
multiStageQuery.payload.stages[].definition.id 스테이지의 고유 식별자.
multiStageQuery.payload.stages[].definition.input 스테이지가 가진 입력 배열.
multiStageQuery.payload.stages[].definition.broadcast 브로드캐스트되는 입력 인덱스 배열. 브로드캐스트되는 입력이 있을 때만 존재합니다.
multiStageQuery.payload.stages[].definition.processor 프로세서 로직을 정의하는 객체.
multiStageQuery.payload.stages[].definition.signature 스테이지의 출력 시그니처.

쿼리 태스크 취소

쿼리 태스크를 취소합니다. 성공적으로 취소된 태스크의 ID가 담긴 JSON 객체를 반환합니다.

URL

POST /druid/indexer/v1/task/{taskId}/shutdown

응답

  • 200 SUCCESS — 태스크를 성공적으로 종료함
  • 404 NOT FOUND — ID로 태스크를 찾을 수 없거나 태스크가 더 이상 실행 중이 아님

샘플 요청

다음 예시는 ID가 query-655efe33-781a-4c50-ae84-c2911b42d63c인 쿼리 태스크를 취소하는 방법을 보여줍니다.

HTTP

POST /druid/indexer/v1/task/query-655efe33-781a-4c50-ae84-c2911b42d63c/shutdown HTTP/1.1
Host: http://ROUTER_IP:ROUTER_PORT

cURL

curl --location --request POST 'http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/task/query-655efe33-781a-4c50-ae84-c2911b42d63c/shutdown'

Python

import requests

url = "http://ROUTER_IP:ROUTER_PORT/druid/indexer/v1/task/query-655efe33-781a-4c50-ae84-c2911b42d63c/shutdown"

payload = {}
headers = {}

response = requests.post(url, headers=headers, data=payload)

print(response.text)
print(response.text)

샘플 응답

응답은 취소된 태스크의 ID를 보여줍니다.

{
    "task": "query-655efe33-781a-4c50-ae84-c2911b42d63c"
}

더 알아보기 (Learn more)

  • MSQ 태스크 엔진에 대한 자세한 내용은 multi-stage query 문서를 참고하세요.
  • SQL 기반 수집의 전체 문법은 SQL-based ingestion 문서를 확인해 보세요.