1 消息队列解决的问题
1.1 什么场景需要消息队列
- 多个系统之间因为数据产生了耦合
假设数据同步交流,有两种方式,被动接受数据,这种方式会导致发送方因为接受方的变动而无法调度,主动调用接口获取数据,这种方式同样不合理因为每次调用都要运行分析程序来获取数据然后返回,所以数据以异步的方式交流可能比较好,通过约定好存放的地点,发送方将数据放在该地点,接收方从该地点接受数据
- 访问的峰值较高
由于数据库所能承受的并发量是有限的,虽然可以通过缓存降低对数据库的访问,但是当修改请求非常多的时候缓存就没什么用了,这时候大量请求进入数据库可能会宕机,两种解决方式第一个就是就是对数据库下手通过集群或者读写分离等等解决,第二种就是减少请求数量,这种方式就是就可以通过消息队列实现
- 需要提高用户响应时间
有时候提高qps的方式可以是提高并发数,但是并发数到达瓶颈之后就无法提升了,那么就可以将一部分工作丢给消息队列在后台慢慢做,这样响应速度就变快了
2 消息队列带来的问题以及如何解决
2.1 kafka如何保证可用性
- kafka的基本元素:kafka服务器本身就是一个broker节点,而kafka集群就是由多个broker节点组成的,消息以topic来分类,由topic可以划分多个broker,每个分区可以存放在不同broker上
- kafka如何保证数据的可用性:通过replica(复制品)的这样一个功能,在创建topic时可以设置副本数,每个分区的数据会在其他机器上保存副本,然后多个副本选出一个leader来与外界交流,读取的时候直接读取leader中的数据,修改的时候其他follower会主动来leader这里拉去数据,这样当某一个机器坏掉了,其他机器上的副本也能继续提供服务
- kafka中broker崩溃了如何重新选举:利用zookeeper的创建节点的机制,多个节点在同一位置创建节点只有一个节点可以成功,利用这个机制ISR中谁创建成功节点谁就是新的leader
- kafka如何应对消费者数量的动态变化:消费者发送心跳保证在消费者组中的存在,当消费者下线或者有新的进来时,kafka会进行重平衡的操作,在此之间整个消费者组不可用
2.3 kafka如何保证消息队列的有序性
- kafka无法保证在多partition的情况下全局有序,但是可以保证在同一个分区中时有序的,而这种有序通过尾加法来保证,消息在被加入分区时通过分配偏移量来保证分区中消息的有序性
- 全局有序可以通过一个topic一个分区来保证
2.4 kafka如何保证消息队列的可靠性
-
如何保证消息的可靠性:①生产者保证消息不丢失,通过设置acks=all,让信息写入所有副本才算写入成功,以次来保证在有leader中途崩溃的情况下的消息丢失和不一致现象。②消费者保证消息不丢失,通过手动提交offset来解决在消费端中途崩溃导致消息没有处理但是offset自动提交的情况。③kafka保证消息不丢失,通过设置副本个数、min.insync.replicas确保follower的个数,当小于设置值时客户端会返回异常、acks个数设置为-1保证所有同步完成、重试次数。
-
关于重复消费问题:①如何避免重复消费,引发的原因是消费者提交offset不及时或者生产者提交多了,这种情况只能通过程序来保证幂等性是的重复变得不是问题,可以通过获取数据判断一下的形式或者数据库本身的唯一性来保证。②假设业务需要重复消费,可以通过指定不同group进行重复消费,不同group之间kafka是以一种广播的形式每个group都可以从头读取数据
2.5 kafka消息持久性如何保证
- kafka的数据存放:kafka的消息是存储在磁盘中的,所以并不需要像redis那样的持久化处理,而topic的数据存放的方式以文件夹的形式存在,一个分区一个文件夹,在文件夹下有多个文件,每一条信息包括offset,messagesize,data
- kafka的数据过期:通过log.retention.hours/minutes/ms来设置过期时间,通过log.cleanup.policy设置过期处理方式有delete/compact两种形式
3 基于kafka的拓展
3.1 zookeeper在kafka中的作用
主要作用为:broker注册,topic注册,负载均衡(给topic中的分区分配broker、给生产者写入的数据分配分区,给消费者动态调整消费的分区)
网友评论