web-dev-qa-db-ja.com

pythonでキネシスストリームを使用する

Python経由でAWS Kinesisストリームを使用する方法を示す適切な例を見つけることができないようです。誰かが私が調査できるいくつかの例を提供してくれませんか?

ベスト

23
aliirz

この質問にはすでに回答していますが、botoを直接使用するのではなく、Kinesis Client Library (KCL) for Pythonを使用することを将来の読者に検討することをお勧めします。複数のコンシューマーインスタンスがある場合、ストリームからの消費、および/またはシャード構成の変更を簡素化します。

https://aws.Amazon.com/blogs/aws/speak-to-kinesis-in-python/

KCLが提供するものの詳細 完全な列挙

  • ストリームに接続します
  • シャードを列挙します
  • 他のワーカー(存在する場合)とのシャード関連付けを調整します
  • 管理するすべてのシャードのレコードプロセッサをインスタンス化します
  • ストリームからデータレコードをプルします
  • レコードを対応するレコードプロセッサにプッシュします。
  • チェックポイント処理レコード(DynamoDBを使用するため、コードでチェックポイント値を手動で永続化する必要はありません)
  • ワーカーインスタンスカウントが変更されたときにシャードとワーカーの関連付けのバランスをとります
  • シャードが分割またはマージされたときにシャードとワーカーの関連付けのバランスをとります

太字の項目は、KCLがbotoよりも重要な価値を提供していると私が思う項目です。しかし、ユースケースによってはbotoの方がはるかに単純な場合があります。

7
jumand

boto.kinesisを使用する必要があります。

from boto import kinesis

ストリームを作成した後:

ステップ1:awsキネシスに接続する:

auth = {"aws_access_key_id":"id", "aws_secret_access_key":"key"}
connection = kinesis.connect_to_region('us-east-1',**auth)

ステップ2:ストリーム情報を取得します(アクティブな場合、シャードの数など)。

tries = 0
while tries < 10:
    tries += 1
    time.sleep(1)
    try:
        response = connection.describe_stream('stream_name')   
        if response['StreamDescription']['StreamStatus'] == 'ACTIVE':
            break 
    except :
        logger.error('error while trying to describe kinesis stream : %s')
else:
    raise TimeoutError('Stream is still not active, aborting...')

ステップ3:すべてのシャードIDを取得し、共有IDごとにシャードイテレーターを取得します。

shard_ids = []
stream_name = None 
if response and 'StreamDescription' in response:
    stream_name = response['StreamDescription']['StreamName']                   
    for shard_id in response['StreamDescription']['Shards']:
         shard_id = shard_id['ShardId']
         shard_iterator = connection.get_shard_iterator(stream_name, shard_id, shard_iterator_type)
         shard_ids.append({'shard_id' : shard_id ,'shard_iterator' : shard_iterator['ShardIterator'] })

ステップ4:各シャードのデータを読み取る

limitは、受信するレコードの制限です。 (最大10 MBを受け取ることができます)shard_iteratorは、前のステップから共有されます。

tries = 0
result = []
while tries < 100:
     tries += 1
     response = connection.get_records(shard_iterator = shard_iterator , limit = limit)
     shard_iterator = response['NextShardIterator']
     if len(response['Records'])> 0:
          for res in response['Records']: 
               result.append(res['Data'])                  
          return result , shard_iterator

get_recordsへの次の呼び出しでは、前のget_recordsの結果とともに受け取ったshard_iteratorを使用する必要があります。

note:get_recordsへの1回の呼び出しで、(制限=なし)空のレコードを受け取ることができます。制限付きでget_recordsを呼び出すと、同じパーティションキーにあるレコードを取得します(データをストリームに入れるときは、パーティションキーを使用する必要があります:

connection.put_record(stream_name, data, partition_key)
33
Eyal Ch