Lächerlich langsam gleichzeitige veröffentlichen/konsumieren rate mit RabbitMQ
Ich bin der Bewertung RabbitMQ und während der Allgemeine Eindruck (von AMQP als solche, und auch RabbitMQ) ist positiv, ich bin nicht sehr beeindruckt von dem Ergebnis.
Versuche ich zu veröffentlichen und konsumieren von Nachrichten gleichzeitig und erreicht haben, sehr schlechte Nachricht raten. Ich habe eine dauerhafte direkten Austausch, was zwangsläufig zu einer dauerhaften Warteschlange und ich veröffentlichen, persistente Nachrichten, exchange. Die Durchschnittliche Größe des Nachrichtentexts ist etwa 1000 bytes.
Meine Veröffentlichung geschieht etwa wie folgt:
AMQP.BasicProperties.Builder bldr = new AMQP.BasicProperties.Builder();
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setHost("my-host");
factory.setPort(5672);
Connection conn = null;
Channel channel = null;
ObjectMapper mapper = new ObjectMapper(); //com.fasterxml.jackson.databind.ObjectMapper
try {
conn = factory.newConnection();
channel = conn.createChannel();
channel.confirmSelect();
} catch (IOException e) {}
for(Message m : messageList) { //the size of messageList happens to be 9945
try {
channel.basicPublish("exchange", "", bldr.deliveryMode(2).contentType("application/json").build(), mapper.writeValueAsBytes(cm));
} catch (Exception e) {}
}
try {
channel.waitForConfirms();
channel.close();
conn.close();
} catch (Exception e1) {}
Und konsumieren Nachrichten aus der gebundenen Warteschlange geschieht so:
AMQP.BasicProperties.Builder bldr = new AMQP.BasicProperties.Builder();
ConnectionFactory factory = new ConnectionFactory();
factory.setUsername("guest");
factory.setPassword("guest");
factory.setVirtualHost("/");
factory.setHost("my-host");
factory.setPort(5672);
Connection conn = null;
Channel channel = null;
try {
conn = factory.newConnection();
channel = conn.createChannel();
channel.basicQos(100);
while (true) {
GetResponse r = channel.basicGet("rawDataQueue", false);
if(r!=null)
channel.basicAck(r.getEnvelope().getDeliveryTag(), false);
}
} catch (IOException e) {}
Das problem ist, dass wenn die Nachricht, die publisher (oder mehrere) und Verbraucher (oder mehrere) gleichzeitig ausgeführt werden und dann der Herausgeber(s) scheinen mit Vollgas laufen, und das RabbitMQ-management-web-interface zeigt eine publishing-rate von, sagen wir, ~2...3K-Nachrichten pro Sekunde, aber ein Verbrauch von 0,5...3 pro Verbraucher. Wenn der Herausgeber(s) fertig stellen, dann bekomme ich einen Verbrauch von, sagen wir, 300...600 Nachrichten pro Verbraucher. Wenn nicht die Einstellung der QOS-prefetch-Wert für den Java-client, dann ein bisschen weniger, wenn Sie die 100-oder 250, dann ein bisschen mehr.
Beim Experimentieren mit Drosselung der Verbraucher etwas, ich habe es geschafft, zu erreichen gleichzeitige zahlen wie ~400 veröffentlicht und ~50 konsumierten Nachrichten pro Sekunde, die ist geringfügig besser, aber nur marginal.
Hier, ein Zitat aus der RabbitMQ blog-Eintrag, die behauptet, dass die Warteschlangen am schnellsten, wenn Sie leer sind, die sehr gut sein kann, aber die Verlangsamung des Konsums auf ein Schneckentempo, wenn es ein paar tausend persistente Nachrichten sitzen in der Warteschlange ist noch eher inakzeptabel.
Höheren QOS-prefetching-Werte können ein wenig helfen, aber sind IMHO nicht die Lösung als solche.
Was, wenn überhaupt, kann getan werden, um die Erzielung eines angemessenen Durchsatz (2 verwendeten Nachrichten pro Verbraucher pro Sekunde ist nicht sinnvoll in jeder Situation)? Dies ist nur eine einfache direkte exchange - eine Bindung - ein Warteschlangen-situation, sollte ich erwarten, mehr Leistungseinbußen mit komplizierter Konfigurationen? Bei der Suche rund um das internet, es wurden auch Vorschläge zu Tropfen Haltbarkeit, aber ich fürchte, in meinem Fall ist dies keine option. Ich wäre sehr glücklich, wenn jemand möchte darauf hinweisen, dass ich dumm bin und dass es eine klare und einfache Lösung irgendeiner Art 🙂
InformationsquelleAutor Manjabes | 2013-12-11
Du musst angemeldet sein, um einen Kommentar abzugeben.
Haben Sie versucht, mit der autoAck option? Das sollte deine performance verbessern. Es ist viel schneller, als sich die Nachrichten und ack ' Ing. Die Erhöhung der prefetch-count sollte es noch besser machen zu können.
Auch, was die Größe der Nachrichten, die Sie senden und zu konsumieren, einschließlich Kopf? Erleben Sie jede flow-control bei der broker?
Andere Frage, sind Sie für das erstellen einer Verbindung und Kanal jedes mal, wenn Sie auf senden/erhalten eine Nachricht? Wenn ja, ist das falsch. Sie sollte eine Verbindung einmal, und verwenden Sie einen Kanal pro thread (wahrscheinlich in einem lokalen thread-Mode) zum senden und empfangen von Nachrichten. Sie können mehrere Kanäle pro Verbindung. Es gibt keine offizielle Dokumentation, aber wenn Sie Lesen Sie Artikel und Foren scheint dies die beste Leistung der Praxis.
Letzte Sache, die Sie als mit den
basicConsume
stattbasicGet
? Es sollte auch damit es schneller geht.Basierend auf meiner Erfahrung, ich habe die Möglichkeit, einen cluster zu senden und das konsumieren auf raten um 20000 Nachrichten pro Sekunde mit nicht-persistenten Nachrichten. Ich denke, dass, wenn Sie verwenden langlebige und persistente Nachrichten, die Leistung würde sinken ein wenig, aber nicht 10x.
OK, mit QueueingConsumer mit ausdrücklicher Danksagung ich übertragungsraten von über 2500 pubs/250 subs gleichzeitig, das ist viel besser als vorher, aber nicht perfekt.
Können Sie erneut versuchen, das entfernen der
channel.confirmSelect();
undchannel.waitForConfirms();
aus Ihren publishing-code?Tat so und erreicht Spitzen von 12+K msgs/sec für die Veröffentlichung und 900...2,5 K für das konsumieren. Die Ergebnisse sind jedoch verzerrt durch die Tatsache, dass die Warteschlange sitzt auf dem anderen Ende der 100M-Netzwerk-link, und dass zu sein schien gesättigt von den Verlagen.
Ok, dass war jetzt eine Ahnung, dass die led irgendwo: wenn ich installiert und lief die MQ von meinem dev-Rechner, auf dem die Erzeuger und Verbraucher laufen, ich erreichte eine gleichzeitige veröffentlichen/Verbrauch von über 2K msg/Sek.
InformationsquelleAutor hveiga
Betriebssystem konnte planen Sie Ihren Prozess auf das nächste Zeitfenster, wenn
sleep
verwendet wird. Dies könnte zu einem deutlichen Leistungsabfall.InformationsquelleAutor Secult