MNS client性能提升1000+倍的方法

简介: MNS是阿里云提供的开箱即用的 队列服务,容易上手。当数据量很大,特别是做大批量数据同步时,很多人就会遇到性能瓶颈。 下面就给大家介绍下,提升单机MNS client性能的几种方法。

MNS是阿里云提供的开箱即用的 队列服务,容易上手。当数据量很大,特别是做大批量数据同步时,很多人就会遇到性能瓶颈。

下面就给大家介绍下,提升单机MNS client性能的几种方法。

1. 网络环境

首先考虑的是网络环境。

使用内网endpoint吧,不细说。

2. 多线程的正确姿势

其次,利用多线程提升并发度。

这个大家肯能都会想到,不过事情并没有那么简单。看看官网的多线程示例,我是例子

嗯。。。100个线程,tps怎么也得10+倍了吧。但是没卵用,多线程似乎失效?

so翻了翻源码,当看到MNS底层使用的http reactor模块,DefaultConnectingIOReactor、AbstractMultiworkerIOReactor时,问题逐渐变得明朗起来。

class AbstractMultiworkerIOReactor {
    private final int workerCount;
    private final ThreadFactory threadFactory;
    private final BaseIOReactor[] dispatchers;
    private final Worker[] workers;
    private final Thread[] threads;

原来事情的真相是这样:

image

MNS client 是个singleton。官网的例子用这个singleton搞出了一大堆CloudQueue,想要发挥多线程的魔力。
其实看图可知,不论搞出多少CloudQueue,下面共用的是io 线程池和连接池,而它们才是真正干活的啊。
这种感觉就好比,一家饭店,找了大堆服务员在门口拉客,但后面就一个厨子。
所以,单纯增加CloudQueue没有用,相反,由于CloudQueue放任务到IO池里都是内存操作是很快的,并不要很多线程。

道理明白后,要做的事情就简单了,多线程的正确姿势是:增多worker。

ClientConfiguration clientConf = new ClientConfiguration();
clientConf.setMaxConnections(很多连接);
clientConf.setIoReactorThreadCount(很多线程);
CloudAccount account = new CloudAccount(
    mnsConfig.getAccessId(),
    mnsConfig.getAccessKey(),
    mnsConfig.getEndPoint(),
    clientConf);

3. Batch的Magic Number

再次,批量处理。像Kafka、flume等都是加大batch提升吞吐量的。

MNS client SDK也有类似的API,如

List<Message> batchPopMessage(int batchSize);
void batchDeleteMessage(List<String> receiptHandles);
batchPutMessage(List<Message> messages)

激动地给batch设了个100,Run,服务端异常,50,异常,20异常。说好的batch呢,难道是个假API?

当试到16这个Magic Number时,终于成功了。翻看下官网文档,也没有对magic number说明。

4. 测试小结

简单测试了下,4core8G,单条消息1k byte。
4线程: total send message 16000, cost 5681, tps 2816
8线程: total send message 16000, cost 4603, tps 3475
16线程:total send message 16000, cost 1973, tps 8109

敬告:对于那些一不小心就超过上面测试数据的同学,欢迎加入橙鹰数据(据说是杭州一个很牛x很低调的大数据公司)。

BTW, 优化的意义。下面是阿里云另一款高性能MQ产品,
image

5. 坑货

5.1巨坑之PollingWaitSeconds

控制台创建MNS队列时,PollingWaitSeconds默认值是0。
这个值必须要设置
这个值必须要设置
这个值必须要设置
因为MNS会按请求次数收费。依稀记得那个晚上,几w块就灰飞烟灭了。推荐设10~30。

5.2 小坑之VisibilityTimeout

使用过Kafka,Metaq的同学知道,消息消费掉后,会commit offset告诉broker。
不同的地方是,在使用MNS时,为了不丢数据,通常是消费成功后,手动删除消息。
如果消息被消费后,超过了VisibilityTimeout,再去删除这个消息,就会遇到喜闻乐见的Not Found错误。

5.3 小坑之重建队列

常会有这种情景,给队列发送了很多消息,想把消息全部删除后重新灌批数据,但是由于没有一键清除的方法,用户会删除该队列,然后重建个同名的队列。
这样产生的问题是,原来的MNS client找不到该队列了,必须要重启。

相关实践学习
消息队列RocketMQ版:基础消息收发功能体验
本实验场景介绍消息队列RocketMQ版的基础消息收发功能,涵盖实例创建、Topic、Group资源创建以及消息收发体验等基础功能模块。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
5月前
|
消息中间件 存储 监控
RocketMQ的性能优势?
【8月更文挑战第29天】RocketMQ的性能优势?
157 2
|
6月前
|
消息中间件 缓存 Apache
消息队列 MQ使用问题之对于Grpc参数的调优,该如何操作
消息队列(MQ)是一种用于异步通信和解耦的应用程序间消息传递的服务,广泛应用于分布式系统中。针对不同的MQ产品,如阿里云的RocketMQ、RabbitMQ等,它们在实现上述场景时可能会有不同的特性和优势,比如RocketMQ强调高吞吐量、低延迟和高可用性,适合大规模分布式系统;而RabbitMQ则以其灵活的路由规则和丰富的协议支持受到青睐。下面是一些常见的消息队列MQ产品的使用场景合集,这些场景涵盖了多种行业和业务需求。
|
8月前
|
消息中间件 物联网 网络性能优化
MQTT常见问题之MQTT的topic超出上限25个如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
消息中间件 运维 算法
RabbitMQ高阶使用延时任务
RabbitMQ高阶使用延时任务
184 0
|
消息中间件 存储 缓存
深度解读 RocketMQ 存储机制
本文想从一个不一样的视角,着重于谈谈我眼中的这种存储实现是在解决哪些复杂的问题,因此我从本文最初的版本中删去了冗杂的代码细节分析,由浅入深的分析存储机制的缺陷与优化方向。
676 1
深度解读 RocketMQ  存储机制
|
消息中间件 Kafka 开发者
使用生成器把Kafka写入速度提高1000倍
使用生成器把Kafka写入速度提高1000倍
135 0
|
存储 消息中间件 缓存
深度解读 RocketMQ 存储机制
本文想从一个不一样的视角,着重于谈谈我眼中的这种存储实现是在解决哪些复杂的问题,因此我从本文最初的版本中删去了冗杂的代码细节分析,由浅入深的分析存储机制的缺陷与优化方向。
936 16
深度解读 RocketMQ 存储机制
|
消息中间件 存储 容灾
Apache RocketMQ 5.0 在Stream场景的存储增强
RocketMQ的诞生是为了解决微服务解耦的问题。微服务解耦指将传统的巨大服务拆分为分布式的微服务。
Apache RocketMQ 5.0 在Stream场景的存储增强
|
消息中间件 存储 缓存
从源码上看,RocketMQ 5.0 跟 RocketMQ 4.x相比增加了哪几个模块
从源码上看,RocketMQ 5.0 跟 RocketMQ 4.x相比增加了哪几个模块
488 0
从源码上看,RocketMQ 5.0 跟 RocketMQ 4.x相比增加了哪几个模块
|
消息中间件 存储 弹性计算
基于Kafka connect+函数计算的轻量计算解决方案
Kafka ETL基于kafka connect加函数计算,为云上用户提供了一套数据流转加数据计算的一站式解决方案。
728 0