use of voldemort.VoldemortException in project voldemort by voldemort.
the class RedirectingStore method getProxyNode.
/**
* Checks if the server has to do any proxying of gets/puts to another
* server, as a part of an ongoing rebalance operation.
*
* Basic idea : Any given node which is a stealer of a partition, as the ith
* replica of a given zone, will proxy to the old ith replica of the
* partition in the given zone, as per the source cluster metadata.
* Exception : if this amounts to proxying to itself.
*
* Note on Zone Expansion : For zone expansion, there will be no proxying
* within the new zone. This is a practical assumption since if we fail, we
* fallback to a cluster topology without the new zone. As a result, reads
* from the new zone are not guaranteed to return some values during the
* course of zone expansion. This is a also reasonable since any
* organization undertaking such effort would need to have the data in place
* in the new zone, before the client apps are moved over.
*
* TODO:refactor Add helper methods to StoreRoutingPlan to simplify this
* code
*
* @param currentRoutingPlan routing plan object based on cluster's current
* topology
* @param storeDef definition of the store being redirected
* @param key to decide where to proxy to
* @return Null if no proxying is required else node id of the server to
* proxy to
*/
private Integer getProxyNode(BaseStoreRoutingPlan currentRoutingPlan, StoreDefinition storeDef, byte[] key) {
// get out if redirecting is disabled.
if (!isRedirectingStoreEnabled.get()) {
return null;
}
// TODO a better design would be to get these state changes from
// metadata listener callbacks, so we need not allocate these objects
// all the time. This has been implemented, but not integration tested,
// on the following branch:
// https://github.com/voldemort/voldemort/compare/proxy-put-metadata-listener
Cluster sourceCluster = metadata.getRebalancingSourceCluster();
// Logic to get the old storedef
List<StoreDefinition> sourceStoreDefs = metadata.getRebalancingSourceStores();
if (sourceCluster == null) {
if (logger.isTraceEnabled()) {
logger.trace("Old Cluster is null.. bail");
}
return null;
}
if (sourceStoreDefs == null) {
if (logger.isTraceEnabled()) {
logger.trace("Old stores def is null.. bail");
}
return null;
}
StoreDefinition sourceStoreDef = null;
sourceStoreDef = StoreUtils.getStoreDef(sourceStoreDefs, storeDef.getName());
Integer nodeId = metadata.getNodeId();
Integer zoneId = currentRoutingPlan.getCluster().getNodeById(nodeId).getZoneId();
// Use the old store definition to get the routing object
BaseStoreRoutingPlan oldRoutingPlan = new BaseStoreRoutingPlan(sourceCluster, sourceStoreDef);
// Check the current node's relationship to the key.
int zoneNAry = currentRoutingPlan.getZoneNAry(zoneId, nodeId, key);
// Determine which node held the key with the same relationship in the
// old cluster. That is your man!
Integer redirectNodeId;
try {
redirectNodeId = oldRoutingPlan.getNodeIdForZoneNary(zoneId, zoneNAry, key);
} catch (VoldemortException ve) {
/*
* If the zone does not exist, as in the case of Zone Expansion,
* there will be no proxy bridges built. The only other time an
* exception can be thrown here is when the replicaType is invalid.
* But that would mean we are changing say a 2/1/1 store to 3/2/2,
* which Voldemort currently does not support anyway
*/
return null;
}
// Unless he is the same as this node (where this is meaningless effort)
if (redirectNodeId == nodeId) {
return null;
}
return redirectNodeId;
}
use of voldemort.VoldemortException in project voldemort by voldemort.
the class MetadataStore method convertObjectToString.
/**
* Converts Object to byte[] depending on the key
* <p>
* StoreRepository takes only StorageEngine<ByteArray,byte[]> and for
* persistence on disk we need to convert them to String.<br>
*
* @param key
* @param value
* @return
*/
@SuppressWarnings("unchecked")
private Versioned<String> convertObjectToString(String key, Versioned<Object> value) {
String valueStr = "";
if (CLUSTER_KEY.equals(key)) {
valueStr = clusterMapper.writeCluster((Cluster) value.getValue());
} else if (STORES_KEY.equals(key)) {
valueStr = storeMapper.writeStoreList((List<StoreDefinition>) value.getValue());
} else if (REBALANCING_STEAL_INFO.equals(key)) {
RebalancerState rebalancerState = (RebalancerState) value.getValue();
valueStr = rebalancerState.toJsonString();
} else if (SERVER_STATE_KEY.equals(key) || NODE_ID_KEY.equals(key) || SLOP_STREAMING_ENABLED_KEY.equals(key) || PARTITION_STREAMING_ENABLED_KEY.equals(key) || READONLY_FETCH_ENABLED_KEY.equals(key) || QUOTA_ENFORCEMENT_ENABLED_KEY.equals(key)) {
valueStr = value.getValue().toString();
} else if (REBALANCING_SOURCE_CLUSTER_XML.equals(key)) {
if (value.getValue() != null) {
valueStr = clusterMapper.writeCluster((Cluster) value.getValue());
}
} else if (REBALANCING_SOURCE_STORES_XML.equals(key)) {
if (value.getValue() != null) {
valueStr = storeMapper.writeStoreList((List<StoreDefinition>) value.getValue());
}
} else if (this.storeNames.contains(key)) {
valueStr = "<stores>";
if (value.getValue() != null) {
valueStr += value.getValue();
}
valueStr += "</stores>";
} else {
throw new VoldemortException("Unhandled key:'" + key + "' for Object to String serialization.");
}
return new Versioned<String>(valueStr, value.getVersion());
}
use of voldemort.VoldemortException in project voldemort by voldemort.
the class MetadataStore method updateStoreDefinitions.
/**
* Function to update store definitions. Unlike the put method, this
* function does not delete any existing state. It only updates the state of
* the stores specified in the given stores.xml
*
* @param valueBytes specifies the bytes of the stores.xml containing
* updates for the specified stores
*/
@SuppressWarnings("unchecked")
public void updateStoreDefinitions(Versioned<byte[]> valueBytes) {
// acquire write lock
writeLock.lock();
try {
Versioned<String> value = new Versioned<String>(ByteUtils.getString(valueBytes.getValue(), "UTF-8"), valueBytes.getVersion());
Versioned<Object> valueObject = convertStringToObject(STORES_KEY, value);
StoreDefinitionsMapper mapper = new StoreDefinitionsMapper();
List<StoreDefinition> storeDefinitions = (List<StoreDefinition>) valueObject.getValue();
// Check for backwards compatibility
StoreDefinitionUtils.validateSchemasAsNeeded(storeDefinitions);
StoreDefinitionUtils.validateNewStoreDefsAreNonBreaking(getStoreDefList(), storeDefinitions);
// Go through each store definition and do a corresponding put
for (StoreDefinition storeDef : storeDefinitions) {
if (!this.storeNames.contains(storeDef.getName())) {
throw new VoldemortException("Cannot update a store which does not exist !");
}
String storeDefStr = mapper.writeStore(storeDef);
Versioned<String> versionedValueStr = new Versioned<String>(storeDefStr, value.getVersion());
this.storeDefinitionsStorageEngine.put(storeDef.getName(), versionedValueStr, "");
// Update the metadata cache
this.metadataCache.put(storeDef.getName(), new Versioned<Object>(storeDefStr, value.getVersion()));
}
// Re-initialize the store definitions
initStoreDefinitions(value.getVersion());
// Update routing strategies
// TODO: Make this more fine grained.. i.e only update listeners for
// a specific store.
updateRoutingStrategies(getCluster(), getStoreDefList());
} finally {
writeLock.unlock();
}
}
use of voldemort.VoldemortException in project voldemort by voldemort.
the class MetadataStore method addRebalancingState.
/**
* Add the steal information to the rebalancer state
*
* @param stealInfo The steal information to add
*/
public void addRebalancingState(final RebalanceTaskInfo stealInfo) {
// acquire write lock
writeLock.lock();
try {
// Move into rebalancing state
if (ByteUtils.getString(get(SERVER_STATE_KEY, null).get(0).getValue(), "UTF-8").compareTo(VoldemortState.NORMAL_SERVER.toString()) == 0) {
put(SERVER_STATE_KEY, VoldemortState.REBALANCING_MASTER_SERVER);
initCache(SERVER_STATE_KEY);
}
// Add the steal information
RebalancerState rebalancerState = getRebalancerState();
if (!rebalancerState.update(stealInfo)) {
throw new VoldemortException("Could not add steal information " + stealInfo + " since a plan for the same donor node " + stealInfo.getDonorId() + " ( " + rebalancerState.find(stealInfo.getDonorId()) + " ) already exists");
}
put(MetadataStore.REBALANCING_STEAL_INFO, rebalancerState);
initCache(REBALANCING_STEAL_INFO);
} finally {
writeLock.unlock();
}
}
use of voldemort.VoldemortException in project voldemort by voldemort.
the class MetadataStore method setOfflineState.
/**
* change server state between OFFLINE_SERVER and NORMAL_SERVER
*
* @param setToOffline True if set to OFFLINE_SERVER
*/
public void setOfflineState(boolean setToOffline) {
// acquire write lock
writeLock.lock();
try {
String currentState = ByteUtils.getString(get(SERVER_STATE_KEY, null).get(0).getValue(), "UTF-8");
if (setToOffline) {
// from NORMAL_SERVER to OFFLINE_SERVER
if (currentState.equals(VoldemortState.NORMAL_SERVER.toString())) {
put(SERVER_STATE_KEY, VoldemortState.OFFLINE_SERVER);
initCache(SERVER_STATE_KEY);
put(SLOP_STREAMING_ENABLED_KEY, false);
initCache(SLOP_STREAMING_ENABLED_KEY);
put(PARTITION_STREAMING_ENABLED_KEY, false);
initCache(PARTITION_STREAMING_ENABLED_KEY);
put(READONLY_FETCH_ENABLED_KEY, false);
initCache(READONLY_FETCH_ENABLED_KEY);
} else if (currentState.equals(VoldemortState.OFFLINE_SERVER.toString())) {
logger.warn("Already in OFFLINE_SERVER state.");
return;
} else {
logger.error("Cannot enter OFFLINE_SERVER state from " + currentState);
throw new VoldemortException("Cannot enter OFFLINE_SERVER state from " + currentState);
}
} else {
// from OFFLINE_SERVER to NORMAL_SERVER
if (currentState.equals(VoldemortState.NORMAL_SERVER.toString())) {
logger.warn("Already in NORMAL_SERVER state.");
return;
} else if (currentState.equals(VoldemortState.OFFLINE_SERVER.toString())) {
put(SERVER_STATE_KEY, VoldemortState.NORMAL_SERVER);
initCache(SERVER_STATE_KEY);
put(SLOP_STREAMING_ENABLED_KEY, true);
initCache(SLOP_STREAMING_ENABLED_KEY);
put(PARTITION_STREAMING_ENABLED_KEY, true);
initCache(PARTITION_STREAMING_ENABLED_KEY);
put(READONLY_FETCH_ENABLED_KEY, true);
initCache(READONLY_FETCH_ENABLED_KEY);
init();
initNodeId(getNodeIdNoLock());
} else {
logger.error("Cannot enter NORMAL_SERVER state from " + currentState);
throw new VoldemortException("Cannot enter NORMAL_SERVER state from " + currentState);
}
}
} finally {
writeLock.unlock();
}
}
Aggregations