Экскурсия по исходному коду Kafka инициирована интервью

Kafka

Введение

Причина, по которой я написал эту статью, заключается в том, что интервьюер в предыдущем интервью спросил меня (внизу), и интервьюер сказал: «Вы сказали, что знакомы с Кафкой? Вы видели исходный код? Давайте поговорим о том, как Кафка сегмент журнала читается и записывается?»

Я тихо сказал в своем сердце: "Подождите... Я сказал, что видел немного исходного кода, а не миллион битов. Я знал, что не буду упоминать это предложение!", тогда что мне делать? остается только идти домой и ждать уведомления.

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

Структура хранения Кафки

Как мы все знаем, топик Kafka может иметь несколько разделов, а раздел — это на самом деле наименьшая структура чтения и хранения, то есть Consumer вроде как подписывается на топик, но на самом деле получает сообщения из раздела под топиком, и Продюсер тоже отправляет сообщения таким образом.

topic-partition关系

На приведенном выше рисунке представлена ​​общая логическая связь, а связь, сопоставленная с фактическим кодом на диске, показана на следующем рисунке:

Каждый раздел соответствует объекту журнала, который является подкаталогом на диске. В подкаталоге будет несколько групп сегментов журнала, то есть несколько сегментов журнала. Каждая группа сегментов журнала включает: файлы журнала сообщений (заканчиваются журналом) , индексные файлы смещения (с индексом), индексные файлы временных меток (заканчивающиеся на timeindex). На самом деле есть и другие файлы с суффиксами, например .txnindex, .deleted и так далее. Количество мест ограничено и пока упоминаться не будет.

Ниже приводится определение журнала

Ниже приведено определение сегмента журнала.

indexIntervalBytesМожно понять сколько сообщений вставляется и потом строится индекс.Это видно из этогоИндекс Кафки на самом деле является разреженным индексом., что позволяет избежать использования индексным файлом слишком большого объема памяти, поэтомуДержите больше индексов в памяти. Соответствует параметрам на стороне брокераlog.index.interval.bytesзначение, по умолчанию 4 КБ.

Фактический процесс поиска сообщения по индексу состоит в том, чтобы сначала найти файл, в котором находится индекс, по смещению, затем найти индекс, ближайший к цели по дихотомии, а затем последовательно пройтись по файлу сообщения, чтобы найти целевой файл. Временная сложность этой операцииO(log2n)+O(m), n — количество индексов в индексном файле, m — степень разреженности.

Это обмен пространства и времени, а после баланса структуры данных и алгоритма, прекрасно!

скажи это сноваrollJitterMs, что фактически является значением возмущения, а соответствующий параметр равенlog.roll.jitter.ms, речь собственно о сегментации лог сегментов,log.segment.bytes, Этот параметр управляет размером файла сегмента лога, по умолчанию 1G, то есть, когда хранилище файла превысит 1G, будет записан новый файл. Это измеряется по размеру, и есть параметр, которыйlog.segment.ms, сегментированные по времени.

После настройки этого параметра, если разделов много, то из-за того, что этот параметр глобальный, вам нужно делать много сегментации файлов одновременно, дисковый ввод-вывод не выдерживает, поэтому вам нужно установитьrollJitterMs, чтобы отвлечь их.

Что вы думаете о времени истечения срока действия кеша Redis? Добавьте случайное число ко времени истечения срока действия, чтобы предотвратить одновременное истечение срока действия большого количества кеша, чтобы кеш не разрушал базу данных. Посмотрите на знания проходят ах!

записать сегмент журнала

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

2. Убедитесь, что значение смещения допустимо, а окончательный вызовAbstractIndex.toRelative(..)метод, даже если оценивается, меньше ли смещение 0, больше ли оно максимального значения int.

3. Сообщение добавления фактически передается черезFileChannelЗапись сообщений, естественно, только в памяти и кэше страниц, то ли обновить диск, чтобы увидеть конфигурацию.

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

5. При необходимости обновите записи указателя.(bytesSinceLastIndexEntry > indexIntervalBytes)

Наконец, еще одна блок-схема

消息写入流程

чтение сегмента журнала

1. По смещению первого сообщения пройтиOffsetIndexНайдите физическое местоположение и размер соответствующего сообщения.

2. ПолучитьLogOffsetMetadata, метаданные содержат смещение сообщения, начальное смещение и физическое местоположение сегмента, в котором находится сообщение.

3. СуждениеminOneMessageЭтоtrue, если это так, он настроен так, чтобы всегда возвращать размер сообщения, фактически, когда одно сообщение больше, чемmaxSizeбыть возвращены, чтобы потребители не умерли от голода

4. Пересчитать максимумfetchSize, то есть (максимальное физическое смещение - физическое смещение начала этого сообщения) иadjustedMaxSizeМинимальное значение (я не очень хорошо понимаю эту волну, потому что предыдущая волна операцийadjustedMaxSizeУже минимальный размер сообщения)

5. ЗвонитеFileRecordsизsliceМетод считывает коллекцию сообщений указанного размера из указанного местоположения и создаетFetchDataInfoвернуть

Еще одна блок-схема:

消息读取流程

резюме

Встаньте с того места, где вы упали, не так ли?После этой волны операций мы не боимся, что в следующий раз нас спросит интервьюер.

Исходный код района не годится, хахахаха (надо сначала импульс)

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

Поэтому настоятельно рекомендуется начинать с исходного кода и понимать его из исходного кода. сказал сегодняappendа такжеreadЭто очень важная функция, но на первый взгляд она не сложна, так что не пугайтесь слова исходный код.

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

Тогда самое главное для меня — уметь притворяться (хахаха).

ситком

Лао Бай уставился на большой экран монитора: «Почему? Почему нагрузка ввода-вывода физического диска Kafka Broker внезапно стала такой высокой?». Несколько волосков стояли на голове старой белой, выглядевшей такой беспомощной.

"Установлено лиlog.segment.msпараметр ? пытатьсяlog.roll.jitter.msПошли." Когда Лао Бай поднял голову, я вышел из офиса, оставив после себя крепкую спину и блестящую лысину!

«Я лысый и сильный»