Создание ордеринг-службы, базирующейся на Kafka =============================================== .. _kafka-caveat: Этот документ предполагает, что читатель знает, как поднять Kafka-кластер и ансамбль ZooKeeper, и как защитить их от неавторизованного доступа. Единственная цель этого документа - определить шаги, которые вам нужно совершить, чтобы ордеринг-узлы Fabric использовали ваш Kafka-кластер. Для информации о ордеринг-службах на Raft, обратитесь к :doc:`raft_configuration`. Общая информация ---------------- Каждый канал соответствует отдельную тему с одним разделом (single-partition topic) в Kafka. Когда ордеринг-узел получает транзакцию через ``Broadcast`` RPC, он проверяет, что клиент, совершающий broadcast, имеет разрешение на запись в канал, а затем записывать транзакции в соответствующий раздел Kafka. Этот раздел также используется ордеринг-узлами, группирующими транзакции в блоки, сохраняющими их локально и далее распространяющими их клиентами через ``Deliver`` RPC. Для низкоуровневых подробностей, обратитесь к `документу, описывающему, как мы пришли к такой архитектуре `_. **Figure 8** - схематическое представление описанного выше процесса. Шаги ---- Пусть ``K`` и ``Z`` - количество узлов в кластере Kafka и ансамбле ZooKeeper: 1. Минимально возможное ``K`` - 4. (необходимо для CFT) 2. ``Z`` - 3, 5 или 7. Оно должно быть нечетными, чтобы избежать сценариев split-brain и быть больше 1. Более 7 ZooKeeper-серверов - перебор. Далее: 3. Ордереры: **Запишите информацию, связанную с Kafka, в genesis-блок сети**. Если вы используете ``configtxgen``, отредактируйте ``configtx.yaml``. * ``Orderer.OrdererType`` должен быть ``kafka``. * ``Orderer.Kafka.Brokers`` должен содержать адрес *хотя бы двух* Kafka-брокеров вашего кластера в формате ``IP:port``. Список может не быть полным. 4. Ордереры: **Установите максимальный размер блока.** Каждый блок может иметь максимум ``Orderer.AbsoluteMaxBytes`` байт (не включая заголовки), это можно указать в ``configtx.yaml``. Пусть вы выбрали значение ``A``, запомните, это будет важно в 6 шаге. 5. Ордереры: **Создайте genesis-блок.** Используйте ``configtxgen``. Настройки, которые вы выбрали, распространяются на всю сеть, они общие для всех ордеринг-узлов. Запомните путь к genesis-блоку. 6. Kafka-кластер: **Настройте ваших Kafka-брокеров.** Проверьте, что у каждого Kafka-брокера настроено три поля: * ``unclean.leader.election.enable = false`` — Консистентность данных крайне важна в блокчейн-сети. Мы не можем выбрать лидера, не синхронизированного с остальными узлами, или возможен риск перезаписи блокчейна. * ``min.insync.replicas = M`` — Такое ``M``, что ``1 < M < N`` (см. ``default.replication.factor`` ниже). Данные, сохраненные хотя бы на ``M`` реплик считаются in-sync и принадлежащими к in-sync replica set, ISR. В любом другом случае, операция записи возвращает ошибку. Тогда: * Если максимум ``N-M`` из ``N`` реплик не доступны, все операции проводятся в штатном режиме. * Иначе Kafka не может поддерживать больше ISR из ``M`` реплик, и она прекращает принимать операции по записи. Операции по чтению работают в штатном режиме. Канал принимает записи, когда хотя бы ``M`` реплик синхронизируются. * ``default.replication.factor = N`` — Такое ``N``, что ``N < K``. Репликационный фактор, равный ``N``, означает, что данные каждого канала реплицируются на ``N`` брокеров. Это кандидаты в ISR канала. Как уже было замечено в ``min.insync.replicas section`` выше, не все брокеры должны быть доступны все время. ``N`` должен быть *строго меньше* ``K``, так как нельзя будет создать канал, если работает меньше ``N`` брокеров, и, соответственно, никакого CFT не будет. Следовательно, минимальные ``M`` и ``N`` - 2 и 3. Такая конфигурация обеспечивает возможность создания новых каналов и записи во все каналы. * ``message.max.bytes`` и ``replica.fetch.max.bytes`` должны быть больше чем ``A``. Добавьте запас на заголовки, 1 MiB точно хватит. Должно соблюдаться следующее: :: Orderer.AbsoluteMaxBytes < replica.fetch.max.bytes <= message.max.bytes <= ``socket.request.max.bytes`` (``socket.request.max.bytes`` по умолчанию 100 MiB) 7. Ордереры: **Указать каждому ордеринг-узлу на genesis-блок**. Установите ``General.BootstrapFile`` в ``orderer.yaml`` на путь к genesis-блоку, созданному на шаге 5. 8. **Настройте узлы и Kafka-кластеры так, чтобы они могли взаимодействовать через SSL**. (Опционально, но крайне рекомендуется.) Обратитесь к `the Confluent guide `_ для настройки со стороны Kafka, и настройте ``Kafka.TLS`` в ``orderer.yaml`` на каждом узле. 9. **Запустите узлы в следующем порядке: ансамбль ZooKeeper, Kafka-кластер, узлы ордеринг-службы.** Совместимость версий протокола Kafka ------------------------------------ Fabric использует `клиентскую библиотеку sarama `_, версию, поддерживающую Kafka 0.10 до 1.0. Используя поле ``Kafka.Version`` в ``orderer.yaml``, вы можете настроить версию протокола Kafka, используемую для связи с брокерами кластера Kafka. Брокеры совместимы с более старыми версиями протоколов. Из-за этого, при обновлении брокеров, не обязательно обновлять ``Kafka.Version``, но это может привести к `проблемам с производительностью `_. Отладка ------- Установите переменную окружения ``FABRIC_LOGGING_SPEC`` на ``DEBUG`` и ``Kafka.Verbose`` на ``true`` в ``orderer.yaml`` . .. Licensed under Creative Commons Attribution 4.0 International License https://creativecommons.org/licenses/by/4.0/