Amazon Kinesis GetRecords Api Лучший подход

1

Я установил поток Kinesis в Amazon WebServices. Я также хочу выполнить следующие задачи:

  1. Поместите записи в один поток с одним осколком (С# Api) - УСПЕХ
  2. Также я написал Sample App, в котором несколько продюсеров работают над разными Stream - SUCCESS
  3. Кроме того, я настраиваю приложение примера для выполнения нескольких работников, которые помещают данные в один поток - УСПЕХ

Также я хочу иметь возможность принудительно выполнять SequenceNumberOrdering в Reacords.

Но настоящая боль - это работа пользователя GetRecords с использованием Kinesis С# Api.

Я создал образец приложения для записей. Проблема в том, что он не останавливает итерацию, даже если в потоке Kinesis нет записей. Также сохранение SequenceNumber в БД или каком-то файле и извлечение файла снова требует много времени - в чем преимущество использования Kinesis Stream для GetRecords?

Почему он продолжает итерацию, даже когда в потоке нет данных?

Я использовал следующий фрагмент кода для ССЫЛКИ;

  private static void GetFilesKinesisStream()
        {
            IAmazonKinesis kinesis = AWSClientFactory.CreateAmazonKinesisClient();
            try
            {
                ListStreamsResponse listStreams = kinesis.ListStreams();
                int numBuckets = 0;
                if (listStreams.StreamNames != null &&
                    listStreams.StreamNames.Count > 0)
                {
                    numBuckets = listStreams.StreamNames.Count;
                    Console.WriteLine("You have " + numBuckets + " Amazon Kinesis Streams.");
                    Console.WriteLine(string.Join(",\n", listStreams.StreamNames.ToArray()));

                    DescribeStreamRequest describeRequest = new DescribeStreamRequest();
                    describeRequest.StreamName = "******************";

                    DescribeStreamResponse describeResponse = kinesis.DescribeStream(describeRequest);
                    List<Shard> shards = describeResponse.StreamDescription.Shards;
                    foreach (Shard s in shards)
                    {
                        Console.WriteLine("shard: " + s.ShardId);
                    }

                    string primaryShardId = shards[0].ShardId;

                    GetShardIteratorRequest iteratorRequest = new GetShardIteratorRequest();
                    iteratorRequest.StreamName = "*********************";
                    iteratorRequest.ShardId = primaryShardId;
                    iteratorRequest.ShardIteratorType = ShardIteratorType.AT_SEQUENCE_NUMBER;
                    iteratorRequest.StartingSequenceNumber = "49544005271533118105145368110776211536226129690186743810";

                    GetShardIteratorResponse iteratorResponse = kinesis.GetShardIterator(iteratorRequest);
                    string iterator = iteratorResponse.ShardIterator;

                    Console.WriteLine("Iterator: " + iterator);
                    //Step #3 - get records in this iterator
                    GetShardRecords(kinesis, iterator);

                    Console.WriteLine("All records read.");
                    Console.ReadLine();
                }
                // sr.WriteLine("You have " + numBuckets + " Amazon S3 bucket(s).");
            }
            catch (AmazonKinesisException ex)
            {
                if (ex.ErrorCode != null && ex.ErrorCode.Equals("AuthFailure"))
                {
                    Console.WriteLine("The account you are using is not signed up for Amazon EC2.");
                    Console.WriteLine("You can sign up for Amazon EC2 at http://aws.amazon.com/ec2");
                }
                else
                {
                    Console.WriteLine("Caught Exception: " + ex.Message);
                    Console.WriteLine("Response Status Code: " + ex.StatusCode);
                    Console.WriteLine("Error Code: " + ex.ErrorCode);
                    Console.WriteLine("Error Type: " + ex.ErrorType);
                    Console.WriteLine("Request ID: " + ex.RequestId);
                }
            }
        }

        private static void GetShardRecords(IAmazonKinesis client, string iteratorId)
        {
            //create reqest
            GetRecordsRequest getRequest = new GetRecordsRequest();
            getRequest.Limit = 100;
            getRequest.ShardIterator = iteratorId;


            //call "get" operation and get everything in this shard range
            GetRecordsResponse getResponse = client.GetRecords(getRequest);
            //get reference to next iterator for this shard
            string nextIterator = getResponse.NextShardIterator;
            //retrieve records
            List<Record> records = getResponse.Records;

            //print out each record data value
            foreach (Record r in records)
            {
                //pull out (JSON) data in this record
                string s = Encoding.UTF8.GetString(r.Data.ToArray());
                Console.WriteLine("Record: " + s);
                Console.WriteLine("Partition Key: " + r.PartitionKey);
            }

            if (null != nextIterator)
            {
                //if there another iterator, call operation again
                GetShardRecords(client, nextIterator);
            }
        }
Теги:
amazon-web-services
amazon-kinesis

1 ответ

1

Почему потребитель кинезита продолжает итерацию после "конца" данных?

Потому что нет "конца". Кинези вроде как очередь, но не совсем. Подумайте об этом как о временном окне записанных событий. Вы не потребляете записи, вы анализируете пассивно записи, которые в настоящее время находятся в окне (какие жесткие коды amazon до 24 часов). Поскольку окно всегда перемещается, как только вы достигаете "последней" записи, он продолжает наблюдать в режиме реального времени. Новые записи могут появляться в любое время; потребитель не знает, что производителей нет.

Если вы хотите остановиться на основе какого-либо условия, это условие должно содержаться в вашей полезной нагрузке. Например, если вы хотите остановиться, когда вы добрались до "сейчас", частью вашей полезной нагрузки может быть метка времени, которую потребитель проверяет на близость к текущему времени.

  • 0
    Я хочу запускать Servie каждые 30 минут, как я могу получить записи после уже использованной записи ...
  • 0
    Запишите последний порядковый номер, который вы прочитали, и возобновите его с помощью итератора с типом AFTER_SEQUENCE_NUMBER .
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню