You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by an...@apache.org on 2016/07/25 17:28:50 UTC
hbase git commit: HBASE-16205 When Cells are not copied to MSLAB,
deep clone it while adding to Memstore.
Repository: hbase
Updated Branches:
refs/heads/master 6dbce2a8c -> 2df0ef549
HBASE-16205 When Cells are not copied to MSLAB, deep clone it while adding to Memstore.
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/2df0ef54
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/2df0ef54
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/2df0ef54
Branch: refs/heads/master
Commit: 2df0ef549abe0ee8e58d4290193b5d69b3e8d6c6
Parents: 6dbce2a
Author: anoopsjohn <an...@gmail.com>
Authored: Mon Jul 25 22:58:32 2016 +0530
Committer: anoopsjohn <an...@gmail.com>
Committed: Mon Jul 25 22:58:32 2016 +0530
----------------------------------------------------------------------
.../apache/hadoop/hbase/ShareableMemory.java | 39 ++++++++++++++++++++
.../hadoop/hbase/codec/KeyValueCodec.java | 33 ++++++++++++++++-
.../hbase/codec/KeyValueCodecWithTags.java | 3 +-
.../hbase/regionserver/AbstractMemStore.java | 33 +++++++++++++++--
4 files changed, 101 insertions(+), 7 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/2df0ef54/hbase-common/src/main/java/org/apache/hadoop/hbase/ShareableMemory.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/ShareableMemory.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/ShareableMemory.java
new file mode 100644
index 0000000..6a6ae59
--- /dev/null
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/ShareableMemory.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright The Apache Software Foundation
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase;
+
+import org.apache.hadoop.hbase.classification.InterfaceAudience;
+
+/**
+ * A cell implementing this interface would mean that the memory area backing this cell will refer
+ * to a memory area that could be part of a larger common memory area used by the RegionServer. This
+ * might be the bigger memory chunk where the RPC requests are read into. If an exclusive instance
+ * is required, use the {@link #cloneToCell()} to have the contents of the cell copied to an
+ * exclusive memory area.
+ */
+@InterfaceAudience.Private
+public interface ShareableMemory {
+
+ /**
+ * Does a deep copy of the contents to a new memory area and returns it in the form of a cell.
+ * @return The deep cloned cell
+ */
+ Cell cloneToCell();
+}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2df0ef54/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodec.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodec.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodec.java
index df2e740..5165f58 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodec.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodec.java
@@ -24,10 +24,13 @@ import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
+import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.NoTagsKeyValue;
+import org.apache.hadoop.hbase.ShareableMemory;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.util.ByteBufferUtils;
+import org.apache.hadoop.hbase.util.Bytes;
/**
* Codec that does KeyValue version 1 serialization.
@@ -99,7 +102,35 @@ public class KeyValueCodec implements Codec {
}
protected Cell createCell(byte[] buf, int offset, int len) {
- return new NoTagsKeyValue(buf, offset, len);
+ return new ShareableMemoryNoTagsKeyValue(buf, offset, len);
+ }
+
+ static class ShareableMemoryKeyValue extends KeyValue implements ShareableMemory {
+ public ShareableMemoryKeyValue(byte[] bytes, int offset, int length) {
+ super(bytes, offset, length);
+ }
+
+ @Override
+ public Cell cloneToCell() {
+ byte[] copy = Bytes.copy(this.bytes, this.offset, this.length);
+ KeyValue kv = new KeyValue(copy, 0, copy.length);
+ kv.setSequenceId(this.getSequenceId());
+ return kv;
+ }
+ }
+
+ static class ShareableMemoryNoTagsKeyValue extends NoTagsKeyValue implements ShareableMemory {
+ public ShareableMemoryNoTagsKeyValue(byte[] bytes, int offset, int length) {
+ super(bytes, offset, length);
+ }
+
+ @Override
+ public Cell cloneToCell() {
+ byte[] copy = Bytes.copy(this.bytes, this.offset, this.length);
+ KeyValue kv = new NoTagsKeyValue(copy, 0, copy.length);
+ kv.setSequenceId(this.getSequenceId());
+ return kv;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2df0ef54/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodecWithTags.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodecWithTags.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodecWithTags.java
index 714cc38..8d2ee99 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodecWithTags.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/codec/KeyValueCodecWithTags.java
@@ -24,7 +24,6 @@ import java.nio.ByteBuffer;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.HBaseInterfaceAudience;
-import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValueUtil;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
@@ -85,7 +84,7 @@ public class KeyValueCodecWithTags implements Codec {
}
protected Cell createCell(byte[] buf, int offset, int len) {
- return new KeyValue(buf, offset, len);
+ return new ShareableMemoryKeyValue(buf, offset, len);
}
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/2df0ef54/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/AbstractMemStore.java
----------------------------------------------------------------------
diff --git a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/AbstractMemStore.java b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/AbstractMemStore.java
index 2b9910f..4716eee 100644
--- a/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/AbstractMemStore.java
+++ b/hbase-server/src/main/java/org/apache/hadoop/hbase/regionserver/AbstractMemStore.java
@@ -33,6 +33,7 @@ import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.CellUtil;
import org.apache.hadoop.hbase.KeyValue;
import org.apache.hadoop.hbase.KeyValueUtil;
+import org.apache.hadoop.hbase.ShareableMemory;
import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.ClassSize;
@@ -110,9 +111,31 @@ public abstract class AbstractMemStore implements MemStore {
public long add(Cell cell) {
Cell toAdd = maybeCloneWithAllocator(cell);
boolean mslabUsed = (toAdd != cell);
+ // This cell data is backed by the same byte[] where we read request in RPC(See HBASE-15180). By
+ // default MSLAB is ON and we might have copied cell to MSLAB area. If not we must do below deep
+ // copy. Or else we will keep referring to the bigger chunk of memory and prevent it from
+ // getting GCed.
+ // Copy to MSLAB would not have happened if
+ // 1. MSLAB is turned OFF. See "hbase.hregion.memstore.mslab.enabled"
+ // 2. When the size of the cell is bigger than the max size supported by MSLAB. See
+ // "hbase.hregion.memstore.mslab.max.allocation". This defaults to 256 KB
+ // 3. When cells are from Append/Increment operation.
+ if (!mslabUsed) {
+ toAdd = deepCopyIfNeeded(toAdd);
+ }
return internalAdd(toAdd, mslabUsed);
}
+ private static Cell deepCopyIfNeeded(Cell cell) {
+ // When Cell is backed by a shared memory chunk (this can be a chunk of memory where we read the
+ // req into) the Cell instance will be of type ShareableMemory. Later we will add feature to
+ // read the RPC request into pooled direct ByteBuffers.
+ if (cell instanceof ShareableMemory) {
+ return ((ShareableMemory) cell).cloneToCell();
+ }
+ return cell;
+ }
+
/**
* Update or insert the specified Cells.
* <p>
@@ -156,10 +179,8 @@ public abstract class AbstractMemStore implements MemStore {
*/
@Override
public long delete(Cell deleteCell) {
- Cell toAdd = maybeCloneWithAllocator(deleteCell);
- boolean mslabUsed = (toAdd != deleteCell);
- long s = internalAdd(toAdd, mslabUsed);
- return s;
+ // Delete operation just adds the delete marker cell coming here.
+ return add(deleteCell);
}
/**
@@ -245,6 +266,10 @@ public abstract class AbstractMemStore implements MemStore {
// hitting OOME - see TestMemStore.testUpsertMSLAB for a
// test that triggers the pathological case if we don't avoid MSLAB
// here.
+ // This cell data is backed by the same byte[] where we read request in RPC(See HBASE-15180). We
+ // must do below deep copy. Or else we will keep referring to the bigger chunk of memory and
+ // prevent it from getting GCed.
+ cell = deepCopyIfNeeded(cell);
long addedSize = internalAdd(cell, false);
// Get the Cells for the row/family/qualifier regardless of timestamp.