Kafka整理



前提auto.offset.reset=smallest,这样能保证每条消息都at least once,至少一次。否则offset取最大时,会导致有些消息因为offset已经跳过而取不到。

zookeeper中没有初始化的offset时,如果offset是以下值的回应:

smallest:自动复位offset为smallest的offset

largest:自动复位offset为largest的offset

anything  else:向consumer抛出异常

 

 

目前定时提交offset的开关是打开的,每分钟提交一次。

 

有两种异常情况

1、offset提交时挂掉,会引起重复取消息

2、消息fetch后,消息处理的过程中,offset已经被定时提交,而此时消息处理时有异常(或者交易系统挂掉),这条消息就会丢失掉。

 

auto.commit.enable=false时,

1、手动提交也会有异常的时候,消息还是会重复;但是不会有消息丢失的情况。

 

 

 

蒋为处理方法:

1、防止丢消息:取消息时把topicpartitionoffset信息落地到一张表中。消息处理完成后,删除表中的信息。

       如果有没有处理完的消息,则利用低版本的consumer去消费指定offset的消息。

       缺点:数据库异常的话,没有办法处理。

     (但调用的是异步接口,直接发到支付平台kafka,所以支付平台保存不了请求消息)

2、重复消费消息:接口中做幂等处理。

 

Pascore处理方法

1、防止丢消息(有些消息取不到):(可能有问题

public synchronizedOrderMessageDTO fetchMessage()throws NoMessageException{

OrderMessageDTOmsgDTO=null;

if(recoveryOrders.size()==0){

//-------------获取消息

byte[]message = getMessage();

//------------解释消息        

msgDTO=parseMssage(message);

if(msgDTO==null){

returnnull;

}

msgDTO.setOffset(offset);

msgDTO.setTopic(topic);

msgDTO.setPartition(partition);

//取出消息后应该马上更新消息状态                        

orderRecord.updateMsgStatus(msgDTO.getId(),OrderMsgStatus.FETCH_FROM_MQ,msgDTO.getOffset());

recoveryOrders.add(msgDTO);

}

//恢复数据处理

Stringkey=topic+"-"+partition;

LongprocOffset=topicPartitionMap.get(key);

topicPartitionMap.put(key,offset);

if(procOffset==null){

 logger.info("First processmessage:"+key+"-"+offset+" and need recovery data for avoidlose message!");

 Calendar cal=Calendar.getInstance();

 cal.setTime(new Date());

 cal.add(Calendar.MINUTE,(-1)*config.getRecoveryMinutes());

 List<OrderMessageDTO> recoveryList =orderRecord.getRecoveryOrder(topic, partition, offset,recoveryStatus,cal.getTime(), new Date());

 if(recoveryList!=null&&recoveryList.size()>0){

 logger.info("recovery datasize:"+recoveryList.size());

 recoveryOrders.addAll(0, recoveryList);

 }

}

returnrecoveryOrders.remove(0);

}

 

 

2、重复消费消息:取消息后先检查mongodb中消息的状态,如果已经是处理过状态,则不重复消费;





Kafka 对比 ActiveMQ


Kafka是LinkedIn开发的一个高性能、分布式的消息系统,广泛用于日志收集、流式数据处理、在线和离线消息分发等场景。虽然不是作为传统的MQ来设计,在大部分情况,Kafaka也可以代替原先ActiveMQ 等传统的消息系统。


Kafka 将消息流按Topic组织,保存消息的服务器称为Broker,消费者可以订阅一个或者多个Topic。为了均衡负载,一个Topic的消息又可以划分到多个分区(Partition),分区越多,Kafka并行能力和吞吐量越高。


Kafka集群需要zookeeper 支持来实现集群,最新的kafka 发行包中已经包含了zookeeper,部署的时候可以在一台服务器上同时启动一个zookeeperServer 和 一个Kafka Server,也可以使用已有的其他zookeeper集群。


和传统的MQ不同,消费者需要自己保留一个offset,从kafka获取消息时,只拉去当前offset 以后的消息。Kafka 的scala/java 版的client 已经实现了这部分的逻辑,将offset保存到zookeeper 上。每个消费者可以选择一个id,同样id 的消费者对于同一条消息只会收到一次。一个Topic的消费者如果都使用相同的id,就是传统的 Queue;如果每个消费者都使用不同的id, 就是传统的pub-sub.


如果在MQ的场景下,将Kafka和 ActiveMQ 相比:


Kafka 的优点


分布式可高可扩展。Kafka集群可以透明的扩展,增加新的服务器进集群。


高性能。Kafka的性能大大超过传统的ActiveMQ、RabbitMQ等MQ 实现,尤其是Kafka 还支持batch 操作。下图是linkedin 的消费者性能压测结果:


容错。Kafka每个Partition的数据都会复制到几台服务器上。当某个Broker故障失效时,ZooKeeper服务将通知生产者和消费者,生产者和消费者转而使用其它Broker。


Kafka 的不利


重复消息。Kafka只保证每个消息至少会送达一次,虽然几率很小,但一条消息有可能会被送达多次。


消息乱序。虽然一个Partition内部的消息是保证有序的,但是如果一个Topic 有多个Partition,Partition 之间的消息送达不保证有序。


复杂性。Kafka需要zookeeper集群的支持,Topic通常需要人工来创建,部署和维护较一般消息队列成本更高




查看topic的命令:。


./kafka-topics.sh-z 109 2181 -describe > /tmp/test20160320


 


6./kafka-consumer-offset-checker.sh--zookeeper 102181 --group Order --topic -rder-topic






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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值