

신중한 고려 끝에 Amazon Kinesis Data Analytics for SQL 애플리케이션을 중단하기로 결정했습니다.

1. **2025년 9월 1**일부터 Amazon Kinesis Data Analytics for SQL 애플리케이션에 대한 버그 수정은 제공되지 않습니다. 곧 중단될 예정이므로 지원이 제한될 예정이기 때문입니다.

2. **2025년 10월 15**일부터 새 Kinesis Data Analytics for SQL 애플리케이션을 생성할 수 없습니다.

3. **2026년 1월 27**일부터 애플리케이션이 삭제됩니다. Amazon Kinesis Data Analytics for SQL 애플리케이션을 시작하거나 작동할 수 없게 됩니다. 그 시점부터 Amazon Kinesis Data Analytics for SQL에 대한 지원을 더 이상 이용할 수 없습니다. 자세한 내용은 [Amazon Kinesis Data Analytics for SQL 애플리케이션 단종](discontinuation.md) 단원을 참조하십시오.

기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.

# 예: 스트림에서 핫스팟 감지(HOTSPOTS 함수)
<a name="app-hotspots-detection"></a>

Amazon Kinesis Data Analytics는 데이터에서 상대적으로 밀도가 높은 리전에 대한 정보를 찾아 반환할 수 있는 `HOTSPOTS` 함수를 제공합니다. 자세한 설명은 *Amazon Managed Service for Apache Flink SQL 참조*에서 [핫스팟](https://docs.aws.amazon.com/kinesisanalytics/latest/sqlref/sqlrf-hotspots.html)을 참조하십시오.

이 실습에서는 애플리케이션 코드를 작성해 애플리케이션의 스트리밍 소스에서 핫스팟을 찾습니다. 애플리케이션을 설정하려면 다음 단계를 수행합니다.

1. **스트리밍 소스 설정** – 다음과 같이 Kinesis 스트림을 설정하고 샘플 좌표 데이터를 작성합니다:

   ```
   {"x": 7.921782426109737, "y": 8.746265312709893, "is_hot": "N"}
   {"x": 0.722248626528026, "y": 4.648868803193405, "is_hot": "Y"}
   ```

   이 예에서는 Python 스크립트를 통해 스트림을 채우는 방법을 알아봅니다. `x` 및 `y` 값은 무작위로 생성되며, 특정 위치 주변에서 일부 기록이 클러스터링됩니다.

   `is_hot` 필드가 제공되어 스크립트가 의도적으로 핫스팟의 일부로서 값을 생성했는지 여부를 나타냅니다. 이는 핫스팟 감지 함수가 제대로 작동하고 있는지 평가하는 데 도움이 될 수 있습니다.

1. **애플리케이션 생성** – AWS Management Console를 사용하여 Kinesis Data Analytics 애플리케이션을 생성합니다. 스트리밍 소스를 애플리케이션 내 스트림(`SOURCE_SQL_STREAM_001`)으로 매핑하여 애플리케이션 입력을 구성합니다. 애플리케이션을 시작하면 Kinesis Data Analytics가 지속적으로 스트리밍 소스를 읽고 애플리케이션 내 스트림에 레코드를 삽입합니다.

   이 연습에서는 애플리케이션에 대해 다음 코드를 사용합니다.

   ```
   CREATE OR REPLACE STREAM "DESTINATION_SQL_STREAM" (
       "x" DOUBLE, 
       "y" DOUBLE, 
       "is_hot" VARCHAR(4),
       HOTSPOTS_RESULT VARCHAR(10000)
   ); 
   CREATE OR REPLACE PUMP "STREAM_PUMP" AS 
       INSERT INTO "DESTINATION_SQL_STREAM" 
       SELECT "x", "y", "is_hot", "HOTSPOTS_RESULT" 
       FROM TABLE (
           HOTSPOTS(   
               CURSOR(SELECT STREAM "x", "y", "is_hot" FROM "SOURCE_SQL_STREAM_001"), 
               1000, 
               0.2, 
               17)
       );
   ```

   코드가 `SOURCE_SQL_STREAM_001`에 있는 행을 읽고, 중요 핫스팟에 대해 이를 분석하고, 결과 데이터를 또 다른 애플리케이션 내 스트림(`DESTINATION_SQL_STREAM`)에 작성합니다. 펌프를 사용하여 행을 애플리케이션 내 스트림에 삽입합니다. 자세한 설명은 [애플리케이션 내 스트림과 펌프](streams-pumps.md) 섹션을 참조하십시오.

1. **출력 구성** – 애플리케이션이 외부 목적지인 또 다른 Kinesis 데이터 스트림으로 데이터를 보내도록 애플리케이션 출력을 구성합니다. 핫스팟 점수를 검토하고 어떤 점수가 핫스팟 발생(알림이 발생해야 함)을 나타내는지 판단합니다. AWS Lambda 함수를 사용하여 핫스팟 정보를 추가로 처리하고 알림을 구성할 수 있습니다.

1. **출력 확인** – 이 예에는 출력 스트림으로부터 데이터를 읽고 이를 그래픽으로 표현하는 JavaScript 애플리케이션이 포함되어 있습니다. 따라서 애플리케이션이 실시간으로 생성하는 핫스팟을 볼 수 있습니다.



이 연습에서는 미국 서부(오레곤)(`us-west-2`)을 사용하여 이러한 스트림과 애플리케이션을 생성합니다. 다른 리전을 사용하는 경우 그에 따라 코드를 업데이트합니다.

**Topics**
+ [1단계: 입력 및 출력 스트림 생성](app-hotspots-prepare.md)
+ [2단계: Kinesis Data Analytics 애플리케이션 생성](app-hotspot-create-app.md)
+ [3단계: 애플리케이션 출력 구성](app-hotspots-create-ka-app-config-destination.md)
+ [4단계: 애플리케이션 출력 확인](app-hotspots-verify-output.md)

# 1단계: 입력 및 출력 스트림 생성
<a name="app-hotspots-prepare"></a>

[핫스팟 예](app-hotspots-detection.md)를 위해 Amazon Kinesis Data Analytics 애플리케이션을 생성하기 전에 먼저 Kinesis 데이터 스트림 2개를 생성합니다. 스트림 중 하나를 애플리케이션의 스트리밍 소스로 구성하고 또 다른 스트림을 Kinesis Data Analytics가 애플리케이션 출력을 유지하는 목적지로 구성합니다.

**Topics**
+ [1.1단계: Kinesis 데이터 스트림 생성](#app-hotspots-create-two-streams)
+ [1.2단계: 샘플 레코드를 입력 스트림에 작성](#app-hotspots-write-sample-records-inputstream)

## 1.1단계: Kinesis 데이터 스트림 생성
<a name="app-hotspots-create-two-streams"></a>

이 섹션에서는 다음 2개의 Kinesis 데이터 스트림을 생성합니다: `ExampleInputStream` 및 `ExampleOutputStream`.

콘솔 또는 AWS CLI을(를) 사용하여 데이터 스트림을 생성합니다.
+ 콘솔을 사용하여 데이터 스트림을 생성:

  1. 에 로그인 AWS Management Console 하고 [https://console.aws.amazon.com/kinesis](https://console.aws.amazon.com/kinesis) Kinesis 콘솔을 엽니다.

  1. 탐색 창에서 **Data Streams(데이터 스트림)**를 선택합니다.

  1. **Kinesis 스트림 생성**을 선택한 다음 샤드가 하나인 스트림(`ExampleInputStream`이라고 함)을 생성합니다.

  1. 이전 단계를 반복하여 샤드가 하나인 스트림(`ExampleOutputStream`이라고 함)을 생성합니다.
+  AWS CLI을(를) 사용하여 데이터 스트림 생성:
  + 다음 Kinesis `create-stream` AWS CLI 명령을 사용하여 스트림(`ExampleInputStream` 및 `ExampleOutputStream`)을 생성합니다. 애플리케이션이 출력을 작성하기 위해 사용할 두 번째 스트림을 생성하려면 동일한 명령을 실행하여 스트림 명칭을 `ExampleOutputStream`으로 변경합니다.

    ```
    $ aws kinesis create-stream \
    --stream-name ExampleInputStream \
    --shard-count 1 \
    --region us-west-2 \
    --profile adminuser
                             
    $ aws kinesis create-stream \
    --stream-name ExampleOutputStream \
    --shard-count 1 \
    --region us-west-2 \
    --profile adminuser
    ```

## 1.2단계: 샘플 레코드를 입력 스트림에 작성
<a name="app-hotspots-write-sample-records-inputstream"></a>

이 단계에서는 Python 코드를 실행하여 샘플 레코드를 연속적으로 생성하고 `ExampleInputStream` 스트림에 작성합니다.

```
{"x": 7.921782426109737, "y": 8.746265312709893, "is_hot": "N"}
{"x": 0.722248626580026, "y": 4.648868803193405, "is_hot": "Y"}
```

1. Python 및 `pip`를 설치합니다.

   Python 설치에 관한 정보는 [Python](https://www.python.org/) 웹사이트를 참조하십시오.

   pip를 사용하여 종속 프로그램을 설치할 수 있습니다. pip 설치에 관한 정보는 pip 웹 사이트에 있는 [Installation](https://pip.pypa.io/en/stable/installing/)을 참조하십시오.

1. 다음 Python 코드를 실행합니다. 이 코드는 다음을 수행합니다.
   + (X, Y) 평면 어딘가에 잠재적 핫스팟을 생성합니다.
   + 각 핫스팟마다 1,000포인트 세트를 생성합니다. 이 포인트에서 20%가 핫스팟 주변에 클러스터링됩니다. 나머지는 전체 공간 내에 무작위로 생성됩니다.
   + `put-record` 명령은 JSON 레코드를 스트림에 작성합니다.
**중요**  
이 파일에는 귀하의 AWS 자격 증명이 포함되어 있으므로 이 파일을 웹 서버에 업로드하지 마십시오.

   ```
    
   import json
   from pprint import pprint
   import random
   import time
   import boto3
   
   STREAM_NAME = "ExampleInputStream"
   
   
   def get_hotspot(field, spot_size):
       hotspot = {
           "left": field["left"] + random.random() * (field["width"] - spot_size),
           "width": spot_size,
           "top": field["top"] + random.random() * (field["height"] - spot_size),
           "height": spot_size,
       }
       return hotspot
   
   
   def get_record(field, hotspot, hotspot_weight):
       rectangle = hotspot if random.random() < hotspot_weight else field
       point = {
           "x": rectangle["left"] + random.random() * rectangle["width"],
           "y": rectangle["top"] + random.random() * rectangle["height"],
           "is_hot": "Y" if rectangle is hotspot else "N",
       }
       return {"Data": json.dumps(point), "PartitionKey": "partition_key"}
   
   
   def generate(
       stream_name, field, hotspot_size, hotspot_weight, batch_size, kinesis_client
   ):
       """
       Generates points used as input to a hotspot detection algorithm.
       With probability hotspot_weight (20%), a point is drawn from the hotspot;
       otherwise, it is drawn from the base field. The location of the hotspot
       changes for every 1000 points generated.
       """
       points_generated = 0
       hotspot = None
       while True:
           if points_generated % 1000 == 0:
               hotspot = get_hotspot(field, hotspot_size)
           records = [
               get_record(field, hotspot, hotspot_weight) for _ in range(batch_size)
           ]
           points_generated += len(records)
           pprint(records)
           kinesis_client.put_records(StreamName=stream_name, Records=records)
   
           time.sleep(0.1)
   
   
   if __name__ == "__main__":
       generate(
           stream_name=STREAM_NAME,
           field={"left": 0, "width": 10, "top": 0, "height": 10},
           hotspot_size=1,
           hotspot_weight=0.2,
           batch_size=10,
           kinesis_client=boto3.client("kinesis"),
       )
   ```



**다음 단계**  
[2단계: Kinesis Data Analytics 애플리케이션 생성](app-hotspot-create-app.md)

# 2단계: Kinesis Data Analytics 애플리케이션 생성
<a name="app-hotspot-create-app"></a>

[핫스팟 예](app-hotspots-detection.md) 섹션에서 다음과 같이 Kinesis Data Analytics 애플리케이션을 생성합니다:
+ [1 단계](app-hotspots-prepare.md)에서 스트리밍 소스로 생성한 Kinesis 데이터 스트림을 사용하도록 애플리케이션 입력을 구성합니다.
+  AWS Management Console에서 제공된 애플리케이션 코드를 사용합니다.

**애플리케이션을 생성하는 방법**

1. [시작하기](https://docs.aws.amazon.com/kinesisanalytics/latest/dev/get-started-exercise.html) 연습 ([단계 3.1: 애플리케이션 만들기](get-started-create-app.md) 참조) 의 1, 2, 3단계에 따라 Kinesis Data Analytics 애플리케이션을 생성합니다.

   소스 구성에서 다음을 수행합니다:
   + [1단계: 입력 및 출력 스트림 생성](app-hotspots-prepare.md) 섹션에서 생성한 스트리밍 소스를 지정합니다.
   + 콘솔에서 스키마를 유추한 이후 스키마를 편집합니다. `x` 및 `y`열 유형이 `DOUBLE`로 설정되고 `IS_HOT` 열 유형이 `VARCHAR`로 설정되어야 합니다.

1. 다음 애플리케이션 코드를 사용합니다(이 코드를 복사하여 SQL 편집기에 붙여넣을 수 있습니다).

   ```
   CREATE OR REPLACE STREAM "DESTINATION_SQL_STREAM" (
       "x" DOUBLE, 
       "y" DOUBLE, 
       "is_hot" VARCHAR(4),
       HOTSPOTS_RESULT VARCHAR(10000)
   ); 
   CREATE OR REPLACE PUMP "STREAM_PUMP" AS 
       INSERT INTO "DESTINATION_SQL_STREAM" 
       SELECT "x", "y", "is_hot", "HOTSPOTS_RESULT" 
       FROM TABLE (
           HOTSPOTS(   
               CURSOR(SELECT STREAM "x", "y", "is_hot" FROM "SOURCE_SQL_STREAM_001"), 
               1000, 
               0.2, 
               17)
       );
   ```

   

1. SQL 코드를 실행하고 결과를 검토합니다.  
![\[rowtime, hotspot 및 hotspot_heat를 보여주는 SQL 코드 결과입니다.\]](http://docs.aws.amazon.com/ko_kr/kinesisanalytics/latest/dev/images/hotspot-v2-40.png)





**다음 단계**  
[3단계: 애플리케이션 출력 구성](app-hotspots-create-ka-app-config-destination.md)

# 3단계: 애플리케이션 출력 구성
<a name="app-hotspots-create-ka-app-config-destination"></a>

이 시점에 [핫스팟 예](app-hotspots-detection.md)에서 Amazon Kinesis Data Analytics 애플리케이션 코드를 보유하여 스트리밍 소스로부터 중요 핫스팟을 발견하고 히트 점수를 각각에게 할당합니다.

이제 애플리케이션 내 스트림에서 외부 목적지인 또 다른 Kinesis 데이터 스트림 (`ExampleOutputStream`)으로 에플리케이션 결과를 보낼 수 있습니다. 그런 다음 핫스팟 점수를 분석하고 핫스팟 히트에 대한 적절한 임계점을 판단할 수 있습니다. 이 애플리케이션을 더욱 확장하여 알림을 만들 수 있습니다.

**애플리케이션 출력을 구성하려면**

1. [ https://console.aws.amazon.com/kinesisanalytics](https://console.aws.amazon.com/kinesisanalytics)에서 Kinesis Data Analytics 콘솔을 엽니다.

1. SQL 편집기에서 [**Destination**]을 선택하거나 애플리케이션 대시보드에서 [**Add a destination**]을 선택합니다.

1. **Add a destination(대상 주소 추가)** 페이지에서 **Select from your streams(나의 스트림에서 선택)**을 선택합니다. 그런 다음 이전 섹션에서 생성한 `ExampleOutputStream` 스트림을 선택합니다.

   이제 애플리케이션 내 스트림 `DESTINATION_SQL_STREAM`에 애플리케이션이 작성하는 모든 레코드를 Amazon Kinesis Data Analytics가 유지하는 외부 대상이 생성되었습니다.

1. 선택적으로 `ExampleOutputStream` 스트림을 모니터링하고 알림을 보내 AWS Lambda 도록를 구성할 수 있습니다. 자세한 내용은 [Lambda 함수를 출력으로 사용](how-it-works-output-lambda.md) 단원을 참조하십시오. [4단계: 애플리케이션 출력 확인](app-hotspots-verify-output.md)에서 설명한 대로 Kinesis Data Analytics가 외부 목적지인 Kinesis 스트림 `ExampleOutputStream`에 기록하는 레코드를 검토할 수 있습니다.

**다음 단계**  
[4단계: 애플리케이션 출력 확인](app-hotspots-verify-output.md)

# 4단계: 애플리케이션 출력 확인
<a name="app-hotspots-verify-output"></a>

[핫스팟 예](app-hotspots-detection.md)의 이번 섹션에서 Scalable Vector Graphics(SVG) 제어에서 핫스팟 정보를 표시하는 웹 애플리케이션을 설정합니다.

1. 다음 콘텐츠를 가진 `index.html`이라는 파일을 생성합니다:

   ```
   <!doctype html>
   <html lang=en>
   <head>
       <meta charset=utf-8>
       <title>hotspots viewer</title>
   
       <style>
       #visualization {
         display: block;
         margin: auto;
       }
   
       .point {
         opacity: 0.2;
       }
   
       .hot {
         fill: red;
       }
   
       .cold {
         fill: blue;
       }
   
       .hotspot {
         stroke: black;
         stroke-opacity: 0.8;
         stroke-width: 1;
         fill: none;
       }
       </style>
       <script src="https://sdk.amazonaws.com/js/aws-sdk-2.202.0.min.js"></script>
       <script src="https://d3js.org/d3.v4.min.js"></script>
   </head>
   <body>
   <svg id="visualization" width="600" height="600"></svg>
   <script src="hotspots_viewer.js"></script>
   </body>
   </html>
   ```

1. 명칭이 `hotspots_viewer.js`인 동일한 디렉터리에 다음 내용을 포함한 파일을 생성합니다. 제공된 변수에 자격 증명 및 출력 스트림 명칭을 입력합니다.

   ```
   // Visualize example output from the Kinesis Analytics hotspot detection algorithm.
   // This script assumes that the output stream has a single shard.
   
   // Modify this section to reflect your AWS configuration
   var awsRegion = "",        // The  where your Kinesis Analytics application is configured.
       accessKeyId = "",      // Your Access Key ID
       secretAccessKey = "",  // Your Secret Access Key
       outputStream = "";     // The name of the Kinesis Stream where the output from the HOTSPOTS function is being written
   
   // The variables in this section should reflect way input data was generated and the parameters that the HOTSPOTS
   // function was called with.
   var windowSize = 1000, // The window size used for hotspot detection
       minimumDensity = 40,  // A filter applied to returned hotspots before visualization
       xRange = [0, 10],  // The range of values to display on the x-axis
       yRange = [0, 10];  // The range of values to display on the y-axis
   
   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   // D3 setup
   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   
   var svg = d3.select("svg"),
       margin = {"top": 20, "right": 20, "bottom": 20, "left": 20},
       graphWidth = +svg.attr("width") - margin.left - margin.right,
       graphHeight = +svg.attr("height") - margin.top - margin.bottom;
   
   // Return the linear function that maps the segment [a, b] to the segment [c, d].
   function linearScale(a, b, c, d) {
       var m = (d - c) / (b - a);
       return function(x) {
           return c + m * (x - a);
       };
   }
   
   // helper functions to extract the x-value from a stream record and scale it for output
   var xValue = function(r) { return r.x; },
       xScale = linearScale(xRange[0], xRange[1], 0, graphWidth),
       xMap = function(r) { return xScale(xValue(r)); };
   
   // helper functions to extract the y-value from a stream record and scale it for output
   var yValue = function(r) { return r.y; },
       yScale = linearScale(yRange[0], yRange[1], 0, graphHeight),
       yMap = function(r) { return yScale(yValue(r)); };
   
   // a helper function that assigns a CSS class to a point based on whether it was generated as part of a hotspot
   var classMap = function(r) { return r.is_hot == "Y" ? "point hot" : "point cold"; };
   
   var g = svg.append("g")
       .attr("transform", "translate(" + margin.left + "," + margin.top + ")");
   
   function update(records, hotspots) {
   
       var points = g.selectAll("circle")
           .data(records, function(r) { return r.dataIndex; });
   
       points.enter().append("circle")
           .attr("class", classMap)
           .attr("r", 3)
           .attr("cx", xMap)
           .attr("cy", yMap);
   
       points.exit().remove();
   
       if (hotspots) {
           var boxes = g.selectAll("rect").data(hotspots);
   
           boxes.enter().append("rect")
               .merge(boxes)
               .attr("class", "hotspot")
               .attr("x", function(h) { return xScale(h.minValues[0]); })
               .attr("y", function(h) { return yScale(h.minValues[1]); })
               .attr("width", function(h) { return xScale(h.maxValues[0]) - xScale(h.minValues[0]); })
               .attr("height", function(h) { return yScale(h.maxValues[1]) - yScale(h.minValues[1]); });
   
           boxes.exit().remove();
       }
   }
   
   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   // Use the AWS SDK to pull output records from Kinesis and update the visualization
   ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
   
   var kinesis = new AWS.Kinesis({
       "region": awsRegion,
       "accessKeyId": accessKeyId,
       "secretAccessKey": secretAccessKey
   });
   
   var textDecoder = new TextDecoder("utf-8");
   
   // Decode an output record into an object and assign it an index value
   function decodeRecord(record, recordIndex) {
       var record = JSON.parse(textDecoder.decode(record.Data));
       var hotspots_result = JSON.parse(record.HOTSPOTS_RESULT);
       record.hotspots = hotspots_result.hotspots
           .filter(function(hotspot) { return hotspot.density >= minimumDensity});
       record.index = recordIndex
       return record;
   }
   
   // Fetch a new records from the shard iterator, append them to records, and update the visualization
   function getRecordsAndUpdateVisualization(shardIterator, records, lastRecordIndex) {
       kinesis.getRecords({
           "ShardIterator": shardIterator
       }, function(err, data) {
           if (err) {
               console.log(err, err.stack);
               return;
           }
   
           var newRecords = data.Records.map(function(raw) { return decodeRecord(raw, ++lastRecordIndex); });
           newRecords.forEach(function(record) { records.push(record); });
   
           var hotspots = null;
           if (newRecords.length > 0) {
               hotspots = newRecords[newRecords.length - 1].hotspots;
           }
   
           while (records.length > windowSize) {
               records.shift();
           }
   
           update(records, hotspots);
   
           getRecordsAndUpdateVisualization(data.NextShardIterator, records, lastRecordIndex);
       });
   }
   
   // Get a shard iterator for the output stream and begin updating the visualization. Note that this script will only
   // read records from the first shard in the stream.
   function init() {
       kinesis.describeStream({
           "StreamName": outputStream
       }, function(err, data) {
           if (err) {
               console.log(err, err.stack);
               return;
           }
   
           var shardId = data.StreamDescription.Shards[0].ShardId;
   
           kinesis.getShardIterator({
               "StreamName": outputStream,
               "ShardId": shardId,
               "ShardIteratorType": "LATEST"
           }, function(err, data) {
               if (err) {
                   console.log(err, err.stack);
                   return;
               }
               getRecordsAndUpdateVisualization(data.ShardIterator, [], 0);
           })
       });
   }
   
   // Start the visualization
   init();
   ```

1. 실행 중인 첫 번째 섹션의 Python 코드를 통해 웹 브라우저에서 `index.html`을 엽니다. 다음과 같이 핫스팟 정보가 페이지에 표시됩니다.

     
![\[핫스팟 정보를 표시하는 Scalable Vector Graphics 다이어그램\]](http://docs.aws.amazon.com/ko_kr/kinesisanalytics/latest/dev/images/hotspots_visualizer.png)