mirror of
https://github.com/apache/rocketmq.git
synced 2026-08-29 04:13:00 +08:00
Add the ability to write ConsumeQueue using fileChannel to prevent JVM crashes in some situations (#8403)
This commit is contained in:
@@ -833,7 +833,13 @@ public class ConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCycle {
|
||||
}
|
||||
}
|
||||
this.setMaxPhysicOffset(offset + size);
|
||||
return mappedFile.appendMessage(this.byteBufferIndex.array());
|
||||
boolean appendResult;
|
||||
if (messageStore.getMessageStoreConfig().isPutConsumeQueueDataByFileChannel()) {
|
||||
appendResult = mappedFile.appendMessageUsingFileChannel(this.byteBufferIndex.array());
|
||||
} else {
|
||||
appendResult = mappedFile.appendMessage(this.byteBufferIndex.array());
|
||||
}
|
||||
return appendResult;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -846,7 +852,12 @@ public class ConsumeQueue implements ConsumeQueueInterface, FileQueueLifeCycle {
|
||||
|
||||
int until = (int) (untilWhere % this.mappedFileQueue.getMappedFileSize());
|
||||
for (int i = 0; i < until; i += CQ_STORE_UNIT_SIZE) {
|
||||
mappedFile.appendMessage(byteBuffer.array());
|
||||
if (messageStore.getMessageStoreConfig().isPutConsumeQueueDataByFileChannel()) {
|
||||
mappedFile.appendMessageUsingFileChannel(byteBuffer.array());
|
||||
} else {
|
||||
mappedFile.appendMessage(byteBuffer.array());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -419,6 +419,8 @@ public class MessageStoreConfig {
|
||||
*/
|
||||
private boolean readUnCommitted = false;
|
||||
|
||||
private boolean putConsumeQueueDataByFileChannel = true;
|
||||
|
||||
public boolean isEnabledAppendPropCRC() {
|
||||
return enabledAppendPropCRC;
|
||||
}
|
||||
@@ -1832,4 +1834,12 @@ public class MessageStoreConfig {
|
||||
public void setReadUnCommitted(boolean readUnCommitted) {
|
||||
this.readUnCommitted = readUnCommitted;
|
||||
}
|
||||
|
||||
public boolean isPutConsumeQueueDataByFileChannel() {
|
||||
return putConsumeQueueDataByFileChannel;
|
||||
}
|
||||
|
||||
public void setPutConsumeQueueDataByFileChannel(boolean putConsumeQueueDataByFileChannel) {
|
||||
this.putConsumeQueueDataByFileChannel = putConsumeQueueDataByFileChannel;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,14 +97,14 @@ public class DefaultMappedFile extends AbstractMappedFile {
|
||||
protected long mappedByteBufferAccessCountSinceLastSwap = 0L;
|
||||
|
||||
/**
|
||||
* If this mapped file belongs to consume queue, this field stores store-timestamp of first message referenced
|
||||
* by this logical queue.
|
||||
* If this mapped file belongs to consume queue, this field stores store-timestamp of first message referenced by
|
||||
* this logical queue.
|
||||
*/
|
||||
private long startTimestamp = -1;
|
||||
|
||||
/**
|
||||
* If this mapped file belongs to consume queue, this field stores store-timestamp of last message referenced
|
||||
* by this logical queue.
|
||||
* If this mapped file belongs to consume queue, this field stores store-timestamp of last message referenced by
|
||||
* this logical queue.
|
||||
*/
|
||||
private long stopTimestamp = -1;
|
||||
|
||||
@@ -357,6 +357,24 @@ public class DefaultMappedFile extends AbstractMappedFile {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean appendMessageUsingFileChannel(byte[] data) {
|
||||
int currentPos = WROTE_POSITION_UPDATER.get(this);
|
||||
|
||||
if ((currentPos + data.length) <= this.fileSize) {
|
||||
try {
|
||||
this.fileChannel.position(currentPos);
|
||||
this.fileChannel.write(ByteBuffer.wrap(data, 0, data.length));
|
||||
} catch (Throwable e) {
|
||||
log.error("Error occurred when append message to mappedFile.", e);
|
||||
}
|
||||
WROTE_POSITION_UPDATER.addAndGet(this, data.length);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return The current flushed position
|
||||
*/
|
||||
@@ -840,7 +858,6 @@ public class DefaultMappedFile extends AbstractMappedFile {
|
||||
this.stopTimestamp = stopTimestamp;
|
||||
}
|
||||
|
||||
|
||||
public Iterator<SelectMappedBufferResult> iterator(int startPos) {
|
||||
return new Itr(startPos);
|
||||
}
|
||||
|
||||
@@ -101,12 +101,23 @@ public interface MappedFile {
|
||||
|
||||
/**
|
||||
* Appends a raw message data represents by a byte array to the current {@code MappedFile}.
|
||||
* Using mappedByteBuffer
|
||||
*
|
||||
* @param data the byte array to append
|
||||
* @return true if success; false otherwise.
|
||||
*/
|
||||
boolean appendMessage(byte[] data);
|
||||
|
||||
|
||||
/**
|
||||
* Appends a raw message data represents by a byte array to the current {@code MappedFile}.
|
||||
* Using fileChannel
|
||||
*
|
||||
* @param data the byte array to append
|
||||
* @return true if success; false otherwise.
|
||||
*/
|
||||
boolean appendMessageUsingFileChannel(byte[] data);
|
||||
|
||||
/**
|
||||
* Appends a raw message data represents by a byte array to the current {@code MappedFile}.
|
||||
*
|
||||
|
||||
@@ -587,7 +587,12 @@ public class BatchConsumeQueue implements ConsumeQueueInterface {
|
||||
MappedFile mappedFile = this.mappedFileQueue.getLastMappedFile(this.mappedFileQueue.getMaxOffset());
|
||||
if (mappedFile != null) {
|
||||
boolean isNewFile = isNewFile(mappedFile);
|
||||
boolean appendRes = mappedFile.appendMessage(this.byteBufferItem.array());
|
||||
boolean appendRes;
|
||||
if (messageStore.getMessageStoreConfig().isPutConsumeQueueDataByFileChannel()) {
|
||||
appendRes = mappedFile.appendMessageUsingFileChannel(this.byteBufferItem.array());
|
||||
} else {
|
||||
appendRes = mappedFile.appendMessage(this.byteBufferItem.array());
|
||||
}
|
||||
if (appendRes) {
|
||||
maxMsgPhyOffsetInCommitLog = offset;
|
||||
maxOffsetInQueue = msgBaseOffset + batchSize;
|
||||
|
||||
@@ -262,7 +262,15 @@ public class SparseConsumeQueue extends BatchConsumeQueue {
|
||||
this.byteBufferItem.putShort((short)0);
|
||||
this.byteBufferItem.putInt(INVALID_POS);
|
||||
this.byteBufferItem.putInt(0); // 4 bytes reserved
|
||||
boolean appendRes = mappedFile.appendMessage(this.byteBufferItem.array());
|
||||
|
||||
boolean appendRes;
|
||||
|
||||
if (messageStore.getMessageStoreConfig().isPutConsumeQueueDataByFileChannel()) {
|
||||
appendRes = mappedFile.appendMessageUsingFileChannel(this.byteBufferItem.array());
|
||||
} else {
|
||||
appendRes = mappedFile.appendMessage(this.byteBufferItem.array());
|
||||
}
|
||||
|
||||
if (!appendRes) {
|
||||
log.error("append end position info into {} failed", mappedFile.getFileName());
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user