Kafka

1.基本理解

-kafka是基于JMS实现的,构建企业中统一的、高通量的、低延时的消息平台,此消息平台是基于生产者和消费者模式的。

2.架构

组件:Cluster、broker、Producer、consumer、Topic

3.Shell操作

创建订单的topic

bin/kafka-topics.sh --create --zookeeper zk01:2181 --replication-factor 1 --partitions 1 --topic order

生产数据

bin/kafka-console-producer.sh --broker-list kafka01:9092 --topic order

消费数据

bin/kafka-console-consumer.sh --zookeeper zk01:2181 --from-beginning --topic order

4.JavaApi操作

<dependency>
    <groupId>org.apache.kafka</groupId>
    <artifactId>kafka-clients</artifactId>
    <version>0.11.0.1</version>
</dependency>
/**
 * 订单的生产者代码
 */
public class OrderProducer {
    public static void main(String[] args) throws InterruptedException {
        /* 1、连接集群,通过配置文件的方式
         * 2、发送数据-topic:order,value
         */
        Properties props = new Properties();
        props.put("bootstrap.servers", "node01:9092");
        props.put("acks", "all");
        props.put("retries", 0);
        props.put("batch.size", 16384);
        props.put("linger.ms", 1);
        props.put("buffer.memory", 33554432);
        props.put("key.serializer",
                "org.apache.kafka.common.serialization.StringSerializer");
        props.put("value.serializer",
                "org.apache.kafka.common.serialization.StringSerializer");
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<String, String>(props);
        for (int i = 0; i < 1000; i++) {
            // 发送数据 ,需要一个producerRecord对象,最少参数 String topic, V value
            kafkaProducer.send(new ProducerRecord<String, String>("order", "订单信息!"+i));
            Thread.sleep(100);
        }
    }
}
/**
 * 消费订单数据--- javaben.tojson
 */
public class OrderConsumer {
    public static void main(String[] args) {
        // 1\连接集群
        Properties props = new Properties();
        props.put("bootstrap.servers", "node01:9092");
        props.put("group.id", "test");
        props.put("enable.auto.commit", "true");
        props.put("auto.commit.interval.ms", "1000");
        props.put("key.deserializer",
                "org.apache.kafka.common.serialization.StringDeserializer");
        props.put("value.deserializer",
                "org.apache.kafka.common.serialization.StringDeserializer");
        KafkaConsumer<String, String> kafkaConsumer = new KafkaConsumer<String, String>(props);
//        2、发送数据 发送数据需要,订阅下要消费的topic。  order
        kafkaConsumer.subscribe(Arrays.asList("order"));
        while (true) {
            // jdk queue offer插入、poll获取元素。 blockingqueue put插入原生,take获取元素
            ConsumerRecords<String, String> consumerRecords = kafkaConsumer.poll(100);
            for (ConsumerRecord<String, String> record : consumerRecords) {
                System.out.println("消费的数据为:" + record.value());
            }
        }
    }
}

5.分片与副本机制

分片

当数据量非常大的时候,一个服务器存放不了,就将数据分成两个或者多个部分,存放在多台服务器上。每个服务器上的数据,叫做一个分片。

副本机制

当数据只保存一份的时候,有丢失的风险。为了更好的容错和容灾,将数据拷贝几份,保存到不同的机器上。

6.消息不丢失机制

生产者端

同步消息有三种状态(0:生产者只负责发送数据,1:某个partition的leader收到数据给出响应,-1:某个partition的所有副本都收到数据后给出响应)。生产者等待10S,如果broker没有给出ack响应,就认为失败。生产者重试3次,如果还没有响应,就报错。

异步消息:先将数据保存在生产者端的buffer中。Buffer大小是2万条。满足数据阈值或者数量阈值其中的一个条件就可以发送数据。发送一批数据的大小是500条。

如果broker迟迟不给ack,而buffer又满了。开发者可以设置是否直接清空buffer中的数据。

broker端

broker端的消息不丢失,其实就是用partition副本机制来保证。同步消息设置成-1

消费者端

只要记录offset值,消费者端不会存在消息不丢失的可能。只会重复消费。对于重复消费,可以去重:将消息的唯一标识保存到外部介质中,每次消费处理时判断是否处理过。如果使用了storm,要开启storm的ackfail机制;如果没有使用storm,确认数据被完成处理之后,再更新offset值。低级API中需要手动控制offset值。

7.消息存储与查询机制

消息存储

消息存储使用segment段中,segment段中有两个核心的文件一个是log,一个是index。 当log文件等于1G时,新的会写入到下一个segment中。一个segment段差不多会存储70万条数据。

查询

读取offset=12345的message,需要先找到segment file,然后根据index找到12345对应的log中的具体文件,使用的是二分查找。

8.生产者数据分发策略

kafka在数据生产的时候,有一个数据分发策略。如果指定了partition,生产就不会调用DefaultPartitioner.partition()方法;如果指定key,使用hash算法,Utils.toPositive(Utils.murmur2(keyBytes)) % numPartitions;如果既没有指定partition,也没有key的情况下如何发送数据,使用轮询的方式发送数据。

