Kafka架构包括以下组件:

话题(Topic):是特定类型的消息流。消息是字节的有效负载(Payload),话题是消息的分类名或种子(Feed)名。

生产者(Producer):是能够发布消息到话题的任何对象。

服务代理(Broker):已发布的消息保存在一组服务器中,它们被称为代理(Broker)或Kafka集群。

消费者(Consumer):可以订阅一个或多个话题,并从Broker拉数据,从而消费这些已发布的消息。

Kafka API方法封装 kafka详解_数据

 

Kafka存储策略

1)kafka以topic来进行消息管理,每个topic包含多个partition,每个partition对应一个逻辑log,有多个segment组成。

2)每个segment中存储多条消息,消息id由其逻辑位置决定,即从消息id可直接定位到消息的存储位置,避免id到位置的额外映射。

3)每个part在内存中对应一个index,记录每个segment中的第一条消息偏移。

4)发布者发到某个topic的消息会被均匀的分布到多个partition上(或根据用户指定的路由规则进行分布),broker收到发布消息往对应partition的最后一个segment上添加该消息,当某个segment上的消息条数达到配置值或消息发布时间超过阈值时,segment上的消息会被flush到磁盘,只有flush到磁盘上的消息订阅者才能订阅到,segment达到一定的大小后将不会再往该segment写数据,broker会创建新的segment。

 

Kafka删除策略

1)N天前的删除。

2)保留最近的MGB数据。

 

Kafka broker

与其它消息系统不同,Kafka broker是无状态的。这意味着消费者必须维护已消费的状态信息。这些信息由消费者自己维护,broker完全不管(有offset managerbroker管理)。

从代理删除消息变得很棘手,因为代理并不知道消费者是否已经使用了该消息。Kafka创新性地解决了这个问题,它将一个简单的基于时间的SLA应用于保留策略。当消息在代理中超过一定时间后,将会被自动删除。

这种创新设计有很大的好处,消费者可以故意倒回到老的偏移量再次消费数据。这违反了队列的常见约定,但被证明是许多消费者的基本特征。

 

Push vs Pull

1)producer push data to broker,consumer pull data from broker

2)consumer pull的优点:consumer自己控制消息的读取速度和数量。

3)consumer pull的缺点:如果broker没有数据,则可能要pull多次忙等待,Kafka可以配置consumer long pull一直等到有数据。

 

Consumer Position

1)大部分消息系统由broker记录哪些消息被消费了,但Kafka不是。

2)Kafka由consumer控制消息的消费,consumer甚至可以回到一个old offset的位置再次消费消息。

 

Consumer:

* 读取消息,写log,处理消息。如果处理消息失败,log已经写入,则无法再次处理失败的消息,对应”At most once“。

* 读取消息,处理消息,写log。如果消息处理成功,写log失败,则消息会被处理两次,对应”At least once“。

* 读取消息,同时处理消息并把result和log同时写入。这样保证result和log同时更新或同时失败,对应”Exactly once“。

Kafka默认保证at-least-once delivery,容许用户实现at-most-once语义,exactly-once的实现取决于目的存储系统,kafka提供了读取offset,实现也没有问题。

 

读取操作测试:

require "kafka"
kafka = Kafka.new(seed_brokers: ["127.0.0.1:9092"])
kafka.deliver_message("Hello,World!", topic:"greetings")
 
# producer push data
producer = kafka.producer
producer.produce("long road!",topic:"topic_test")
puts producer.deliver_messages
 
# consumer pull data
kafka.topics
consumer = kafka.consumer(group_id:"my_consumer")
consumer.subscribe("topic_test")
 
consumer.each_message do |message|
  puts message.topic, message.partition
  puts message.offset, message.key, message.value
end

 

查看kafka数据:

kafka-console-consumer --zookeeper localhost:2181 --topic dataset_42

kafka-console-consumer --zookeeper localhost:2181 --topic dataset_42 --from-beginning