文章目录
一、什么是Kafka?
kafka是一个分布式、支持分区的(partition)、多副本的(replica),基于zookeeper协调的分布式消息系统
二、Kafka介绍
1.特征
- 高吞吐,低延迟
- 可拓展性
- 持久性,可靠性
- 容错性
- 高并发
2.Kafka名词解释
- Broker:Kafka节点,一个Kafka节点就是一个broker,多个broker可以组成一个Kafka集群。
- Topic:一类消息,消息存放的目录即主题,例如page view日志、click日志等都可以以topic的形式存在,Kafka集群能够同时负责多个topic的分发。
- Partition:topic物理上的分组,一个topic可以分为多个partition,每个partition是一个有序的队列
- Segment:partition物理上由多个segment组成,每个Segment存着message信息
- Producer : 生产message发送到topic
- Consumer : 订阅topic消费message, consumer作为一个线程来消费
- Consumer Group:一个Consumer Group包含多个consumer,配置文件中配置
3.Kafka常用命令
Kafka 版本 2.0.1
1.Kafka服务
1.启动服务:
分2步,第一步是启动zookeeper:
sh zookeeper-server-start.sh
可指定config文件,后面带上config的路径即可。
第二步再启动kafka服务:
sh kafka-server-start.sh
也可指定config文件,后面带上config的路径即可。
2.关闭服务:
sh kafka-server-stop.sh
2.Topic
1.查看help:
sh kafka-topic.sh --help
2.创建topic:
sh kafka-topic.sh --create --topic topic_name --zookeeper udp01:2181 --partitions 3 --replication-factor 1
参数解释:
–partition:指定当前创建的kafka topic的分区数量,不指定默认为1。
—replication-factor :知道每个分区的复制因子,不指定默认为1。
其余参数还有:
–config:指定config文件。
创建topic还有一种是自动创建,当你往一个不存在的topic里面输入数据的时候,他会自动创建一个默认配置的topic,这种方式需要在server.properties配置文件中加上auto.create.topics.enable=ture。
3.查看当前Kafka集群中所有的topic
sh kafka-topics.sh --list --zookeeper udp01:2181
4.查看某个的topic的信息
sh kafka-topics.sh --describe --zookeeper udp01:2181 --topic topic_name
5.修改toipc信息
sh kafka-topics.sh --zookeeper udp01:2181 --alter --topic topic_name --partitions/config/delete-config
其中 partitions的数据只能比修改之前的大,不能小。
6.删除topic
bin/kafka-topics.sh --delete --topic topic_name --zookeeper udp01::2181
删除有2种,一种是标记删除,但实际还是存在的,一种是真的删除。
要真的删除也有2种方式:
- 删除本地磁盘以及zk上的相关topic信息。所属目录为/brokers/topics
- 配置server.properties文件中的delete.topic.enable为ture,需要重启kafka才会生效,在执行delete命令则会将topic删掉。
3.Produce
向topic中传数据:
sh kafka-console-producer.sh --broker-list udp01:9092 --topic topic_name
4.Consumer
消费topic:
sh kafka-console-consumer.sh --bootstrap-server udp01:9092 --topic topic_name --from-beginning
–from-beginning 为从头开始消费,如果不加则从当前时间开始消费。
5.Consumer Group
6.Kafka 自带压测脚本
1.生产者:
sh kafka-producer-perf-test.sh --topic test --record-size 10 --num-records 100 --throughput 2000 --producer-props bootstrap.servers=usdp-clustera-01:9092;
参数解释:
–record-size 每条消息字节大小
–num-records 总共需要发送的消息数
–throughput 每秒钟发送的记录数
返回的数据是:
100 records sent, 534.759358 records/sec (0.01 MB/sec), 52.47 ms avg latency, 177.00 ms max latency, 50 ms 50th, 58 ms 95th, 177 ms 99th, 177 ms 99.9th.
分别对应
100条消息,平均吞吐量为0.01MB/s,平均延时为0.0524秒,最大延迟为0.177秒,平均有50%的消息发送花费0.05秒,95%的消息花费0.177秒。
1.消费者:
sh kafka-consumer-perf-test.sh --messages 1000 --topic test --threads 1 --broker-list usdp-clustera-01:9092 --timeout 1000
参数解释:
–messages 消费者消费消息总数量
–threads 消费者使用几个线程同时消费
–timeout 消费者去kafka broker拿去一条消息超时时间
其余的还有
–fetch-size 每次向kafka broker请求消费大小
–socket-buffer-size 缓冲大小
返回的数据是:
start.time, end.time, data.consumed.in.MB, MB.sec, data.consumed.in.nMsg, nMsg.sec, rebalance.time.ms, fetch.time.ms, fetch.MB.sec, fetch.nMsg.sec
2022-03-03 15:59:37:848, 2022-03-03 15:59:41:400, 0.0105, 0.0030, 1100, 309.6847, 3064, 488, 0.0215, 2254.0984
参数解释:
data.consumed.in.MB:消费的所有消息的大小(MB),
MB.sec:每秒传输的数据量(MB),
data.consumed.in.nMsg:总共消费的消息数,
nMsg.sec:一秒内消费的消息数,
rebalance.time.ms:均衡耗时(ms),
fetch.time.ms:拉取耗时(ms),
fetch.MB.sec:每秒拉取数据(MB),
fetch.nMsg.sec:每秒拉取消息数
4.Kafka API
1.Topic
public class TopicOption {
// String zk =new GetProperties("");
private static final ZkUtils ZK = ZkUtils.apply("usdp-clustera-01:2181,usdp-clustera-02:2181,usdp-clustera-03:2181",3000,3000, JaasUtils.isZkSecurityEnabled());
public final static String topic = "test";
public static void main(String[] args) {
createTopic();
// changeTopicPartitions("2");
}
public TopicOption() throws IOException {
}
//获取topic list
@Test
public void getTopicList(){
List<String> topiclist= JavaConversions.seqAsJavaList(ZK.getAllTopics());
System.out.println(topiclist);
}
//创建topic
@Test
public static void createTopic(){
AdminUtils.createTopic(ZK,topic,1,1,new Properties(),
RackAwareMode.Enforced$.MODULE$);
}
@Test
public static void changeTopicPartitions(int partitions){
AdminUtils.addPartitions(ZK,topic,partitions,"",true,RackAwareMode.Enforced$.MODULE$);
}
//查看topic详情
@Test
public void queryTopic(){
Properties prop = AdminUtils.fetchEntityConfig(ZK, ConfigType.Topic(),"__consumer_offsets");
Iterator it = prop.entrySet().iterator();
while (it.hasNext()){
Map.Entry entry = (Map.Entry)it.next();
Object key =entry.getKey();
Object value =entry.getValue();
System.out.println(key + "=" + value);
}
}
//删除topic
@Test
public void deleteTopic(){
AdminUtils.deleteTopic(ZK,topic);
}
@Test
public void topicExists(){
boolean exists = AdminUtils.topicExists(ZK,topic);
System.out.println(exists);
}
@After
public void closeZk(){
ZK.close();
}
}
2.Produce
public class ProducerDemo {
private static KafkaProducer<String,String> producer;
public static void produceMessage(String topic,String message) {
int messageNo = 1;
final int COUNT = 5;
while(messageNo < COUNT) {
// String key = String.valueOf(messageNo);
String data = String.format(message);
try {
ProducerRecord<String,String> record = new ProducerRecord<>(topic,data);
producer.send(record);
} catch (Exception e) {
e.printStackTrace();
}
messageNo++;
}
producer.close();
}
public static void main(String[] args) {
Properties props = new Properties();
props.put("bootstrap.servers", "usdp-clustera-01:9092,usdp-clustera-02:9092,usdp-clustera-03:9092");//xxx服务器ip
props.put("acks", "all");//所有follower都响应了才认为消息提交成功,即"committed"
props.put("retries", 0);//retries = MAX 无限重试,直到你意识到出现了问题:)
props.put("batch.size", 16384);//producer将试图批处理消息记录,以减少请求次数.默认的批量处理消息字节数
//batch.size当批量的数据大小达到设定值后,就会立即发送,不顾下面的linger.ms
props.put("linger.ms", 1);//延迟1ms发送,这项设置将通过增加小的延迟来完成--即,不是立即发送一条记录,producer将会等待给定的延迟时间以允许其他消息记录发送,这些消息记录可以批量处理
props.put("buffer.memory", 33554432);//producer可以用来缓存数据的内存大小。
props.put("key.serializer",
"org.apache.kafka.common.serialization.IntegerSerializer");
props.put("value.serializer",
"org.apache.kafka.common.serialization.StringSerializer");
producer = new KafkaProducer<String, String>(props);
produceMessage("test","test");
}
}
3.Consumer
public class ProducerDemo {
private static KafkaProducer<String,String> producer;
public static void produceMessage(String topic,String message) {
int messageNo = 1;
final int COUNT = 5;
while(messageNo < COUNT) {
// String key = String.valueOf(messageNo);
String data = String.format(message);
try {
ProducerRecord<String,String> record = new ProducerRecord<>(topic,data);
producer.send(record);
} catch (Exception e) {
e.printStackTrace();
}
messageNo++;
}
producer.close();
}
public static void main(String[] args) {
Properties props = new Properties();
props.put("bootstrap.servers", "usdp-clustera-01:9092,usdp-clustera-02:9092,usdp-clustera-03:9092");//xxx服务器ip
props.put("acks", "all");//所有follower都响应了才认为消息提交成功,即"committed"
props.put("retries", 0);//retries = MAX 无限重试,直到你意识到出现了问题:)
props.put("batch.size", 16384);//producer将试图批处理消息记录,以减少请求次数.默认的批量处理消息字节数
//batch.size当批量的数据大小达到设定值后,就会立即发送,不顾下面的linger.ms
props.put("linger.ms", 1);//延迟1ms发送,这项设置将通过增加小的延迟来完成--即,不是立即发送一条记录,producer将会等待给定的延迟时间以允许其他消息记录发送,这些消息记录可以批量处理
props.put("buffer.memory", 33554432);//producer可以用来缓存数据的内存大小。
props.put("key.serializer",
"org.apache.kafka.common.serialization.IntegerSerializer");
props.put("value.serializer",
"org.apache.kafka.common.serialization.StringSerializer");
producer = new KafkaProducer<String, String>(props);
produceMessage("test","test");
}
}