9.消费者的负载均衡

如果消费组中有多于partition数量的消费者,那么一定会有消费者无法消费数据。因为负载均衡策略规定,多出来的消费者处于空闲状态,所以真实的解决方案是修改topic的partition数量或者减少消费者处理时间,提高处理速度。

提高消费速度
  1. 增加分区
  2. 关闭autocommit(偏移量手工提交可以按需减少分区偏移量的更新,有利于提升消费速度)
  3. 增加单次拉取消息的大小(大量消息的场景下可减少拉取消息的次数)
  4. 如果不考虑数据一致性,可以将key值平均一下,这样每个分区的消息大小都差不多,有利于负载均衡
  5. 如果没有开启压缩,最好开启压缩(需要重启集群),可大大提高通信效率,有得消费速度提升

10.应用场景

消息
  • kafka更好的替换传统的消息系统,消息系统被用于各种场景(解耦数据生产者,缓存未处理的消息,等),与大多数消息系统比较,kafka有更好的吞吐量,内置分区,副本和故障转移,这有利于处理大规模的消息。
  • 根据我们的经验,消息往往用于较低的吞吐量,但需要低的端到端延迟,并需要提供强大的耐用性的保证。
  • 在这一领域的kafka比得上传统的消息系统,如的ActiveMQ或RabbitMQ的。
网站活动追踪
  • kafka原本的使用场景:用户的活动追踪,网站的活动(网页游览,搜索或其他用户的操作信息)发布到不同的话题中心,这些消息可实时处理,实时监测,也可加载到Hadoop或离线处理数据仓库。
  • 每个用户页面视图都会产生非常高的量。
指标
  • kafka也常常用于监测数据。分布式应用程序生成的统计数据集中聚合。
日志聚合
  • 许多人使用Kafka作为日志聚合解决方案的替代品。日志聚合通常从服务器中收集物理日志文件,并将它们放在中央位置(可能是文件服务器或HDFS)进行处理。Kafka抽象出文件的细节,并将日志或事件数据更清晰地抽象为消息流。这允许更低延迟的处理并更容易支持多个数据源和分布式数据消费。
流处理
  • kafka中消息处理一般包含多个阶段。其中原始输入数据是从kafka主题消费的,然后汇总,丰富,或者以其他的方式处理转化为新主题,例如,一个推荐新闻文章,文章内容可能从“articles”主题获取;然后进一步处理内容,得到一个处理后的新内容,最后推荐给用户。这种处理是基于单个主题的实时数据流。从0.10.0.0开始,轻量,但功能强大的流处理,就可以这样进行数据处理了。
  • 除了Kafka Streams,还有Apache Storm和Apache Samza可选择。
事件采集
  • 事件采集是一种应用程序的设计风格,其中状态的变化根据时间的顺序记录下来,kafka支持这种非常大的存储日志数据的场景。
提交日志
  • kafka可以作为一种分布式的外部日志,可帮助节点之间复制数据,并作为失败的节点来恢复数据重新同步,kafka的日志压缩功能很好的支持这种用法,这种用法类似于Apacha BookKeeper项目。

11.同类型框架的异同

kafka
  • kafka是个日志处理缓冲组件,在大数据信息处理中使用。和传统的消息队列相比较简化了队列结构和功能,以流形式处理存储(持久化)消息(主要是日志)。日志数据量巨大,处理组件一般会处理不过来,所以作为缓冲曾的kafka,支持巨大吞吐量。为了防止信息都是,其消息被消防后不直接丢弃,要多存储一段时间,等过期时间过了才丢弃。这是mq和redis不能具备的。
主要特点入下:
  • 巨型存储量: 支持TB甚至PB级别数据。
  • 高吞吐,高IO:一般配置的服务器能实现单机每秒100K条以上消息的传输。
  • 消息分区,分布式消费:能保消息顺序传输。 支持离线数据处理和实时数据处理。
  • Scale out:支持在线水平扩展,以支持更大数据处理量。
redis
  • redis只是提供一个高性能的、原子操作内存键值队,具有高速访问能力,可用做消息队列的存储,但是不具备消息队列的任何功能和逻辑,要作做为消息队列来实现的话,功能和逻辑要通过上层应用自己实现。
MQ
  • 我们以是RabbitMQ为例介绍。它是用Erlang语言开发的开源的消息队列,支持多种协议,包括AMQP,XMPP, SMTP, STOMP。适合于企业级的开发。
  • MQ支持Broker构架,消息发送给客户端时需要在中心队列排队。对路由,负载均衡或者数据持久化都有很好的支持。
  • 其他更多消息队列还有ActiveMq,ZeroMq等。功能基本上大同小异。专门测结果,并发吞吐TPS比较,ZeroMq 最好,RabbitMq 次之, ActiveMq 最差。

转载于:https://my.oschina.net/chinahufei/blog/3089860

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值