Redis&MQ

一、消息队列

1、消息队列的基本作用?

1、异步处理
2、代码解耦
3、流量削峰
4、日志处理

2、消息队列的优缺点有哪些?

优点:异步、解耦、削峰
缺点:系统可用性降低、系统复杂性提高、数据一致性问题

  • 引入MQ后,MQ宕机导致业务系统受影响,必须保证MQ的高可用
  • 引入MQ后,需要保证消息不丢失,保证不重复消费、消费的幂等性、顺序消费
3、如何保证消息队列的高可用?
1. RabbitMQ 的高可用性
RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式
- 单机模式:一台机器,无法保证高可用
- 普通集群模式:只同步queue的元数据,无高可用,主要提高吞吐量
- 镜像集群模式:同步queue的元数据,同步消息到多个实例上,queue全量数据,带宽压力大,扩容难
2. Kafka 的高可用性
- 由多个 broker 组成,每个 broker 是一个节点
- 创建一个 topic,这个 topic 可以划分为多个 partition
- 每个 partition 可以存在于不同的 broker 上,每个 partition 就放一部分数据
- 每个 partition 在其他 broker 上存在副本,多个 partition 选举 leader 负责数据同步及对外提供服务
> 天然的分布式消息队列,就是说一个 topic 的数据,是分散放在多个机器上的,每个机器就放一部分数据
4、如何保证消息不被重复消费?或者说,如何保证消息消费的幂等性?
所谓幂等性是指多次执行与执行一次的结果是一致的
- 出现幂等性的情况
1.生产者发出消息,MQ接收到消息,未成功返回 ack 给生产者,生产者重试再次发送消息,造成MQ接收到重复消息
 即:生产者发送重复消息
2.消费者消费消息,消费者消费MQ的消息,消费者未成功返回 ack 给MQ,MQ再次将消息发送给其他消费者或当前消费者
 即:消费者重复消费消息
- 解决办法
1.生产者发送重复消息:给消息设置全局唯一的消息ID,MQ保证不接受重复ID的消息
2.消费者重复消费消息:使用业务ID或消息ID,每次消费消息时用ID先判断该消息是否已消费(mysql或redis)
5、如何保证消息的可靠性传输?或者说,如何处理消息丢失的问题?
- 丢失消息的环节
1.生产者丢消息:消息发出,网络闪断,MQ未收到消息,消息丢失
2.MQ丢消息:MQ宕机,消息丢失
3.消费者丢消息:消费者从MQ获取到消息并返回ack,未来得及处理进程挂掉,消息丢失
- 解决办法
1.rabbitmq
1)生产者:①开启rabbitmq事务(耗性能) ②开启confirm模式(ack/nack回调)生产者重试
2)MQ:开启rabbitmq的持久化,消息写入之后会持久化到磁盘
3)消费者:关闭rabbitmq自动ack,消息处理完手动 ack 确认
2.kafka
1)生产者:设置 acks=all,leader接收到消息,所有follower都同步到消息才认为成功,失败就重试
2)MQ:①replication.factor大于1,要求partition至少2个副本,②min.insync.replicas大于1,保证至少一
   个follower与leader同步没掉队,③producer设置acks=all,④producer设置retries=MAX
3)消费者:关闭自动提交offset,在处理完之后自己手动提交offset
6、如何保证消息的顺序性?
1.RabbitMQ保证消息顺序性
 生产者消息按顺序发送到同一个queue中;一个消费者监听这个queue进行顺序消费或者单线程取消息不处理消息,在此
 线程中对任务进行区分排序(queue中存在其他信息),然后开启多线程分类按序进行消费 - 其他消息并行处理
2.Kafka保证消息的顺序性
 生产者指定key单线程

你可能感兴趣的:(MQ,redis,rabbitmq,kafka)