HBASE-2985 HRegionServer.multi() no longer calls HRegion.put(List) when possible
git-svn-id: https://svn.apache.org/repos/asf/hbase/trunk@1024074 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
113d533ad7
commit
1eede65ae1
|
@ -596,6 +596,8 @@ Release 0.21.0 - Unreleased
|
||||||
HBASE-3121 [rest] Do not perform cache control when returning results
|
HBASE-3121 [rest] Do not perform cache control when returning results
|
||||||
HBASE-2669 HCM.shutdownHook causes data loss with
|
HBASE-2669 HCM.shutdownHook causes data loss with
|
||||||
hbase.client.write.buffer != 0
|
hbase.client.write.buffer != 0
|
||||||
|
HBASE-2985 HRegionServer.multi() no longer calls HRegion.put(List) when
|
||||||
|
possible
|
||||||
|
|
||||||
IMPROVEMENTS
|
IMPROVEMENTS
|
||||||
HBASE-1760 Cleanup TODOs in HTable
|
HBASE-1760 Cleanup TODOs in HTable
|
||||||
|
|
|
@ -1176,7 +1176,7 @@ public class HConnectionManager {
|
||||||
List<Pair<Integer, Result>> regionResults = e.getValue();
|
List<Pair<Integer, Result>> regionResults = e.getValue();
|
||||||
for (Pair<Integer, Result> regionResult : regionResults) {
|
for (Pair<Integer, Result> regionResult : regionResults) {
|
||||||
if (regionResult == null) {
|
if (regionResult == null) {
|
||||||
// failed
|
// if the first/only record is 'null' the entire region failed.
|
||||||
LOG.debug("Failures for region: " + Bytes.toStringBinary(regionName) + ", removing from cache");
|
LOG.debug("Failures for region: " + Bytes.toStringBinary(regionName) + ", removing from cache");
|
||||||
} else {
|
} else {
|
||||||
// success
|
// success
|
||||||
|
|
|
@ -551,7 +551,10 @@ public class HTable implements HTableInterface {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Method that does a batch call on Deletes, Gets and Puts.
|
* Method that does a batch call on Deletes, Gets and Puts. The ordering of
|
||||||
|
* execution of the actions is not defined. Meaning if you do a Put and a
|
||||||
|
* Get in the same {@link #batch} call, you will not necessarily be
|
||||||
|
* guaranteed that the Get returns what the Put had put.
|
||||||
*
|
*
|
||||||
* @param actions list of Get, Put, Delete objects
|
* @param actions list of Get, Put, Delete objects
|
||||||
* @param results Empty Result[], same size as actions. Provides access to partial
|
* @param results Empty Result[], same size as actions. Provides access to partial
|
||||||
|
|
|
@ -42,8 +42,8 @@ public class MultiResponse implements Writable {
|
||||||
|
|
||||||
// map of regionName to list of (Results paired to the original index for that
|
// map of regionName to list of (Results paired to the original index for that
|
||||||
// Result)
|
// Result)
|
||||||
private Map<byte[], List<Pair<Integer, Result>>> results = new TreeMap<byte[], List<Pair<Integer, Result>>>(
|
private Map<byte[], List<Pair<Integer, Result>>> results =
|
||||||
Bytes.BYTES_COMPARATOR);
|
new TreeMap<byte[], List<Pair<Integer, Result>>>(Bytes.BYTES_COMPARATOR);
|
||||||
|
|
||||||
public MultiResponse() {
|
public MultiResponse() {
|
||||||
}
|
}
|
||||||
|
|
|
@ -2330,9 +2330,11 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
|
||||||
// actions in the list.
|
// actions in the list.
|
||||||
Collections.sort(actionsForRegion);
|
Collections.sort(actionsForRegion);
|
||||||
Row action = null;
|
Row action = null;
|
||||||
|
List<Action> puts = new ArrayList<Action>();
|
||||||
try {
|
try {
|
||||||
for (Action a : actionsForRegion) {
|
for (Action a : actionsForRegion) {
|
||||||
action = a.getAction();
|
action = a.getAction();
|
||||||
|
// TODO catch exceptions so we can report them on a per-item basis.
|
||||||
if (action instanceof Delete) {
|
if (action instanceof Delete) {
|
||||||
delete(regionName, (Delete) action);
|
delete(regionName, (Delete) action);
|
||||||
response.add(regionName, new Pair<Integer, Result>(
|
response.add(regionName, new Pair<Integer, Result>(
|
||||||
|
@ -2341,14 +2343,50 @@ public class HRegionServer implements HRegionInterface, HBaseRPCErrorHandler,
|
||||||
response.add(regionName, new Pair<Integer, Result>(
|
response.add(regionName, new Pair<Integer, Result>(
|
||||||
a.getOriginalIndex(), get(regionName, (Get) action)));
|
a.getOriginalIndex(), get(regionName, (Get) action)));
|
||||||
} else if (action instanceof Put) {
|
} else if (action instanceof Put) {
|
||||||
put(regionName, (Put) action);
|
puts.add(a);
|
||||||
response.add(regionName, new Pair<Integer, Result>(
|
|
||||||
a.getOriginalIndex(), new Result()));
|
|
||||||
} else {
|
} else {
|
||||||
LOG.debug("Error: invalid Action, row must be a Get, Delete or Put.");
|
LOG.debug("Error: invalid Action, row must be a Get, Delete or Put.");
|
||||||
throw new IllegalArgumentException("Invalid Action, row must be a Get, Delete or Put.");
|
throw new IllegalArgumentException("Invalid Action, row must be a Get, Delete or Put.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We do the puts with result.put so we can get the batching efficiency
|
||||||
|
// we so need. All this data munging doesn't seem great, but at least
|
||||||
|
// we arent copying bytes or anything.
|
||||||
|
if (!puts.isEmpty()) {
|
||||||
|
HRegion region = getRegion(regionName);
|
||||||
|
if (!region.getRegionInfo().isMetaTable()) {
|
||||||
|
this.cacheFlusher.reclaimMemStoreMemory();
|
||||||
|
}
|
||||||
|
|
||||||
|
Pair<Put,Integer> [] putsWithLocks = new Pair[puts.size()];
|
||||||
|
int i = 0;
|
||||||
|
for (Action a : puts) {
|
||||||
|
Put p = (Put) a.getAction();
|
||||||
|
|
||||||
|
Integer lock = getLockFromId(p.getLockId());
|
||||||
|
putsWithLocks[i++] = new Pair<Put, Integer>(p, lock);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.requestCount.addAndGet(puts.size());
|
||||||
|
|
||||||
|
OperationStatusCode[] codes = region.put(putsWithLocks);
|
||||||
|
for( i = 0 ; i < codes.length ; i++) {
|
||||||
|
OperationStatusCode code = codes[i];
|
||||||
|
|
||||||
|
Action theAction = puts.get(i);
|
||||||
|
Result result = null;
|
||||||
|
|
||||||
|
if (code == OperationStatusCode.SUCCESS) {
|
||||||
|
result = new Result();
|
||||||
|
}
|
||||||
|
// TODO turning the alternate exception into a different result
|
||||||
|
|
||||||
|
response.add(regionName,
|
||||||
|
new Pair<Integer, Result>(
|
||||||
|
theAction.getOriginalIndex(), result));
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (IOException ioe) {
|
} catch (IOException ioe) {
|
||||||
if (multi.size() == 1) throw ioe;
|
if (multi.size() == 1) throw ioe;
|
||||||
LOG.debug("Exception processing " +
|
LOG.debug("Exception processing " +
|
||||||
|
|
|
@ -354,17 +354,11 @@ public class TestMultiParallel {
|
||||||
get.addColumn(BYTES_FAMILY, QUALIFIER);
|
get.addColumn(BYTES_FAMILY, QUALIFIER);
|
||||||
actions.add(get);
|
actions.add(get);
|
||||||
|
|
||||||
// 5 get of the put in #2 (entire family)
|
// There used to be a 'get' of a previous put here, but removed
|
||||||
get = new Get(KEYS[10]);
|
// since this API really cannot guarantee order in terms of mixed
|
||||||
get.addFamily(BYTES_FAMILY);
|
// get/puts.
|
||||||
actions.add(get);
|
|
||||||
|
|
||||||
// 6 get of the delete from #3
|
// 5 put of new column
|
||||||
get = new Get(KEYS[20]);
|
|
||||||
get.addColumn(BYTES_FAMILY, QUALIFIER);
|
|
||||||
actions.add(get);
|
|
||||||
|
|
||||||
// 7 put of new column
|
|
||||||
put = new Put(KEYS[40]);
|
put = new Put(KEYS[40]);
|
||||||
put.add(BYTES_FAMILY, qual2, val2);
|
put.add(BYTES_FAMILY, qual2, val2);
|
||||||
actions.add(put);
|
actions.add(put);
|
||||||
|
@ -378,10 +372,7 @@ public class TestMultiParallel {
|
||||||
validateEmpty(results[2]);
|
validateEmpty(results[2]);
|
||||||
validateEmpty(results[3]);
|
validateEmpty(results[3]);
|
||||||
validateResult(results[4]);
|
validateResult(results[4]);
|
||||||
validateResult(results[5]);
|
validateEmpty(results[5]);
|
||||||
validateResult(results[5], qual2, val2); // testing second column in #5
|
|
||||||
validateEmpty(results[6]); // deleted
|
|
||||||
validateEmpty(results[7]);
|
|
||||||
|
|
||||||
// validate last put, externally from the batch
|
// validate last put, externally from the batch
|
||||||
get = new Get(KEYS[40]);
|
get = new Get(KEYS[40]);
|
||||||
|
|
Loading…
Reference in New Issue