web-dev-qa-db-ja.com

AWSキネシスストリームをファンアウトする方法は?

入力AWSKinesisストリームをN個の新しいKinesisストリームにファンアウト/チェーン/複製したい、入力Kinesisに書き込まれた各レコードがN個のストリームのそれぞれに表示されるようにします。

AWSサービスまたはオープンソースソリューションはありますか?

既成の解決策がある場合、私はそれを行うためのコードを書かないことを好みます。 AWS Kinesis firehose kinesisに出力できないため、解決策はありません。実行するのに費用がかかりすぎないのであれば、おそらくAWS Lambdaソリューションですか?

14
Gili Nachum

Amazon Kinesisストリームのファンアウトを達成する方法は2つあります

  • Amazon Kinesis Analyticsを使用して、レコードを追加のストリームにコピーします
  • AWS Lambda関数をトリガーして、レコードを別のストリームにコピーします

オプション1:Amazon Kinesis Analyticsを使用してファンアウトする

Amazon Kinesis Analytics を使用して、既存のストリームから新しいストリームを生成できます。

Amazon Kinesis Analyticsドキュメント から:

Amazon Kinesis Analyticsアプリケーションは継続的にストリーミングデータをリアルタイムで読み取り、処理します。 SQLを使用してアプリケーションコードを記述し、着信ストリーミングデータを処理して出力を生成します。次に、Amazon Kinesis Analyticsが設定された宛先に出力を書き込みます。

Amazon Kinesis Analytics flow diagram

ファンアウトは アプリケーションコード セクションに記載されています:

互いに独立して実行されるSQLクエリを作成することもできます。たとえば、同じアプリケーション内ストリームをクエリする2つのSQLステートメントを記述できますが、出力を異なるアプリケーション内ストリームに送信します。

私はこれを次のように実装することができました:

  • Input、output1、output2の3つのストリームを作成しました
  • 2つのAmazonKinesis Analyticsアプリケーションを作成しました:copy1、copy2

Amazon Kinesis AnalyticsSQLアプリケーションは次のようになります。

CREATE OR REPLACE STREAM "DESTINATION_SQL_STREAM"
(log VARCHAR(16));

CREATE OR REPLACE PUMP "COPY_PUMP1" AS
  INSERT INTO "DESTINATION_SQL_STREAM"
    SELECT STREAM "log" FROM "SOURCE_SQL_STREAM_001";

このコードは、inputストリームから選択してoutput1ストリームに出力するpump(継続的なselectステートメントと考えてください)を作成します。 output2ストリームに出力する別の同一のアプリケーションを作成しました。

テストするために、データをinputストリームに送信しました。

#!/usr/bin/env python

import json, time
from boto import kinesis

kinesis = kinesis.connect_to_region("us-west-2")
i = 0

while True:
  data={}
  data['log'] =  'Record ' + str(i)
  i += 1
  print data
  kinesis.put_record("input", json.dumps(data), "key")
  time.sleep(2)

しばらく実行してから、次のコードを使用して出力を表示しました。

from boto import kinesis

kinesis = kinesis.connect_to_region("us-west-2")
iterator = kinesis.get_shard_iterator('output1', 'shardId-000000000000', 'TRIM_HORIZON')['ShardIterator']
records = kinesis.get_records(iterator, 5)
print [r['Data'] for r in records['Records']]

出力は次のとおりです。

[u'{"LOG":"Record 0"}', u'{"LOG":"Record 1"}', u'{"LOG":"Record 2"}', u'{"LOG":"Record 3"}', u'{"LOG":"Record 4"}']

output2に対して再度実行したところ、同じ出力が表示されました。

オプション2:AWS Lambdaを使用する

多くのストリームにファンアウトしている場合、より効率的な方法はAWSLambda関数を作成することです。

  • Amazon Kinesisストリームレコードによってトリガー
  • そのレコードを複数のAmazonKinesisの「出力」ストリームに書き込みます

Lambda関数に命名規則に基づいて出力ストリームを自己検出させることもできます(たとえば、app-output-*という名前のストリーム)。

18
John Rotenstein

ラムダを使用してファンアウトを提供するAmazonラボのgithubリポジトリがあります。 https://github.com/awslabs/aws-lambda-fanouthttps://medium.com/retailmenot-engineering/building-a-high-throughput-data-pipeline-with-kinesis-lambda-and-)の「同期Lambda呼び出しを非同期呼び出しに変換する」もお読みください。 dynamodb-7d78e992a02d 、これは真の非同期処理を構築するために重要です。

1
Hammer

AWSFirehoseまたはAWSLambdaを必要としないKinesisストリームをファンアウトするための2つのAWSネイティブソリューションがあります。

  1. Kafkaコンシューマーグループと同様に、Kinesisにはアプリケーション名があります。ストリームへのすべてのコンシューマーは一意のアプリケーション名を提供できます。2つのコンシューマーが同じアプリケーション名を持っている場合、メッセージはそれらの間で配信されます。ストリームをファンアウトし、ストリームから同じメッセージを受信するコンシューマーに異なるアプリケーション名を指定します。Kinesisは、内部で新しいDynamoDBテーブルを作成して、新しいアプリケーションごとに各コンシューマーを追跡できるようにします。異なるレートでメッセージを消費するなど。
  2. Kinesis Enhanced Fan-Out を使用してスループットを高めます(最大2MiB /秒)。これは、グローバル読み取り制限にはカウントされません。執筆時点では、ストリームごとに20の「拡張ファンアウト」コンシューマーの制限があります。

これらの2つのオプションについて私が知っている限り、注意点の1つは、 Kinesis Client Library(KCL) (生の AWS SDK ではなく)を使用する必要があるということです。

0
Tri Q Tran