不要求消息准确性很高,但是消息的吞吐量大
由于Kafka可以处理高吞吐量的消息,所以非常适合处理系统点击日志收集。即使是有的消息被消费了一次以上,但并不影响统计结果的精确性。
而且系统点击日志一般都量很大,放到单一的硬盘中很容易把硬盘撑爆。而Kafka的分布式存储系统,可以自动的实现消息分片和服务器扩容的功能,适合收集日志。
很多实时分析系统,都是通过Kafka + Storm进行日志收集和计算分析的。
业务代码实现幂等性,且消费者速度与生产者基本匹配
如果业务代码已经实现了幂等性,那么可以通过Kafka大幅提升业务系统的性能。实现幂等性有两种方式,一种是多次调用方法都会返回同样的结果,而不是累加的结果;另一种是在消费者端增加一个缓存,缓存中存储已经消费消息的主键,一旦缓存中存在这个主键,则不再重复消费。
另一个需要注意的问题就是消费者的速度不能和生产者差别太大,如果消费者速度远远小于生产者速度,导致时间差大于消息保存的时间,则会导致消息还未来得及消费就被删除。比如大于7天的消息就会删除,但是消费者还未来得及消费7天之前的消息,那么消息将丢失。遇到这种情况可以增加消息中介的分区和消费者实例,并行消费。但是如果瓶颈在数据库等其他资源,那么这种场景就不适合使用Kafka。
如果想使用Kafka处理仅仅发送一次的消息
由于Kafka的性能超过了传统的消息中间件很多,所以使用Kafka带来的优势很明显。
如果也想使用Kafka处理仅仅发送一次的消息,比如,业务端程序并没有实现幂等性。使用这种消息消费模型,需要以牺牲性能作为代价,但是由于其天生支持高可用和消息分片,则仍然比ActiveMQ这种消息中间件更好用。
首先需要每次存储消息都刷入磁盘。Kafka为了提升性能,一般是先将消息放入内存,等到一定数据或时间,才写入磁盘。设置为每写入一次消息,就刷一次盘。
开启事务永远是最保险的回滚数据的方式,如果将消息消费的偏移量放在Zookeeper或者消费者的客户端,是不能保证偏移量和业务数据在一个事务中一起回滚的。所以这里需要修改Kafka的程序,将消息的偏移量存入业务数据的数据库。如果是一个库,只要开启事务就可以,如果是在不同的库,则需要分布式事务。
在Kafka公布的0.9的新版本中提供了将偏移量存入自己定制的数据库中。预计在2014年12月发布。
Kafka的不适用场景,不支持消息失败的自动重试
ActiveMQ等JMS消息中间件,是支持消息失败重试的,自动重试n次在将消息放入死消息队列,供人工审查。不会因为某个消息有问题,影响后面的消息消费。但是Kafka这点要非常小心,如果采用将偏移量存入数据库,和业务数据一个事务,那么一旦某个消息有问题,需要完善的判断机制来判断消息是否已经消费,否则可能出现由于某一个消息消费不了而导致后面的消息都不能消费的情况。