У мене є сервіс, який передає повідомлення з досить високою швидкістю.
Наразі його обслуговує akka-tcp, і він повідомляє 3,5 млн повідомлень в хвилину. Я вирішив спробувати grpc. На жаль, це призвело до набагато меншої пропускної здатності: ~ 500k повідомлень в хвилину ще менше.
Чи можете ви порадити, як оптимізувати це?
Моя установка
Обладнання : 32 ядра, купа 24 Гбіт.
версія GRPC: 1.25.0
Формат повідомлення та кінцева точка
Повідомлення в основному є двійковим крапом. Клієнт передає 100K - 1М і більше повідомлень в один запит (асинхронно), сервер нічим не відповідає, клієнт використовує спостережника
service MyService {
rpc send (stream MyMessage) returns (stream DummyResponse);
}
message MyMessage {
int64 someField = 1;
bytes payload = 2; //not huge
}
message DummyResponse {
}
Проблеми: Частота повідомлень низька порівняно з реалізацією akka. Я спостерігаю низьке використання процесора, тому я підозрюю, що виклик grpc насправді блокується внутрішньо, незважаючи на те, що йдеться про інше. Виклик onNext()
дійсно не повертається одразу, але на столі також є GC.
Я спробував породити більше відправників, щоб пом’якшити цю проблему, але не покращився.
Мої висновки Grpc фактично виділяє 8 Кбайт байтовий буфер на кожне повідомлення при його серіалізації. Дивіться стек-трек:
java.lang.Thread.State: BLOCKED (на моніторі об’єктів) на com.google.common.io.ByteStreams.createBuffer (ByteStreams.java:58) на com.google.common.io.ByteStreams.copy (ByteStreams.java: 105) на io.grpc.internal.MessageFramer.writeToOutputStream (MessageFramer.java:274) на io.grpc.internal.MessageFramer.writeKknownLengthUncompression (MessageFramer.java:230) at io.grpc.internal.MessageFramer.writeUncompression (Message : 168) на io.grpc.internal.MessageFramer.writePayload (MessageFramer.java:141) на io.grpc.internal.Ab абстрактStream.writeMessage (AbstractStream.java:53) на io.grpc.internal.ForwardingClientStream.writeMessage (ForwardingClientStream. java: 37) на io.grpc.internal.DelayedStream.writeMessage (DelayedStream.java:252) на io.grpc.internal.ClientCallImpl. (ForwardingClientCall.java:37) на io.grpc.stub.ClientCalls $ CallToStreamObserverAdapter.onNext (ClientCalls.java:346)
Була вдячна будь-яка допомога щодо передового досвіду створення клієнтів високої пропускної здатності.
scalapb
. Ймовірно, цей стек-трек був дійсно від коду, створеного scalapb. Я видалив усе, що стосується scalapb, але це не дуже допомогло Wrt.