如何让网站显示404,最新国际新闻热点事件,最近新闻头条,沈阳seo关键词排名优化软件为何使用消息队列
异步。接口方式实现多个系统协作#xff0c;如图A系统作为用户请求接收方#xff0c;需要调用多个系统的接口#xff0c;这些接口还有可能是在A系统里同步调用#xff0c;所以最后的接口耗时是多个系统接口耗时的总和#xff1b;mq方式则可以异步发送消…为何使用消息队列
异步。接口方式实现多个系统协作如图A系统作为用户请求接收方需要调用多个系统的接口这些接口还有可能是在A系统里同步调用所以最后的接口耗时是多个系统接口耗时的总和mq方式则可以异步发送消息给mqmq再发送给其他多个系统多个系统并行且异步的接收消息。当然mq方式实现有一个前提是用户的请求不需要立即返回请求结果例如用户发送一个查询请求就不适合mq方式。mq方式多用于传递事件如发送优惠券、秒杀等。 削峰。用户的请求大部分都集中在固定的时间段而在晚间凌晨或者用户使用低峰期基本没什么请求。所以mq的削峰就是为了将高峰期的请求泄洪一部分到低峰期。解耦。接口方式发送消息发送者调用接口接收者提供接口此时发送者作为消息生产者如图中的A系统作为主动的一方需要适配上游的各个类型的接口它们的传输协议、参数、返回值等可能都不一样同时各个接收方还不能拒收消息这些都会带来极大的工作量mq方式发送消息消息发送者变成了上游现在只需要将统一格式的消息发送给mq由mq来控制消息的存储、容灾以及消息是否送达等。消息接收者则遵守消息的统一格式即可如果不想接收消息可以取消订阅。这样就达到了生产者和消费者之间的解耦效果。 kafka的总体架构 Producer消息的生产者即消息的入口。Brokerkafka的一个实例一台kafka服务器上会有一个或多个实例。多台kafka服务构成了kafka的集群。Topic消息的主题生产者按照主题发送消息消费者按照主题接收消息一个Broker可以有多个主题。PartitionTopic的分区一个Topic可以有多个分区分区越多可以并行处理消息的能力越强。同一个Topic上的不同分区消息是不重复的Partition的本质是文件夹。ReplicationPartition的副本副本用来做数据备份。副本分为主分区副本Leader和从分区副本Follower它们不能同时出现在一个Broker上。主分区副本负责消息的接收并写入从分区副本不接收生产者发来的消息它的唯一职责就是从主分区副本同步过来消息。当主分区副本挂掉的时候会在从分区副本中选出一个新的Leader作为主分区副本。kafka中一个Partition的最大副本数量是10个且副本数量不能大于Broker的数量。Consumer消息的消费者即消息的出口。Consumer Group多个消费者组成一个消费组消费组之间可以重复消费消息。同一个消费组的某一个Partition不能同时被多个消费者消费。Zookeeperkafka集群依赖Zookeeper保存集群的元信息以保证kafka集群的可靠性。kafka从2.8版本以后使用其内部的Quorum控制器来代替Zookeeper。
生产者写数据
生产者发送消息给Leader分区副本并顺序写入到磁盘文件然后Follower分区副本从Leader分区副本poll消息以保证数据是最新的。kafka将消息写入哪个分区有几下几个原则
生产者指定了分区写入对应的分区生产者没有指定分区但设置了数据库的key根据key的hash值算出一个分区生产者既没有指定分区也没有设置key轮询出一个分区 topic本质是一个目录而topic又是由一些Partition Logs(分区日志)组成。消息采用hash取模的分区算法有序的写入到Partitionp Log上。
producer在将消息写入partition之前会先在内存中缓存累计到一定量后按数量、按时间间隔或按数据大小再批量写入。 一般一条消息大概1~10kB推荐不要超过1MB。
kafka默认数据保留7天时间。如果数据量大可以修改配置log.retention.hours将时间缩短。
消费者读数据
与生产者一样消费者主动的从Leader分区副本拉取消息。每成功拉取一条partition的消息partition的消息游标卡尺offset就会加1。 partition里的offset默认配置是从最新一条开始消费也可以配置from beginning从0开始消费。
在同一个消费组里消费者和partition的关系是1:1或者1:n不能出现消费者与partition是n:1的情况意思是同一个消费组里消费者数量要小于等于parition的数量。因为不这样做就会造成多个消费者共享一个offset从而就不能保证一个partition内的消息的顺序性也会造成消息被重复消费的安全问题这是一种不稳定的重复消费。
如果想要稳定的重复消费同一条消息可以设置两个消费组。两个组内的消费者消费同一个partition时offset是相互独立的。 消息的有序性
想要保证消息被消费的有序性有以下两个方法
一个topic只设置一个partition。缺点是消费组里只能有一个消费者消费不适用高并发场景。producer将需要保证顺序的消息发送到同一个partition。两种方式指定1、指定partition2、不指定partition根据key的hash值运算后得到partition。 消息的可靠性
kafka的数据是可持久化的写在Partition Log文件里。每个topic都可以设置副本数量。副本数量决定了有几个broker来存放写入的数据。
consumer和partition数量的关系是partition数 同一个消费组里的consumer数。因为一个partition只能被同一个消费组的一个consumer消费但一个consumer可以消费多个partition。这是为了消息在一个partition里的顺序读。
生产端消息可靠性
分区副本 所有的读写请求都发往leader副本所在的brokerfollower副本不处理客户端请求它唯一的任务就是从leader副本异步拉取消息。
Kafka默认的副本因子是3即每个分区只有1个leader副本和2个follower副本。 同步副本(In-sync replicas)
ISR同步副本机制是用来判断follower是否同步了leader的最新数据。
ISR列表保存了与leader已经同步的副本leader自己是长期存在于ISR列表。当follower副本超过设定的时间间隔replica.lag.time.max.ms没有和leader同步就会被踢出ISR列表反之则不会被踢出。 acks参数生产者配置
acks参数表示有多少的分区副本收到消息才能认为消息是写入成功的。
acks0。不需要副本收到消息producer就能收到broker的响应。该模式吞吐量高但安全性低容易丢消息。 acks1默认。只要leader副本接收到了消息并写入到磁盘producer就能收到broker的响应。需要注意的是这种模式依然会有丢消息的安全问题。例如当leader副本收到消息以后还没来得及同步副本到follower就宕机了此时producer已经收到了成功的响应但follower变为新的leader时还未将最新的那条消息同步过来。 acksall或-1。只有ISR列表里的所有分区副本都收到消息producer才能收到broker的响应。该模式延迟最高。 acksall模式下有一个最小副本配置min.insync.replicas。该配置默认值是1只在acksall时生效。该参数控制消息最少被多少个副本写入才算成功写入。即ISR列表的副本最小数量。因为ISR列表始终要有leader副本所以如果该配置默认是1实际上是起不到副本作用的所以该配置最好配置为大于1的数。
当leader副本宕机时acksall模式下会在ISR列表中选举一个新的broker作为leader。
增大min.insync.replicas。可以增加数据的可靠性。减小min.insync.replicas。可以增加系统的可用性。
消费端消息可靠性
要想实现消费端的消息可靠性必须抓住两点
保证消息到达的状态offset和本地事务的状态保持一致。保证消费的幂等性。
要想保证消费端消息的可靠性首先必须保证提交offset和提交本地事务要么一起成功要么一起失败。我们以自动提交offset和手动提交offset分别举例说明。
自动提交offset。消息到达消费客户端不论本地事务是否提交成功offset都会自动提交。一旦本地事务提交失败就会造成消息丢失的问题。手动提交offset。有三种方法 第一种方式是消费端KafkaListener不配置本地事务业务代码执行完后数据入库最后再提交offset即使offset提交失败只要保证业务代码的幂等性消息重复消费也可以接受。第二种方式是消费端KafkaListener配置本地事务将offset的值写道数据库里和业务数据一起提交这样就将业务数据和offset做了绑定关系在消费一开始就根据业务id和offset判断消息是否消费过如果没有消费过才执行业务代码。第三种方式是前两种方式的结合这种方式不需要将offset入库。该方法在消费端KafkaListener配置本地事务先执行业务代码最后执行offset提交这样业务代码失败就不会执行提交offset的代码而如果是最后提交offset失败本地事务也会回滚。
在实际的运用中考虑到数据库事务相对性能较差可以把本地事务和offset的绑定关系用缓存来保存。
kafka优化
kafka削峰的几种方法
增加分区。增加分区数可以提高消息并行处理的能力。当然也会增加集群的维护成本需要权衡。使用消费组。使用消费组可以让多个消费者并行消费一个partition的消息因为每个消费组在同一个partition的offset不是共享的。但是为了避免重复消费消息需要为不同消费组上的多个消费者指定所消费消息的key。增加副本数。可以提高kafka的吞吐量提升kafka的可靠性和容错性。
此外修改一些kafka配置参数也能达到一定的优化效果。例如
为了减少每次发送/拉取消息的次数可以提高消息发送/拉取的消息数量/数据大小的阈值或者增加时间间隔。减少消息发送/拉取的次数意味着一次发送/拉取的量比较大所以还要注意提高会话超时、拉取超时的时间间隔以免触发rebalance。减小并行度concurrency。当concurrency3时就会有4*312个Consumer线程12个Listener线程。减小concurrency可以减少客户端线程数量。
kafka和rocketmq
目前消息队列用的比较多的就是kafka和rocketmq了。我们可以比较一下这两种消息队列的优缺点。
适用场景
topic较多时推荐使用rocketmqtopic少时kafka性能更佳。因为kafka一个topic一个partition文件rocketmq是多个topic一个文件。
kafka适合日志处理、大数据领域rocketmq适合业务处理。
性能
kafka的tps在百万条/秒rocketmq大约10万条/秒。
可靠性
kafka异步刷盘异步副本recketmq异步/同步刷盘异步/同步副本。
支持队列数量
kafka单机最大支持64个队列/分区增加分区性能降低严重rocketmq单机最大支持5w队列性能稳定。
消息顺序性
kafka在同一个partition下支持消息顺序性但如果一台broker宕机会打乱顺序rocketmq支持消息顺序性一台broker宕机消息会发送失败但顺序性依然可以保证。