Ожидаемое поведение AWS Kinesis ShardIteratorType TRIM_HORIZON

Контекст: я не обязательно имею в виду приложение на основе KCL, это просто вызовы API Kinesis.

Предоставляет ли итератор TRIM_HORIZON тип итератора сразу самой ранней опубликованной записи в потоке (т. Е. Самой ранней из доступных во встроенном 24-часовом окне Kinesis) или просто итератора / курсора для некоторого периода времени, равного 24 часам назад, что вы должны затем использовать для продвижения по потоку, пока не достигнете самой ранней опубликованной записи?

Другими словами, если это не совсем понятно ....

При использовании типа итератора осколка TRIM_HORIZON, ожидаемое поведение начнется с возврата записей, которые были доступны 24 часа назад, НО если ноль записей было опубликовано ровно 24 часа назад, а вместо этого всего 3 часа назад, ваше приложение будет нужно итеративно опрашивать предыдущий 21 час, прежде чем он достигнет записей, опубликованных 3 часа назад?

Пример временной шкалы:

  1. 29 сентября, 5:00 - создание потока "foo" с 1 осколком.
  2. 29 сентября, 5:02 - публикация отдельной записи «Item = A» в потоке «foo».
  3. 29 сентября, 5:03. Выполните вызов GetShardIterator с TRIM_HORIZON в качестве типа итератора сегмента, затем выполните вызов GetRecords с этим итератором сегмента и получите запись «Item = A»
  4. 30 сентября, 7:02 - публикация второй записи «Item = B» в потоке «foo».
  5. 30 сентября, 7:03. Выполните вызов GetShardIterator с TRIM_HORIZON в качестве типа итератора осколка, затем выполните вызов GetRecords с этим итератором осколка. Чего следует ожидать в результате этого вызова? (Примечание: мы не запомнили / не использовали итератор сегментов из шага 3)

Для шага 5, описанного выше, прошло более 24 часов с момента публикации сообщения «Item = A» в потоке и только минута с момента публикации «Item = B». Будет ли новый итератор сегментов с TRIM_HORIZON немедленно предоставить вам самую раннюю доступную запись, или вам нужно будет продолжать итерацию до тех пор, пока не наступит период времени, когда что-то было опубликовано?

Я экспериментировал с Kinesis, и вчера или два дня назад все работало нормально (т. Е. Я публиковал и потреблял без каких-либо проблем). Я внес некоторые дополнительные изменения в свой код и сегодня снова начал публикацию. Когда я запустил своего потребителя, ничего не выходило даже после того, как он поработал несколько минут. Я пробовал публиковать и использовать в одно и то же время, но все равно ничего. После ручной игры с типом итератора AFTER_SEQUENCE_NUMBER и использования некоторых порядковых номеров из моих журналов потребителей, сделанных несколько дней назад, я смог добраться до моих недавно опубликованных сообщений. Но затем, если я вернусь к использованию типа TRIM_HORIZON, я не вижу вообще никаких сообщений.

Я просмотрел документы, но большинство найденных мной документов Предположим, вы используете KCL (на самом деле я изначально использовал KCL, но когда он начал давать сбои, я перешел к необработанным вызовам API) и упомянул, что у вас должно быть имя приложения и что таблицы DynamoDB используются для отслеживания состояния. Что, насколько я могу судить, неверно, если вы используете чистые вызовы Kinesis API или Kinesis CLI, которые я в конце концов попробовал. В конце концов, я написал чистый API-скрипт, чтобы начать с TRIM_HORIZON и бесконечно опрашивать, и в конце концов он достиг новых рекордов (потребовалось ~ 600 итераций; началось на 14 часов позже «сейчас», а записи были обнаружены примерно на 5 часов позже «сейчас»). Если это ожидаемое поведение, похоже, что формулировка в документации просто немного сбивает с толку / вводит в заблуждение:

TRIM_HORIZON - начать чтение с последней необрезанной записи в шарде в системе, которая является самой старой записью данных в шарде.

