annidy / notes

0 stars 0 forks source link

Kafka in practice #320

Open annidy opened 3 months ago

annidy commented 3 months ago

术语

  1. 消息:每一条消息包含3个要素:键(可选)、值和时间戳。为了提高效率,同属于一个主题和分区的消息会批次写入
  2. 主题和分区:主题是对消息进行分类,一个主题一般包含多个分区,一个分区可以存储多个主题(多对多关系,主要是为了通过多分区提高吞吐量);分区是broker的一块物理文件,写入同一个分区的消息可以保证FIFO;
  3. 生产者和消费者:生产者会将消息写入分区,分区器决定消息应该写入那个分区。消费者消费分区的消息,每个消费者有一个偏移量,表示现在消费到哪里了
  4. broker和集群:单台kafka服务器称之为broker,同nsq #316 一样,多台服务器组成一个集群,broker之间选举出partition leader。同时broker会保留一定量的历史消息。

消息格式

1. 1 byte CRC32 of the message
2. 1 byte "magic" identifier to allow format changes, value is 0 or 1
3. 1 byte "attributes" identifier to allow annotations on the message independent of the version
    bit 0 ~ 2 : Compression codec
        0 : no compression
        1 : gzip
        2 : snappy
        3 : lz4
    bit 3 : Timestamp type
        0 : create time
        1 : log append time
    bit 4 ~ 7 : reserved
4. (可选) 8 byte timestamp only if "magic" identifier is greater than 0
5. 4 byte key length, containing length K
6. K byte key
7. 4 byte payload length, containing length V
8. V byte payload

工作流

image

生产数据:

1.⽣产者从Kafka集群获取分区leader信息。如果指定了key,那么将根据key的hash选取某个partition,否则随机 2.⽣产者将消息发送给leader 3.leader将消息写入本地磁盘 4.follower从leader拉取消息数据 5.follower将消息写入本地磁盘后向leader发送ACK 6.leader收到所有的follower的ACK之后向生产者发送ACK。这一步生产者可以配置follwer ack为0、1、all

Kafka的设计更倾向于“最终一致性”和“高可用性”。不同与传统的RDS的leader,Kafka的leader是partition维度,能很大程度避免单机broker故障。

消费数据:

消费者被分到消费者组中。同一组的消费者均匀负载消息,Kafka会将每一条消息广播给消费组。这个和nsq的channel非常类似。 一个partition只能有一个consumer读,而一个consumer可以同时连接多个partition。当consumer发生变动时,kafka会自动重新平衡。因此partition的数量决定了消费者并发,当消费者的数量大于分区时,多余的消费者只能等待。

应用场景

同大部分消息中间件一样

  1. Data Pipelines。 支持1对N的消息场景
  2. Stream Processing。流式消息处理,包括ETL、日志、归档
  3. Event-Driven Microservices。

使用

Kafka需要java环境,建议通过Docker来部署,安装步骤

Note:如果允许外网访问需这样启动

docker run -d --name kafka-test -p 9092:9092 \
--link zookeeper-test \
--env KAFKA_ZOOKEEPER_CONNECT=zookeeper-test:2181 \
--env KAFKA_ADVERTISED_LISTENERS=PLAINTEXT://you-ip-address:9092 \
--env KAFKA_LISTENERS=PLAINTEXT://0.0.0.0:9092 \
--env KAFKA_LOG_DIRS=/kafka/logs \
-v kafka_vol:/kafka  \
wurstmeister/kafka:2.13-2.8.1

通常是通过脚本来管理Kafak,操作命令列表位于/opt/kafka/bin下

connect-distributed.sh        kafka-preferred-replica-election.sh
connect-mirror-maker.sh       kafka-producer-perf-test.sh
connect-standalone.sh         kafka-reassign-partitions.sh
kafka-acls.sh             kafka-replica-verification.sh
kafka-broker-api-versions.sh  kafka-run-class.sh
kafka-cluster.sh          kafka-server-start.sh
kafka-configs.sh          kafka-server-stop.sh
kafka-console-consumer.sh     kafka-storage.sh
kafka-console-producer.sh     kafka-streams-application-reset.sh
kafka-consumer-groups.sh      kafka-topics.sh
kafka-consumer-perf-test.sh   kafka-verifiable-consumer.sh
kafka-delegation-tokens.sh    kafka-verifiable-producer.sh
kafka-delete-records.sh       trogdor.sh
kafka-dump-log.sh         windows
kafka-features.sh         zookeeper-security-migration.sh
kafka-leader-election.sh      zookeeper-server-start.sh
kafka-log-dirs.sh         zookeeper-server-stop.sh
kafka-metadata-shell.sh       zookeeper-shell.sh
kafka-mirror-maker.sh

Client

第三方库 github.com/Shopify/sarama

消费组vs非消费组

消费组可以配置自动提交消费偏移,每隔一定时间后把消费编译上班给broker,broker会纪录偏移量,下次消费者重启时就可以从上次的位置消费。 非消费组不支持自动保存偏移,只能自己保存偏移位置,API支持设置消费偏移offset