Запись байтабуфера отнимает слишком много времени

Я сделал нагрузочный тест для 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, потому что основной код очень простой, это только код раздела выше.

Но я не могу понять, почему написание воспоминаний может стоить столько времени. Есть ли способ понять это или что-то в этом роде?

Заранее спасибо!

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

SeverityOne 08.04.2018 11:15

извините, это мой первый вопрос по stackoverflow. «32C96G» означает, что количество процессоров составляет 32, а количество физической памяти - 96 ГБ. Позвольте мне заполнить код

yuzhou.li 08.04.2018 18:07

Я не знаю RocketMQ, но знаю сети. Вы разговариваете через Интернет с каким-то сервером? В этом случае задержки 100 мс - это нормально.

Thomas 08.04.2018 18:39

Нет, просто запишите байты в память без каких-либо других операций

yuzhou.li 08.04.2018 18:40

Вы имеете в виду byteBuffer.put(this.msgStoreItemMemory.array(), 0, msgLen);. Похоже, вы конвертируете в массив, а затем копируете из него. Почему бы не скрыть массив, а затем использовать ByteBuffer :: wrap?

K.Nicholas 08.04.2018 21:12

Я знаю, что вы имеете в виду. Но этот буфер также добавляет много других метаданных, таких как смещение, размер сообщения перед этой операцией. Хотя я согласен с вашим мнением, я хочу знать, почему эта операция так дорого стоит.

yuzhou.li 09.04.2018 10:47
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
6
192
0

Другие вопросы по теме