Эта страница переведена с английского языковой моделью. При любом расхождении верен английский оригинал.
Сегменты, разделение и слияние
Сегмент обеспечивает фиксированную долю пропускной способности потока. Разделение или слияние закрывает сегменты и открывает дочерние, которые читаются после родительских.
Схема текстом
- Сегмент 0, закрыт конечный порядковый номер → Сегмент 1, закрыт нижняя половина 0: разделение
- Сегмент 0, закрыт конечный порядковый номер → Сегмент 2, закрыт верхняя половина 0: разделение
- Сегмент 1, закрыт нижняя половина 0 → Сегмент 3, открыт родители 1 и 2: слияние
- Сегмент 2, закрыт верхняя половина 0 → Сегмент 3, открыт родители 1 и 2: слияние
- Дочерний сегмент читается, только когда каждый родитель прочитан до конца, поэтому записи одного ключа сохраняют порядок при изменении
Каждый сегмент принимает на запись до 1 МБ или 1000 записей в секунду. На чтение он отдаёт до 2 МБ
в секунду и не больше пяти вызовов GetRecords в секунду. Эти пять вызовов делят все потребители,
которые читают сегмент, поэтому этот предел - не про оплату: он определяет, как часто сегмент
вообще можно прочитать. У потока в режиме выделенной ёмкости столько сегментов, сколько ему
задали, а поток в режиме по запросу получает столько, сколько нужно его трафику.
Разделение делит диапазон хеш-ключей одного сегмента между двумя дочерними. Слияние объединяет два
соседних сегмента в один. В обоих случаях родительские сегменты закрываются: ListShards сообщает
для них конечный порядковый номер, новых записей они не принимают, а имеющиеся хранят, пока не
истечёт срок хранения. Читатель, дошедший до конца закрытого сегмента, не получает следующего
итератора: это SHARD_END.
Записи одного ключа могут лежать сначала в родительском сегменте, а затем в дочернем. Чтобы
сохранить их порядок, потребитель читает каждый родительский сегмент до конца, прежде чем читать
дочерний. Крейт проверяет это для каждого дочернего сегмента, прежде чем взять его аренду: каждый
родитель должен быть помечен SHARD_END в хранилище аренд или пропасть из списка сегментов,
потому что его удалил срок хранения. Закрытый родитель без контрольной точки считается
прочитанным, когда подписка начинает с конца потока, потому что его старые записи всё равно
пропускаются. Читатель записывает SHARD_END, только когда завершились все доставки его сегмента.
Подписка заново перечисляет сегменты каждые 10 секунд, поэтому дочерний сегмент открывается в
течение этого времени после того, как его родители прочитаны. Читатель дочернего сегмента
продолжает с его контрольной точки, как показывает страница Чтение. Дочерний сегмент
без контрольной точки открывается с самой старой записи, поэтому то, что в него записали до запуска
читателя, тоже прочитывается. create_if_missing(shards) создаёт отсутствующий поток в режиме
выделенной ёмкости с заданным числом сегментов и ждёт до минуты, пока он не станет доступен.
Эта модель взята у самого Amazon Kinesis Data Streams (квоты и ограничения, режимы ёмкости, разделение и слияние, чтение после разделения и слияния).