消息中间件学习

一、kafka

设计目标:以时间复杂度O(1)的方式提供消息持久化能力的。即使TB级别以上数据也能保证常数时间的访问性能,单机支持每秒100K条消息的传输。

Kafka特点:

  • 高吞吐量。
  • 消息持久化。
  • 分布式。
  • 消费消息采用Pull模式。
  • 支持Online和Offine场景,同时支持离线数据处理和实时数据处理。

Kafka的基本存储单元是分区(Partition),在一个Topic中会有一个或 多个Partition,不同的Partition可位于不同的服务器节点上,物理上一个Partition对应于一个文件夹。需要注意的是,Partition不能在多个服务器节点之间再进行细分,也不能在一台服务器的多个磁盘上再细分,所以其大小会受挂载点可用空间的限制。
Partition内包含一个或多个Segment,每个Segment又包含一个数据文件和一个与之对应的索引文件。虽然物理上最小单位是Segment,但是Kafka并不提供同一个Partition内不同Segment的并行处理能力。对于写操作,每次只会写Partition内的一个Segment;对于读操作,也只会顺序读取同一个

消息重复解决方案
概念:消费偏移量,kafka在设计上不同于其他JMS队列的地方是生产者的消息不需要消费者确认,而消息在分区中又都是顺序排列的,那么必然就可以通过一个偏移量(offset)来确定每一条消息的位置。

kafka中有一个叫作_consumer_offset的特殊主题用来保存消息在每个分区的偏移量,消费者每次消费时都会往这个主题中发送消息,消息包含每个分区的偏移量。

如果所提交的偏移量小于客户端处理的最后一条消息的偏移量,那么两个偏移量之间的消息就会被重复处理;如果所提交的偏移量大于客户端处理的最后一条消息的偏移量,那么两个偏移量之间的消息就会被丢掉。所以想要用好kafka,维护消息偏移量对于避免消息被重复消费和遗漏消费,确保消息的ExactlyOnce是至关重要的,在org.apache.kafka.clients.consumer.KafkaConsumer类中提供了很多方式来提交偏移量:

  1. 自动提交(默认的时间间隔是5秒)
    这种自动提交的方式看起来很简便,但会产生重复处理消息的问题。
  2. 手动提交
    在进行手动提交之前需要先关闭消费者的自动提交配置,然后使用commitSync提交偏移量。每接收到一批消息(或单个消息)并处理完之后提交一次偏移量,这样相对来说可以减少重复消息的数量,但会降低消费端的吞吐量。
  3. 异步提交

二、rocketMq

概念:

Broker的集群部署有多种

  1. 单Master
  2. 多Master多Slave(同步双写)
  3. 多Master多Slave(异步双写)

名称服务器:用来保存Broker相关元信息并给生产者和消费者查找Broker信息。每个Broker在启动时都会到名称服务器中注册,生产者在发送消息前根据主题到名称服务器中获取到Broker的路由信息,消费者也会定时获取主题的路由信息。

消息消费模式:集群消费和广播消费。默认是集群消费。
消息顺序有两种:顺序消费和并行消费。
顺序消费的原理是确保将消息投递到同一个队列中,在队列内部RocketMq保证先进先出。

消息重试概念

  1. 生产者端重试
    指当生产者向Broker发送消息时,如果由于网络抖动等原因导致消息发送失败,此时可以通过手动设置发送失败重试次数的方式让消息重发一次。
  2. 消费者端重试
    消费者端的失败一般分为两种情况,一是由于网络等原因导致消息没法从Broker发送到消费者端,这时在RocketMq内部会不断尝试发送这条消息,直到发送成功为止(比如向集群中的一个Broker实例发送失败,就尝试发往另一个Broker实例);二是消费者端已经正常接收到了消息,但是在执行后续的消息处理逻辑时发生了异常,最终反馈给MQ消费者处理失败,例如所接收到的消息数据可能不符合本身的业务要求,如当前卡号未激活不能执行业务等,这时就需要通过业务代码返回消息消费的不同状态来控制。

消息重复概念

理论上,所以的MQ产品在消息投递时都会面临三种模式,即:至少一次(at least once)、最多一次(at most once)、只有一次(exactly once)。
至少一次是指如果消息没有接收成功,则可能会重发一直到接收成功为止。
最多一次是指消息指发送一次,不管发送的结果是成功还是失败都不会重发。
只有一次的语义可以分成两部分解释,一是在消息发送时不允许发送重发的消息;二是在消息消费时也不允许消费重发的消息。只有这两个条件都满足时,才能认为是只有一次的。
RocketMq能保证消息至少被投递一次,即支持至少一次模式,但不支持只有一次模式。

消息重复解决方案
1,消费消息做幂等性(所谓幂等是指同样的入参,即使多次调用某个接口,对系统的影响也是一种的),只要做保持幂等性,不管来多少条重复消息,最后处理的结果都是一样的。
2,保证每条消息都有一个唯一标识,然后用一个消息处理日志表来记录已经处理成功的消息ID,假如新到的消息其ID已在日志表中,则不再处理这条消息。

消息丢失解决方案

  1. 同步刷盘,是指生产者发送的消息都要等到消息数据保存到Broker的磁盘成功后才向生产者返回成功信息。采用这种方式可以避免消息丢失,但是对性能有一定的影响,因为它有很大的磁盘I/O开销
  2. 异步刷盘,是指生产者发送的消息并不需要先保存到磁盘中,而是先缓存起来之后就向生产者返回成功消息,然后再将缓存的数据异步保存到磁盘中。这里有两种情况:一是定期刷盘缓存中的数据;二是如果缓存中的数据达到所设定的阀值就刷盘。异步刷盘在消息数据还没来得及同步到磁盘中时就宕机的情况下回导致少量消息丢失,但这种方式的性能比较高

你可能感兴趣的:(消息中间件)