kafka常见命令操作及底层原理总结

 

fa124607857 2019-12-11 17:24:29  11  已收藏
展开
Kafka集群操作
创建topic
bin/kafka-topics.sh --create  --partitions 3 --replication-factor 2 --topic test --zookeeper node01:2181,node02:2181,node03:2181
1
查看topic
 bin/kafka-topics.sh --list --zookeeper node01:2181,node02:2181,node03:2181
1
生产数据
bin/kafka-console-producer.sh --broker-list node01:9092,node02:9092,node03:9092 --topic test
1
消费数据
bin/kafka-console-consumer.sh --from-beginning  --topic test --zookeeper node01:2181,node02:2181,node03:2181
1
查看topic的一些信息
bin/kafka-topics.sh --describe  --topic test --zookeeper node01:2181
1
修改topic的配置属性
bin/kafka-topics.sh --zookeeper node01:2181 --alter --topic test --config flush.messages=1
1
删除topic
 bin/kafka-topics.sh --zookeeper node01:2181 --delete --topic test
1
kafka集群当中JavaAPI操作
kafka集群当中ProducerAPI
public class MyProducer {

    /**
     * 实现生产数据到kafka test这个topic里面去
     * @param args
     */
    public static void main(String[] args) {

        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");
        //获取kafakProducer这个类
        KafkaProducer<String, String> kafkaProducer = new KafkaProducer<>(props);
        //使用循环发送消息
        for(int i =0;i<100;i++){
            kafkaProducer.send(new ProducerRecord<String, String>("test","mymessage" + i));
        }
        //关闭生产者
        kafkaProducer.close();
    }

}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
kafka集群当中的consumerAPI
消息的消费分为两种方式:

offset:offset记录了每个分区里面的消息消费到了哪一条,下一次来的时候,我们继续从上一次的记录接着消费

自动提交offset:

手动提交offset:

kafka的streamAPI
注意:如果程序启动的时候抛出异常,找不到文件夹的路径,需要我们手动的去创建文件夹的路径

kafkaAPI开发:

生产者API

消费者API:自动提交offset,手动提交offset。offset记录了我们数据的对应的long类型的数字

streamAPI:实现从一个topic里面获取数据,转换成为大写,写入到另外一个topic里面去

kafka的底层原理
生产者原理以及分区策略
生产者原理:主要就是研究如何将数据写入到kafka集群里面去,写入到某一个topic里面去之后,如何确定数据写入到哪一个分区里面去

一个topic里面有好多个分区,数据究竟写入到哪一个分区里面去???

生产数据三个必要的条件:

#1、地址
bootstrap.servers=node01:9092
#2、序列化 key.serializer=org.apache.kafka.common.serialization.StringSerializer value.serializer=org.apache.kafka.common.serialization.StringSerializer
#3、主题(topic) 需要制定具体的某个topic(order)即可。
1
2
3
4
默认的分区规则:

/**
 * The default partitioning strategy:
 * <ul>
 * <li>If a partition is specified in the record, use it
 * <li>If no partition is specified but a key is present choose a partition based on a hash of the key
 * <li>If no partition or key is present choose a partition in a round-robin fashion
 */
1
2
3
4
5
6
7
总结:如果指定了数据的分区号,那么数据直接生产到对应的分区里面去

如果没有指定分区好,出现了数据key,通过key取hashCode来计算数据究竟该落在哪一个分区里面

如果既没有指定分区号,也没有指定数据的key,使用round-robin轮询 的这种机制来是实现

创建topic 3 个分区,两个副本

