You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by jx...@apache.org on 2012/10/16 20:46:55 UTC
svn commit: r1398920 -
/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java
Author: jxiang
Date: Tue Oct 16 18:46:54 2012
New Revision: 1398920
URL: http://svn.apache.org/viewvc?rev=1398920&view=rev
Log:
HBASE-6858 Fix the incorrect BADVERSION checking in the recoverable zookeeper
Modified:
hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java
Modified: hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java
URL: http://svn.apache.org/viewvc/hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java?rev=1398920&r1=1398919&r2=1398920&view=diff
==============================================================================
--- hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java (original)
+++ hbase/trunk/hbase-server/src/main/java/org/apache/hadoop/hbase/zookeeper/RecoverableZooKeeper.java Tue Oct 16 18:46:54 2012
@@ -20,8 +20,10 @@ package org.apache.hadoop.hbase.zookeepe
import java.io.IOException;
import java.lang.management.ManagementFactory;
+import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
+import java.util.Random;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -75,6 +77,7 @@ public class RecoverableZooKeeper {
private Watcher watcher;
private int sessionTimeout;
private String quorumServers;
+ private final Random salter;
// The metadata attached to each piece of data has the
// format:
@@ -104,6 +107,7 @@ public class RecoverableZooKeeper {
this.watcher = watcher;
this.sessionTimeout = sessionTimeout;
this.quorumServers = quorumServers;
+ salter = new SecureRandom();
}
public void reconnectAfterExpiration()
@@ -341,6 +345,7 @@ public class RecoverableZooKeeper {
throws KeeperException, InterruptedException {
RetryCounter retryCounter = retryCounterFactory.create();
byte[] newData = appendMetaData(data);
+ boolean isRetry = false;
while (true) {
try {
return zk.setData(path, newData, version);
@@ -352,24 +357,20 @@ public class RecoverableZooKeeper {
retryOrThrow(retryCounter, e, "setData");
break;
case BADVERSION:
- // try to verify whether the previous setData success or not
- try{
- Stat stat = new Stat();
- byte[] revData = zk.getData(path, false, stat);
- int idLength = Bytes.toInt(revData, ID_LENGTH_SIZE);
- int dataLength = revData.length-ID_LENGTH_SIZE-idLength;
- int dataOffset = ID_LENGTH_SIZE+idLength;
-
- if(Bytes.compareTo(revData, ID_LENGTH_SIZE, id.length,
- revData, dataOffset, dataLength) == 0) {
- // the bad version is caused by previous successful setData
- return stat;
+ if (isRetry) {
+ // try to verify whether the previous setData success or not
+ try{
+ Stat stat = new Stat();
+ byte[] revData = zk.getData(path, false, stat);
+ if(Bytes.compareTo(revData, newData) == 0) {
+ // the bad version is caused by previous successful setData
+ return stat;
+ }
+ } catch(KeeperException keeperException){
+ // the ZK is not reliable at this moment. just throwing exception
+ throw keeperException;
}
- } catch(KeeperException keeperException){
- // the ZK is not reliable at this moment. just throwing exception
- throw keeperException;
- }
-
+ }
// throw other exceptions and verified bad version exceptions
default:
throw e;
@@ -377,6 +378,7 @@ public class RecoverableZooKeeper {
}
retryCounter.sleepUntilNextRetry();
retryCounter.useRetry();
+ isRetry = true;
}
}
@@ -521,30 +523,29 @@ public class RecoverableZooKeeper {
if(magic != MAGIC) {
return data;
}
-
+
int idLength = Bytes.toInt(data, ID_LENGTH_OFFSET);
int dataLength = data.length-MAGIC_SIZE-ID_LENGTH_SIZE-idLength;
int dataOffset = MAGIC_SIZE+ID_LENGTH_SIZE+idLength;
byte[] newData = new byte[dataLength];
System.arraycopy(data, dataOffset, newData, 0, dataLength);
-
return newData;
-
}
-
+
private byte[] appendMetaData(byte[] data) {
if(data == null || data.length == 0){
return data;
}
-
- byte[] newData = new byte[MAGIC_SIZE+ID_LENGTH_SIZE+id.length+data.length];
+ byte[] salt = Bytes.toBytes(salter.nextLong());
+ int idLength = id.length + salt.length;
+ byte[] newData = new byte[MAGIC_SIZE+ID_LENGTH_SIZE+idLength+data.length];
int pos = 0;
pos = Bytes.putByte(newData, pos, MAGIC);
- pos = Bytes.putInt(newData, pos, id.length);
+ pos = Bytes.putInt(newData, pos, idLength);
pos = Bytes.putBytes(newData, pos, id, 0, id.length);
+ pos = Bytes.putBytes(newData, pos, salt, 0, salt.length);
pos = Bytes.putBytes(newData, pos, data, 0, data.length);
-
return newData;
}