Kafka
继kafka基础之后再来点高级实用的。顺便做一个kafka整理总结。
查看kafka自身维护偏移量:kafka-run-class.sh kafka.tools.GetOffsetShell --broker-list master:9092 --topic flink --time -1
1、kafka自定义分区
分析
步骤:
1,设计一个子类继承分区父类,重写其中的partition方法,在该方法中定制分区规则
2,修改producer.properties文件,指定自定的分区类
源码以及效果
import org.apache.kafka.clients.producer.Partitioner;
import org.apache.kafka.common.Cluster;
import org.apache.kafka.common.PartitionInfo;
import java.util.List;
import java.util.Map;
public class MyPartition implements Partitioner {
/**
* 下述方法在消息存储到相应分区之前,都会被回调一次。
* 原因:消息得找到自己存储的所在。
*
* @param topic 主题名
* @param key 消息的key
* @param keyBytes key对应的字节数组
* @param value 消息的value
* @param valueBytes value对应的字节数组
* @param cluster kafka分布式集群
* @return
*/
@Override
public int partition(String topic, Object key, byte[] keyBytes, Object value, byte[] valueBytes, Cluster cluster) {
//思路:
//①获得当前主题的分区数
List<PartitionInfo> partitionInfos = cluster.availablePartitionsForTopic(topic);
int totalPartitionNum = partitionInfos.size();
//②关于key
// a)key≠null, key的hash码值对分区数求余数,余数即为当前消息所对应的分区编号
//b)key=null, 根据value来计算
//i)value ≠null, value的hash码值对分区数求余数,余数即为当前消息所对应的分区编号
//ii)value=null, 直接返回默认的分区编号,如:0.
if (key != null) {
return key.hashCode() % totalPartitionNum;
} else {
if (value != null) {
return value.hashCode() % totalPartitionNum;
} else {
return 0;
}
}
}
@Override
public void close() {
}
@Override
public void configure(Map<String, ?> configs) {
}
}
2、 消息拦截器
介绍
①在消息发送到kafka分布式集群之前,针对于一些共通的业务处理,建议使用拦截器。如:对每条消息添加一个共通的前缀(如:时间戳),对消息中包含一些反动的信息进行筛选
②还可以监测到消息发送的状态(成功,失败)
③需求:实现一个简单的双interceptor组成的拦截链。第一个interceptor会在消息发送前将时间戳信息加到消息value的最前部;第二个interceptor会在消息发送后更新成功发送消息数或失败发送消息数。
④核心api:ProducerIntercepter
源码以及效果
import org.apache.kafka.clients.producer.*;
import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.Properties;
public class InteceptorUsageDemo {
public static void main(String[] args) {
//步骤:
Producer<Integer, String> producer = null;
try {
//①准备Properties的实例,并将资源目录下的配置文件producer.properties中定制的参数封装进去
Properties properties = new Properties();
properties.load(InteceptorUsageDemo.class.getClassLoader().getResourceAsStream("producer.properties"));
//将拦截器封装到properties实例中,作为参数来构建KafkaProducer
Collection<