Сообщения Kafka хранятся или кэшируются на диске.Принято считать, что чтение и запись данных на диск снижает производительность, поскольку адресация занимает больше времени, но на самом деле одной из характеристик Kafka является высокая пропускная способность.
Даже для обычных серверов Kafka может легко поддерживать миллионы запросов на запись в секунду, превосходя большинство промежуточного программного обеспечения сообщений.Эта функция также делает Kafka широко используемой в сценариях с большими объемами данных, таких как обработка журналов.
Ниже приводится анализ того, почему Kafka так быстр с точки зрения двух аспектов записи и чтения данных.
ввод данных
Kafka будет записывать полученные сообщения на жесткий диск и никогда не потеряет данные. Для оптимизации скорости записи Kafka использует два метода: последовательную запись и MMFile.
последовательная запись
Скорость чтения и записи на диск зависит от того, как вы его используете, то есть последовательное чтение и запись или случайное чтение и запись. В случае последовательного чтения и записи скорость чтения и записи диска может быть равна скорости памяти в некоторых оптимизированных сценариях.
Поскольку жесткий диск представляет собой механическую структуру, каждое чтение и запись будут адресовать -> писать, где адресация — это «механическое действие», которое занимает больше всего времени. Таким образом, жесткий диск больше всего ненавидит случайный ввод-вывод и больше всего любит последовательный ввод-вывод. Чтобы повысить скорость чтения и записи на жесткий диск, Kafka использует последовательный ввод-вывод.
И Linux также имеет больше оптимизаций чтения и записи для диска, включая упреждающее чтение и отложенную запись, дисковый кеш и т. д. Если эти операции выполняются в памяти, во-первых, накладные расходы памяти для объектов JAVA очень велики, а во-вторых, с увеличением данных в памяти кучи время GC JAVA станет очень большим.Использование дисковых операций имеет следующие преимущества:
- Скорость последовательного чтения и записи диска превышает скорость произвольного чтения и записи памяти
- Эффективность GC JVM низкая, а использование памяти велико. Этой проблемы можно избежать, используя диск
- Дисковый кеш по-прежнему доступен после холодной загрузки системы
На приведенном выше рисунке показано, как Kafka записывает данные. Каждый раздел на самом деле является файлом. После получения сообщения Kafka вставит данные в конец файла (виртуальное поле).
У этого метода есть недостаток — нет возможности удалить данные, поэтому Kafka не будет удалять данные, он сохранит все данные, у каждого потребителя (Consumer) есть смещение для каждой темы, чтобы представить количество прочитанных фрагментов данных.
Для двух потребителей у Consumer1 есть два смещения, соответствующие Partition0 и Partition1 соответственно (при условии, что каждая тема имеет Partition); у Consumer2 есть смещение, соответствующее Partition2. Это смещение сохраняется клиентским SDK, а Kafka's Broker полностью игнорирует существование этой штуки, при нормальных обстоятельствах SDK сохранит его в zookeeper. (Поэтому вам нужно предоставить потребителю адрес зоопарка).
Если вы не удалите жесткий диск, он определенно будет заполнен, поэтому Kakfa предлагает две стратегии удаления данных. Один основан на времени, а другой на размере файла раздела. Для конкретной конфигурации, пожалуйста, обратитесь к его конфигурационному документу.
Memory Mapped Files
Даже если она будет записываться на жесткий диск последовательно, скорость доступа жесткого диска все равно невозможно догнать в памяти. Таким образом, данные Kafka не записываются на жесткий диск в режиме реального времени, а в полной мере использует память подкачки современной операционной системы, чтобы использовать память для повышения эффективности ввода-вывода.
Файлы с отображением памяти (далее именуемые mmap) также преобразуются в файлы с отображением памяти, которые обычно могут представлять файлы данных 20G в 64-разрядной операционной системе.Его принцип работы заключается в непосредственном использовании страницы операционной системы для реализации прямого отображения файлов в физическую память. После завершения сопоставления ваши операции с физической памятью будут синхронизированы с жестким диском (если применимо, с операционной системой).
Через mmap процесс читает и записывает память (разумеется, память виртуальной машины) так же, как читает и записывает жесткие диски, и ему не нужно заботиться о размере памяти.
Использование этого метода может значительно улучшить ввод-вывод, устраняя накладные расходы на копирование из пользовательского пространства в пространство ядра (вызов чтения файла сначала поместит данные в память пространства ядра, а затем скопирует их в память). пользовательского пространства. Также есть очевидный недостаток - ненадежность, данные, записанные в mmap, фактически не записываются на жесткий диск, а операционная система фактически записывает данные на жесткий диск только тогда, когда программа активно вызывает флеш. Kafka предоставляет параметр-producer.type для управления активным сбросом.Если Kafka записывает в mmap, он немедленно сбрасывается, а затем возвращается в Producer, который называется синхронным (синхронным); после записи в mmap немедленно возвращается Producer без вызов флеша называется асинхронным (async).
читать данные
Какие оптимизации делает Kafka при чтении с диска?
Реализовать нулевое копирование на основе файла отправки
В традиционном режиме, когда необходимо передать файл, конкретные детали процесса следующие:
- Вызывается функция чтения, и данные файла копируются в буфер ядра.
- Функция чтения возвращается, и данные файла копируются из буфера ядра в пользовательский буфер.
- Функция записи вызывается для копирования данных файла из пользовательского буфера в связанный с сокетом буфер ядра.
- Данные копируются из буфера сокета в соответствующий механизм протокола.
Приведенные выше детали представляют собой традиционный метод чтения/записи для передачи файлов по сети.Мы видим, что в этом процессе данные файла фактически подвергаются четырем операциям копирования:
Жесткий диск—>база ядра—>буфер пользователя—>буфер, связанный с сокетом—>механизм протокола
Системный вызов sendfile позволяет уменьшить количество копий, указанных выше, и повысить производительность передачи файлов.
В ядре версии 2.1 был введен системный вызов sendfile для упрощения передачи данных по сети и между двумя локальными файлами. Введение sendfile не только уменьшает копирование данных, но и уменьшает переключение контекста.
sendfile(socket, file, len);
Процесс запуска выглядит следующим образом:
- системный вызов sendfile, данные файла копируются в буфер ядра
- Затем скопируйте из буфера ядра в буфер, связанный с сокетом в ядре.
- Наконец, скопируйте буферы, связанные с сокетами, в механизм протокола.
По сравнению с традиционным методом чтения/записи файл отправки, представленный в ядре 2.1, уменьшил копирование файла из буфера ядра в буфер пользователя, а затем из буфера пользователя в буфер, связанный с сокетом. результаты файлового дескриптора Изменено, sendfile реализует более простой способ, снова уменьшая одну операцию копирования.
В веб-серверах, таких как apache, nginx и lighttpd, есть конфигурация, связанная с sendfile.Использование sendfile может значительно повысить производительность передачи файлов.
Kafka хранит все сообщения в файлах одно за другим. Когда потребителям нужны данные, Kafka напрямую отправляет файл потребителю. Используя mmap в качестве метода чтения и записи файла, он напрямую передает его в sendfile.
Массовое сжатие
Во многих случаях узким местом системы является не ЦП или диск, а сетевой ввод-вывод, особенно для конвейеров данных, которым необходимо отправлять сообщения между центрами обработки данных в глобальной сети. Сжатие данных будет потреблять небольшое количество ресурсов ЦП, но для kafka следует больше учитывать сетевой ввод-вывод.
- Если каждое сообщение сжато, но степень сжатия относительно низкая, то Kafka использует пакетное сжатие, то есть несколько сообщений сжимаются вместе, а не одно сообщение.
- Kafka позволяет использовать рекурсивные коллекции сообщений, пакеты сообщений могут передаваться в сжатом виде, а также могут оставаться сжатыми в журнале до тех пор, пока не будут распакованы потребителем.
- Kafka поддерживает несколько протоколов сжатия, включая протоколы сжатия Gzip и Snappy.
Суммировать
Секрет скорости Kafka заключается в том, что он превращает все сообщения в пакетный файл и выполняет разумное пакетное сжатие, чтобы уменьшить потери сетевого ввода-вывода и повысить скорость ввода-вывода через mmap.При записи данных в конце добавляется один раздел.Поэтому , скорость оптимальная, при чтении данных прямо бурно выводится с помощью sendfile.