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一站式入门使用
从源码编译、部署broker、部署namesrv,使用java客户端首发消息等一站式入门RocketMQ。
消息队列 MNS 入门课程
1、消息队列MNS简介 本节课介绍消息队列的MNS的基础概念 2、消息队列MNS特性 本节课介绍消息队列的MNS的主要特性 3、MNS的最佳实践及场景应用 本节课介绍消息队列的MNS的最佳实践及场景应用案例 4、手把手系列:消息队列MNS实操讲 本节课介绍消息队列的MNS的实际操作演示 5、动手实验:基于MNS,0基础轻松构建 Web Client 本节课带您一起基于MNS,0基础轻松构建 Web Client
目录
相关文章
|
29天前
|
物联网 网络性能优化 API
MQTT常见问题之单个消息发送数据不能超过64k如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
29天前
|
消息中间件 物联网 网络性能优化
MQTT常见问题之MQTT的topic超出上限25个如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
25天前
|
消息中间件 NoSQL Kafka
云原生最佳实践系列 5:基于函数计算 FC 实现阿里云 Kafka 消息内容控制 MongoDB DML 操作
该方案描述了一个大数据ETL流程,其中阿里云Kafka消息根据内容触发函数计算(FC)函数,执行针对MongoDB的增、删、改操作。
|
29天前
|
消息中间件 物联网 RocketMQ
MQTT常见问题之RocketMQ到MQTT的消息轨迹查询失败如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
29天前
|
消息中间件 物联网 关系型数据库
MQTT常见问题之消息对列mqtt的历史数据查看失败如何解决
MQTT(Message Queuing Telemetry Transport)是一个轻量级的、基于发布/订阅模式的消息协议,广泛用于物联网(IoT)中设备间的通信。以下是MQTT使用过程中可能遇到的一些常见问题及其答案的汇总:
|
4月前
|
消息中间件 Kafka 流计算
在Flink我从holo读取数据,数据往kafka 写,好像差12个小时, 有没有参数哪里可以配置 ?
在Flink我从holo读取数据,数据往kafka 写,好像差12个小时, 有没有参数哪里可以配置 ?
29 1
|
11月前
|
API Apache
Apache Kafka-通过API获取主题所有分区的积压消息数量
Apache Kafka-通过API获取主题所有分区的积压消息数量
100 0
|
11月前
|
消息中间件 Kafka 开发者
使用生成器把Kafka写入速度提高1000倍
使用生成器把Kafka写入速度提高1000倍
91 0
|
存储 SQL 消息中间件
RocketMQ-Streams 首个版本发布,轻量级计算的新选择
RocketMQ-Streams 聚焦「大数据量-&gt;高过滤-&gt;轻窗口计算」场景,核心打造轻资源,高性能优势,在资源敏感场景有很大优势,最低 1Core,1G 可部署。通过大量过滤优化,性能比其他大数据提升 2-5 倍性能。广泛应用于安全,风控,边缘计算,消息队列流计算。
366 0
RocketMQ-Streams 首个版本发布,轻量级计算的新选择
|
C# 容器
分布式服务器框架之Server.Common库中实现 秒级定时器
定时器模块是服务器中的常用组件,本文带你实现一个具有基本功能的定时器模块要想设计一个定时器模块,一般包含两部分,一个是定时器对象(ServerTimer),另一个管理定时器对象的管理者(TimerManager)也叫定时器容器;定时器使用了C#内System库里面的Timer定时器作为定时器的主驱动
分布式服务器框架之Server.Common库中实现 秒级定时器