Я сделал нагрузочный тест для rocketmq, потом обнаружил много длинных звонков, стоимость длинных звонков намного превышала 100 мс, но я прочитал исходный код длинного звонка, основная стоимость - написание байтового буфера. Основной код вроде этого:
public AppendMessageResult doAppend(final long fileFromOffset,
final ByteBuffer byteBuffer, final int maxBlank,
final MessageExtBrokerInner msgInner) {//from CommitLog.java
...
final long beginTimeMills = CommitLog.this.defaultMessageStore.now();
byteBuffer.put(this.msgStoreItemMemory.array(), 0, msgLen);
AppendMessageResult result = new AppendMessageResult(AppendMessageStatus.PUT_OK, wroteOffset, msgLen, msgId,
msgInner.getStoreTimestamp(), queueOffset, CommitLog.this.defaultMessageStore.now() - beginTimeMills);
return result;
}
Журнал показывает, что стоимость CommitLog.this.defaultMessageStore.now() - beginTimeMills (pagecacheRT в журнале ниже) превышает 100 мс.
2018-04-09 00:24:41 WARN SendMessageThread_1 - [NOTIFYME]putMessage in lock cost time(ms)=517 nano time(ms)=516, bodyLength=130 AppendMessageResult=AppendMessageResult{status=PUT_OK, wroteOffset=3113603972920, wroteBytes=128, msgId='0A0C240300002A9F000002D4F1423F38', storeTimestamp=1523204680621, logicsOffset=11016755, pagecacheRT=517, msgNum=1}
pagecacheRT - это стоимость времени операции put. Затем я увидел код инициализации byteBuffer, например:
public void init() {
for (int i = 0; i < poolSize; i++) {
ByteBuffer byteBuffer = ByteBuffer.allocateDirect(fileSize);
final long address = ((DirectBuffer) byteBuffer).address();
Pointer pointer = new Pointer(address);
LibC.INSTANCE.mlock(pointer, new NativeLong(fileSize));
availableBuffers.offer(byteBuffer);
}
}
Bytebuffer - это просто directBuffer. Моя тестовая среда - это физическая машина с 32 процессорами и 96 ГБ памяти, а байты записи - это 125 байтов до записи. Я видел монитор во время нагрузочного теста, ЦП и диск в порядке. Я не думаю, что эта проблема вызвана инструментами rocketmq, потому что основной код очень простой, это только код раздела выше.
Но я не могу понять, почему написание воспоминаний может стоить столько времени. Есть ли способ понять это или что-то в этом роде?
Заранее спасибо!
извините, это мой первый вопрос по stackoverflow. «32C96G» означает, что количество процессоров составляет 32, а количество физической памяти - 96 ГБ. Позвольте мне заполнить код
Я не знаю RocketMQ, но знаю сети. Вы разговариваете через Интернет с каким-то сервером? В этом случае задержки 100 мс - это нормально.
Нет, просто запишите байты в память без каких-либо других операций
Вы имеете в виду byteBuffer.put(this.msgStoreItemMemory.array(), 0, msgLen);. Похоже, вы конвертируете в массив, а затем копируете из него. Почему бы не скрыть массив, а затем использовать ByteBuffer :: wrap?
Я знаю, что вы имеете в виду. Но этот буфер также добавляет много других метаданных, таких как смещение, размер сообщения перед этой операцией. Хотя я согласен с вашим мнением, я хочу знать, почему эта операция так дорого стоит.




Это не так уж много, как и остальная часть вашего кода - это не MCVE - или количество байтов, которые вы пишете. А что значит "32C96G"?