bin/kafka-topics.sh --create  --partitions 3 --replication-factor 2 --topic mypartition --zookeeper node01:2181,node02:2181,node03:2181
1
kafka当中四种分区策略

 //分区策略第一种,如果既没有指定分区号,也没有指定数据key,那么就会使用轮询的方式将数据均匀的发送到不同的分区里面去
            //ProducerRecord<String, String> producerRecord1 = new ProducerRecord<>("mypartition", "mymessage" + i);
            //kafkaProducer.send(producerRecord1);

            //第二种分区策略 如果没有指定分区号,指定了数据key,通过key.hashCode  % numPartitions来计算数据究竟会保存在哪一个分区里面
            //注意:如果数据key,没有变化   key.hashCode % numPartitions  =  固定值  所有的数据都会写入到某一个分区里面去
            //ProducerRecord<String, String> producerRecord2 = new ProducerRecord<>("mypartition", "mykey", "mymessage" + i);
            //kafkaProducer.send(producerRecord2);

            //第三种分区策略:如果指定了分区号,那么就会将数据直接写入到对应的分区里面去
          //  ProducerRecord<String, String> producerRecord3 = new ProducerRecord<>("mypartition", 0, "mykey", "mymessage" + i);
           // kafkaProducer.send(producerRecord3);

            //第四种分区策略:自动以分区策略.如果不自定义分区规则,那么会将数据使用轮询的方式均匀的发送到各个分区里面去
              //配置我们自定义分区类
        props.put("partitioner.class","cn.itcast.kafka.partition.MyPartitioner");
            kafkaProducer.send(new ProducerRecord<String, String>("mypartition","mymessage"+i));


消费者底层原理以及各种消费的过程
自动提交offset

手动提交offset

处理完每个分区里面的数据之后,然后就进行一次提交offset

手动指定某些分区里面的数据进行消费:例如:有一个topic mypartition,里面有三个分区 ,需求:只需要消费其中两个分区里面的数据

消费者API总结:自动提交offset,手动提交offset,处理完每个分区里面的数据就进行提交offset,通过指定消费topic当中某些分区的数据

kafka当中数据丢失以及数据重复消费
kafka当中数据消费模型:

eactly once:消费且仅仅消费一次,可以在事务里面执行kafka的操作

at most once:至多消费一次,数据丢失的问题

at least once :至少消费一次,数据重复消费的问题

kafka的消费模式:决定了offset值保存在哪里
kafka的highLevel API进行消费:将offset保存在zk当中,每次更新offset的时候,都需要连接zk

以及kafka的lowLevelAP进行消费:保存了消费的状态,其实就是保存了offset,将offset保存在kafka的一个默认的topic里面。kafka会自动的创建一个topic,保存所有其他topic里面的offset在哪里

kafka将数据全部都以文件的方式保存到了文件里面去了。

kafka的数据保存形式
kafka里面一个topic有多个partition组成,每一个partition里面有多个segment组成,每个segment都由两部分组成,分别是.log文件和.index文件 。一旦.log文件达到1GB的时候,就会生成一个新的segment

.log文件:顺序的保存了我们的写入的数据

.index文件:索引文件,使用索引文件,加快kafka数据的查找速度

总结:查找数据的过程

第一步:通过offset确定数据保存在哪一个segment里面了,

第二部:查找对应的segment里面的index文件 。index文件都是key/value对的。key表示数据在log文件里面的顺序是第几条。value记录了这一条数据在全局的标号。如果能够直接找到对应的offset直接去获取对应的数据即可

如果index文件里面没有存储offset,就会查找offset最近的那一个offset,例如查找offset为7的数据找不到,那么就会去查找offset为6对应的数据,找到之后,再取下一条数据就是offset为7的数据

kafka如何保证数据不丢失
生产者:使用ack机制

broker:使用partition的副本机制

消费者:使用offset来进行记录

主分区与副本分区之间的数据同步:

两个指标,一个是副本分区与主分区之间的心跳间隔,超过10S就认为副本分区已经宕机,会将副本分区从ISR当中移除

主分区与副本分区之间的数据同步延迟,默认数据差值是4000条

例如主分区有10000条数据,副本分区同步了3000条,差值是7000 > 4000条,也会将这个副本分区从ISR列表里面移除掉
————————————————
原文链接:https://blog.csdn.net/fa124607857/article/details/103496294

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值