Создание ордеринг-службы, базирующейся на Kafka

Этот документ предполагает, что читатель знает, как поднять Kafka-кластер и ансамбль ZooKeeper, и как защитить их от неавторизованного доступа. Единственная цель этого документа - определить шаги, которые вам нужно совершить, чтобы ордеринг-узлы Fabric использовали ваш Kafka-кластер.

Для информации о ордеринг-службах на Raft, обратитесь к Конфигурация и администрирование Raft ордеринг-службы.

Общая информация

Каждый канал соответствует отдельную тему с одним разделом (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-серверов - перебор.

Далее:

  1. Ордереры: Запишите информацию, связанную с Kafka, в genesis-блок сети. Если вы используете configtxgen, отредактируйте configtx.yaml.

    • Orderer.OrdererType должен быть kafka.
    • Orderer.Kafka.Brokers должен содержать адрес хотя бы двух Kafka-брокеров вашего кластера в формате IP:port. Список может не быть полным.
  2. Ордереры: Установите максимальный размер блока. Каждый блок может иметь максимум Orderer.AbsoluteMaxBytes байт (не включая заголовки), это можно указать в configtx.yaml. Пусть вы выбрали значение A, запомните, это будет важно в 6 шаге.

  3. Ордереры: Создайте genesis-блок. Используйте configtxgen. Настройки, которые вы выбрали, распространяются на всю сеть, они общие для всех ордеринг-узлов. Запомните путь к genesis-блоку.

  4. 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)

  5. Ордереры: Указать каждому ордеринг-узлу на genesis-блок. Установите General.BootstrapFile в orderer.yaml на путь к genesis-блоку, созданному на шаге 5.

  6. Настройте узлы и Kafka-кластеры так, чтобы они могли взаимодействовать через SSL. (Опционально, но крайне рекомендуется.) Обратитесь к the Confluent guide для настройки со стороны Kafka, и настройте Kafka.TLS в orderer.yaml на каждом узле.

  7. Запустите узлы в следующем порядке: ансамбль 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 .