Redis / RabbitMQ - Pub / Sub - 性能

发布于 2024-12-05 13:12:51 字数 2404 浏览 1 评论 0原文

我为一个简单的场景编写了一个小测试:

一个发布者和一个订阅者

发布者发送 1000000 条消息

订阅者接收 1000000 条消息

使用 RabbitMQ、扇出 Exchange、RabbitMq 节点类型 Ram 进行第一次测试:320 秒

使用 Redis 进行第二次测试,基本 pub/Sub:24秒

我错过了什么吗?为什么会有这样的差别呢?这是配置问题还是什么?

第一种场景:一个用于订阅者的 Node.js 进程,一个用于发布者,每个进程都有一个使用 amqp 节点模块与rabbitmq 的连接。 第二种场景:一个用于订阅者的 Node.js 进程,一个用于发布者的进程,每个进程都有一个到 Redis 的连接。

欢迎任何帮助来理解...如果需要,我可以分享代码。

我对这一切都很陌生。 我需要的是一个高性能的发布/订阅消息系统。我想要具有集群功能。

为了运行我的测试,我只需启动rabbitMq服务器(默认配置)并使用以下

Publisher.js

var sys  = require('sys');
var amqp = require('amqp');
var nb_messages = process.argv[2];
var connection  = amqp.createConnection({url: 'amqp://guest:guest@localhost:5672'});

connection.addListener('ready', function () {
    exchangeName = 'myexchange';   
    var start = end = null;
    var exchange = connection.exchange(exchangeName, {type: 'fanout'}, function(exchange){
        start = (new Date()).getTime();

        for(i=1; i <= nb_messages; i++){
            if (i%1000 == 0){
                console.log("x");
            }
            exchange.publish("", "hello");
        }

        end = (new Date()).getTime();
        console.log("Publishing duration: "+((end-start)/1000)+" sec");
        process.exit(0);
    });
});

Subscriber.js

var sys  = require('sys');
var amqp = require('amqp');
var nb_messages = process.argv[2];
var connection = amqp.createConnection({url: 'amqp://guest:guest@localhost:5672'});

connection.addListener('ready', function () {    
    exchangeName = 'myexchange';
    queueName    = 'myqueue'+Math.random();

    var queue    = connection.queue(queueName, function (queue) {
        queue.bind(exchangeName, "");
        queue.start       = false;
        queue.nb_messages = 0;

        queue.subscribe(function (message) {
            if (!queue.start){
                queue.start = (new Date()).getTime();
            }
            queue.nb_messages++;
            if (queue.nb_messages % 1000 == 0){
                console.log('+');
            }
            if (queue.nb_messages >= nb_messages){
                queue.end = (new Date()).getTime();
                console.log("Ending at "+queue.end);
                console.log("Receive duration: "+((queue.end - queue.start)/1000));
                process.exit(0);
            }
        });
    });
});

I wrote a little test for a simple scenario:

One publisher and one subscriber

Publisher send 1000000 messages

Subscriber receive the 1000000 messages

First test with RabbitMQ, fanout Exchange, RabbitMq node type Ram : 320 seconds

Second test with Redis, basic pub/Sub : 24 seconds

Am i missing something? Why a such difference ? Is this a configuration problem or something?

First scenario: one node.js process for the subscriber, one for the publisher, each one, one connection to rabbitmq with amqp node module.
Second scénario: one node.js process for the subscriber, one for the publisher, each one got one connection to redis.

Any help is welcom to understand... I can share the code if needed.

i'm pretty new to all of this.
What i need, is a high performances pub / sub messaging system. I'd like to have clustering capabilities.

To run my test, i just launch the rabbitMq server (default configuration) and i use the following

Publisher.js

var sys  = require('sys');
var amqp = require('amqp');
var nb_messages = process.argv[2];
var connection  = amqp.createConnection({url: 'amqp://guest:guest@localhost:5672'});

connection.addListener('ready', function () {
    exchangeName = 'myexchange';   
    var start = end = null;
    var exchange = connection.exchange(exchangeName, {type: 'fanout'}, function(exchange){
        start = (new Date()).getTime();

        for(i=1; i <= nb_messages; i++){
            if (i%1000 == 0){
                console.log("x");
            }
            exchange.publish("", "hello");
        }

        end = (new Date()).getTime();
        console.log("Publishing duration: "+((end-start)/1000)+" sec");
        process.exit(0);
    });
});

Subscriber.js

var sys  = require('sys');
var amqp = require('amqp');
var nb_messages = process.argv[2];
var connection = amqp.createConnection({url: 'amqp://guest:guest@localhost:5672'});

connection.addListener('ready', function () {    
    exchangeName = 'myexchange';
    queueName    = 'myqueue'+Math.random();

    var queue    = connection.queue(queueName, function (queue) {
        queue.bind(exchangeName, "");
        queue.start       = false;
        queue.nb_messages = 0;

        queue.subscribe(function (message) {
            if (!queue.start){
                queue.start = (new Date()).getTime();
            }
            queue.nb_messages++;
            if (queue.nb_messages % 1000 == 0){
                console.log('+');
            }
            if (queue.nb_messages >= nb_messages){
                queue.end = (new Date()).getTime();
                console.log("Ending at "+queue.end);
                console.log("Receive duration: "+((queue.end - queue.start)/1000));
                process.exit(0);
            }
        });
    });
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

情仇皆在手 2024-12-12 13:12:51

检查以确保:

  • 您的 RabbitMQ 队列未配置为持久队列(因为这需要为每条消息进行磁盘写入)
  • 您订阅者端的预取计数为 0
  • 您没有使用事务或发布者确认

还有其他可以调整的事情,但如果不知道测试的细节,就很难猜测。我只是确保您正在比较“苹果与苹果”。

大多数消息传递产品都可以以尽可能快的速度运行,但会牺牲各种保证(例如交付保证等),因此请确保您首先了解应用程序的要求。如果您唯一的要求是将数据从 A 点转移到 B 点,并且您可以容忍丢失一些消息,那么几乎每个消息传递系统都可以做到这一点,并且做得很好。更困难的部分是弄清楚除了原始速度之外您还需要什么,并进行调整以满足这些要求。

Check to ensure that:

  • Your RabbitMQ queue is not configured as persistent (since that would require disk writes for each message)
  • Your prefetch count on the subscriber side is 0
  • You are not using transactions or publisher confirms

There are other things which could be tuned, but without knowing the details of your test it's hard to guess. I would just make sure that you are comparing "apples to apples".

Most messaging products can be made to go as fast as humanly possible at the expense of various guarantees (like delivery assurance, etc) so make sure you understand your application's requirements first. If your only requirement is for data to get shoveled from point A to point B and you can tolerate the loss of some messages, pretty much every messaging system out there can do that, and do it well. The harder part is figuring out what you need beyond raw speed, and tuning to meet those requirements as well.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文