南通网站制作价格,做传奇网站,h5和手机网站,使用免费网站制作软件1.RabbitMQ的高性能解决方案
1.1 发布确认机制
RabbitMQ提供了3种生产者发布确认的模式#xff1a; 简单模式#xff08;Simple Mode#xff09;#xff1a;生产者发送消息后#xff0c;等待服务器确认消息已经被接收。这种模式下#xff0c;生产者发送消息后会阻塞 简单模式Simple Mode生产者发送消息后等待服务器确认消息已经被接收。这种模式下生产者发送消息后会阻塞直到收到服务器确认消息。如果服务器在确认消息前崩溃生产者会重新发送消息。 同步等待确认实现简单但是吞吐量十分有限。 批量模式Batch Mode生产者发送一批消息后等待服务器一次性确认这批消息已经被接收。这种模式相比简单模式有更高的吞吐量因为确认是批量进行的。批量同步等待确认实现简单吞吐量较大但是很难找出未确认的消息其中一个失败后需要把一个批次都重试。 异步模式Asynchronous Mode生产者发送消息后不会等待服务器的确认消息。而是通过回调函数来处理确认和错误信息。这种模式适用于对消息可靠性要求不高的场景可以提高生产者的性能。 可靠性和性能最好在出现未确认消息时容易处理但是实现困难。
1.2 预取机制
RabbitMQ的默认分发方式是轮询分发轮询分发的问题是会导致消费快的消费者空闲消费慢的消费者一直干活。为了解决这个问题RabbitMQ引入了不公平分发机制可以把任务分发给空闲的消费者。
Channel channel connection.createChannel();
channel.basicQos(1)
上面案例中方法basicQos的参数PrefetchCount案例中等于1是最大传输信息数当消息由消费者消费完成之后再次从Queue中获取消息达到预取值。
PrefetchCount 0轮询分发PrefetchCount 1不公平分发PrefetchCount 1设置不公平分发并设置预期值
通过预取值的机制可以减少消费者与磁盘之间的交换次数从而提升消费者的处理能力。
2. Kafka的高性能解决方案
2.1 批量发送 Producer会为每个Partition创建一个双端队列来缓存客户端的消息队列中的每个元素是PorducerBatchPorducerBatch的每个元素就是客户端要发送的Msg。
KafkaProducer发送消息后会先经过分区器判断发往哪个双端队列。找到具体的双端队列后先判断ProducerBatch是否已满若满了则创建一个新的ProducerBatch否则追加到以后的ProducerBatch中。
接下来sender线程工作机制是
寻找ReadyNodesender到消息累加器中轮询存在哪些Node已经准备好的ProducerBatch只要一个Node有任何一个ProducerBatch准备好这个Node就会被认为是ReadyNode。创建Request拿到所有的ReadyNode寻找其中准备好的ProducerBatch对于一个Node下的ProducerBatch打包成一个Request其中一个Request最多包含的ProducerBatch由max.request.size控制。发起通讯然后每个Request通过Selector发起通讯。
sender把消息发送到Broker有两个条件
消息大小达到阈值通常为1M可以由message.max.bytes控制消息发送等待时间达到阈值默认为60000ms可以由max.block.ms控制
2.2 消息持久化
磁盘通查查询一条数据的过程如下 磁头寻道磁盘驱动器中的读写磁头会移动到指定的磁道上。磁道是磁盘表面的一个环形轨道用于存储数据。 磁道选择一旦到达正确的磁道磁头会选择正确的扇区。扇区是磁道上的一个小块用于存储数据。 磁头等待一旦选择了正确的扇区磁头会等待磁盘旋转到正确的位置。这是为了确保磁头在正确的时间读取或写入数据。 数据读取/写入一旦磁盘旋转到正确位置磁头会读取或写入数据。数据通过磁场变化在磁盘表面上进行存储和读取。
从上面的过程可以看出如果我们查询/写入一条数据是随机在磁盘的一个位置那么整个过程会比较耗时。对于Kafka来说采用的策略是使用顺序IO这样就可以避免寻址的过程直接操作对数据的读/写操作。
2.3 零拷贝 传统情况下从磁盘读取数据并通过网络发出去需要2次CPU copy和2次DMA copy 数据读取过程DMA执行了一次数据拷贝数据从磁盘拷贝到内核空间。cpu再将数据从内核空间拷贝到用户空间用户缓冲区。 数据发送过程cpu发生第三次数据拷贝由cpu将数据从用户空间拷贝至内核空间(socket缓冲区)DMA执行第四次数据拷贝将数据从内核空间写到网卡。
Linux2.4的Linux系统支持了sendfile DMA Gather 发起一次sendfile()系统调用进行一次上下文切换数据从磁盘DMA copy到内核缓冲区。将内核缓冲区中带有文件位置、文件信息的缓冲区描述符copy到Socket缓冲区然后借助DMA Gather真正的数据直接DMA copy到网卡。
这样只有两次上下文切换和两次DMA copy极大的减少了系统开支。
3.RocketMQ的高性能解决方案
3.1 异步机制
RocketMQ在高性能上与Kafka类似使用异步、批量、零拷贝的机制来实现高吞吐量。具体RocketMQ的异步机制如下 数据写入CommitLogBroker接收来自Producer发出的消息获取CommitLog最新offset并往CommitLog对应ByteBuffer追加数据。异步写磁盘Broker通过同步/异步的方式写入到磁盘。若为异步写入磁盘则是把数据写入OS的Page Cache就给Producer返回ACK后台线程异步把Page Cache的数据写的磁盘。异步复制Broker通过同步/异步的方式进行Master/Slave之间的数据同步。若为异步复制则是数据写入Master成功即视为成功再后台异步同步至其他Slave。异步写ConsumerQueue后台线程轮询CommitLog的offset是否发生变化若发生变化则计算CommitLog对应消息的commitLog Offset、size、Message Tag HashCode写入ConsumerQueue。异步写IndexFIle写入ConsumerQueue后再将消息Key Hash、commitLog Offset、TimeStamp、Next Index Offset写入到到IndexFile。
在RocketMQ中使用的批量发送、零拷贝等机制在上面已讲过不再重复陈述
4. 参考文档
Kafka由浅入深6 Sender线程执行源码解析_kafka sender源码解析_架构源启的博客-CSDN博客
Kafka全面学习_kafka学习_oraen的博客-CSDN博客
零拷贝技术----sendfile_socket 零拷贝_不吃树叶的树袋熊的博客-CSDN博客
kafka-生产者源码解析_kafka request.timeout.ms_SnaiI的博客-CSDN博客
RocketMQ源码分析之消息写入_rocketmq 写入 json数据_不爱学习的小妞的博客-CSDN博客
RocketMQ源码解读四 Broker写入数据_python 从mq写入文件_colspanprince的博客-CSDN博客
Java 两种zero-copy零拷贝技术mmap和sendfile的介绍_sendfile和mmap的比较_刘Java的博客-CSDN博客
多图详解 kafka 生产者消息发送过程_kafka生产者发送消息_Java程序V的博客-CSDN博客
Rabbitmq消息队列详解_rabbitmq查看消息队列_☜阳光的博客-CSDN博客
【RabbitMQ】Producer之publisher confirm、transaction - 基于AMQP 0-9-1_穿越在未来的博客-CSDN博客
spring-rabbit消费过程解析及AcknowledgeMode选择_acknowledge-mode_JinchaoLv的博客-CSDN博客
RabbitMQ持久化机制_琦彦的博客-CSDN博客
rabbitmq基础8——持久化、存储机制、ETS、队列结构、消息状态、内存告警、磁盘告警_rabbitmq存储机制_百慕卿君的博客-CSDN博客
从数据存储分析RocketMQ的高性能设计_rocketmq性能_怪兽靠边闪的博客-CSDN博客
RabbitMQ、RocketMQ和Kafka之间有什么性能差距_mq性能对比_Java技术攻略的博客-CSDN博客
计算机操作系统(二十二)磁盘_操作系统 磁盘转速 扇区_BKSW.的博客-CSDN博客
零拷贝技术mmap和sendfile_零拷贝mmap和sendfile_johnny233的博客-CSDN博客