Я предположил (теперь это кажется неверным), что термин «самая старая запись данных» означает запись, которую я опубликовал в потоке, а не просто период времени в потоке.

Было бы здорово, если бы кто-нибудь мог помочь подтвердить / объяснить поведение, которое я наблюдаю.

Спасибо!


person jumand    schedule 30.09.2015    source источник


Ответы (2)


это в TRIM HORIZON или HORIZON, где происходит обрезка потока.

итератор сегментов может получить 0 записей при вызове, поэтому вам нужно будет продолжать итерацию, чтобы добраться до области, где находится самая старая запись (если вы нечасто нажимаете на поток или имеете временные промежутки). getRecords предоставит вам следующий итератор осколка, который вы можете использовать для итерации.

из документа: http://docs.aws.amazon.com/kinesis/latest/APIReference/API_GetRecords.html

Если в той части осколка, на которую указывает итератор, нет доступных записей, GetRecords возвращает пустой список. Обратите внимание, что для доступа к части осколка, содержащей записи, может потребоваться несколько вызовов.

person Mircea    schedule 30.09.2015
comment
Значит, это нормальное / ожидаемое поведение для GetRecords - возвращать 0 записей, даже если доступны новые записи? Что определяет, где происходит отключение? У Kinesis окно составляет 24 часа, но итератор сегментов не всегда запускается на 24 часа позже. В моем тесте отставание было на 14 часов, но рекордов там не было. Какое значение имеют эти 14 часов? - person jumand; 30.09.2015
comment
Отказ от ответственности: я не знаю, как Kinesis работает внутри. Я делаю предположения, основываясь на документации и поведении наблюдателя. Ответ: да, поведение, которое вы наблюдаете, я тоже видел. Иногда получение 0 записей после итератора осколка является нормальным. Я собираюсь предположить, что внутри Kinesis хранится карта идентификаторов shardIterator для записи порядковых номеров, и он повторно использует эти порядковые номера по мере продвижения горизонта обрезки. Также собираюсь угадать, что это зависит от того, когда происходит переработка и от того, что это делается лениво. - person Mircea; 01.10.2015
comment
также будет догадываться, что когда вы ищите что-то, что относится к порядковым номерам, он также использует сопоставления последовательностей id-> sharditerator, чтобы быстро найти ваши данные, а после этого он выполняет итерацию по записям, указанным идентификатором сегмента, и находит вашу последовательность. - person Mircea; 01.10.2015
comment
Спасибо за подтверждение, увидев подобное поведение. Заметили ли вы какую-либо тенденцию / постоянство задержки в значении MillisBehindLatest при использовании типа TRIM_HORIZON? Я хотел бы знать, какие подробности скрываются за этим. - person jumand; 01.10.2015

TRIM_HORIZON дает самую старую запись в потоке.

Просто это иногда при передаче TRIM_HORIZON в качестве shard_iterator_type: -

 Suppose the value of "millis_behind_latest" in the kinesis response is ~86399000 & your stream retention period is 24 hours(86400000) 

К тому времени, когда вы используете shard_iterator для извлечения записи, запись больше не находится в потоке, так как период хранения записи был превышен. Следовательно, вы получаете пустой результат, потому что срок действия самой старой записи истек и ее больше нет в потоке данных. Итак, shard_iterator теперь указывает на пустое место на диске.

Когда такое случается, возьмите значение next_shard_iterator и используйте get_records, чтобы еще раз получить записи данных кинезиса.

Еще одна вещь: мы не совсем знаем, как AWS управляет каждым сегментом в потоке данных. Как данные стираются и добавляются в них. Возможно, данные не хранятся в параллельных / смежных блоках памяти, и, следовательно, мы получаем пустые результаты между извлечением данных.

Продолжайте брать значение «next_shard_iterator» и используйте get_records, пока не получите значение 0 для «millis_behind_latest».

Надеюсь, этот ответ поможет. :)

person Vinu Joseph    schedule 12.02.2018