我对rocketmq进行了负载测试,然后我发现了很长时间的通话,长时间通话费用远远超过100ms。但是我读了长呼叫的源代码,主要成本是写入bytebuffer。核心代码如下:
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个处理器和96G内存的pyhsical机器,并且写入字节是预写入的125byte。我在负载测试期间看到了显示器,CPU和磁盘非常健康。我不认为这个问题是由rocketmq的工具引起的。因为主代码非常简单,只是上面的代码。
但是我无法理解为什么写作记忆会花费这么多时间。有什么方法可以理解这些或其他东西吗?
提前致谢!