/** * Parse a given cluster state string into a returned ClusterState instance, wrapping any * parse exceptions in a RuntimeException. */ public static ClusterState stateFromString(final String stateStr) { try { return new ClusterState(stateStr); } catch (Exception e) { throw new RuntimeException(e); } }
public void updateValidTargets(ClusterState state) { List<Integer> validRandomTargets = new ArrayList<>(); for (int i=0; i<state.getNodeCount(NodeType.DISTRIBUTOR); ++i) { if (state.getNodeState(new Node(NodeType.DISTRIBUTOR, i)).getState().oneOf(upStates)) validRandomTargets.add(i); } this.validRandomTargets = validRandomTargets; this.totalTargets = state.getNodeCount(NodeType.DISTRIBUTOR); } public abstract String getTargetSpec(Integer distributor, RoutingContext context);
private void updateCachedRoutingStateFromWrongDistribution(MessageContext context, ClusterState newState) { if (cachedClusterState == null || newState.getVersion() >= cachedClusterState.getVersion()) { cachedClusterState = newState; if (newState.getClusterState().equals(State.UP)) { hostFetcher.updateValidTargets(newState); } } else if (newState.getVersion() + 2000000000 < cachedClusterState.getVersion()) { cachedClusterState = null; } else if (context.calculatedDistributor != null) { persistentFailureChecker.addFailure(context.calculatedDistributor); } }
public int getIdealDistributorNode(ClusterState state, BucketId bucket, String upStates) throws TooFewBucketBitsInUseException, NoDistributorsAvailableException { if (bucket.getUsedBits() < state.getDistributionBitCount()) { throw new TooFewBucketBitsInUseException("Cannot get ideal state for bucket " + bucket + " using " + bucket.getUsedBits() + " bits when cluster uses " + state.getDistributionBitCount() + " distribution bits."); throw new NoDistributorsAvailableException("No distributors available in cluster state version " + state.getVersion()); ScoredNode node = new ScoredNode(0, 0, 0); for (ConfiguredNode configuredNode : configuredNodes) { NodeState nodeState = state.getNodeState(new Node(NodeType.DISTRIBUTOR, configuredNode.index())); if (!nodeState.getState().oneOf(upStates)) continue; if (configuredNode.index() != randomIndex) {
private void handleWrongDistributionReply(WrongDistributionReply reply) { try { ClusterState newState = new ClusterState(reply.getSystemState()); int stateBits = newState.getDistributionBitCount(); if (stateBits != progress.getIterator().getDistributionBitCount()) { log.log(LogLevel.DEBUG, "System state changed; now at " + stateBits + " distribution bits"); // Update the internal state of the visitor iterator. If we're increasing // the number of distribution bits, this may lead to splitting of pending // buckets. If we're decreasing, it may lead to merging of pending buckets // and potential loss of sub-bucket progress. In either way, the iterator // will not let any new buckets out before all active buckets have been // updated. progress.getIterator().setDistributionBitCount(stateBits); } } catch (Exception e) { log.log(LogLevel.ERROR, "Failed to parse new system state string: " + reply.getSystemState()); transitionTo(new StateDescription(State.FAILED, "Failed to parse cluster state '" + reply.getSystemState() + "'")); } }
if (bucket.getUsedBits() < clusterState.getDistributionBitCount()) { String msg = "Cannot get ideal state for bucket " + bucket + " using " + bucket.getUsedBits() + " bits when cluster uses " + clusterState.getDistributionBitCount() + " distribution bits."; throw new TooFewBucketBitsInUseException(msg); NodeState nodeState = clusterState.getNodeState(new Node(NodeType.STORAGE, configuredNode.index())); if (!nodeState.getState().oneOf(upStates)) { continue;
public String toString() { return "Context(Distributor " + calculatedDistributor + ", state version " + usedState.getVersion() + ")"; } }
@Override public boolean nodeUp() { return !clusterUp() && clusterState.getNodeState(new Node(NodeType.STORAGE, clusterIndex)).getState().oneOf("uir"); } }
if (context.shouldTrace(1)) { context.trace(1, "Using distributor " + messageContext.calculatedDistributor + " for " + bucketId + " as our state version is " + cachedClusterState.getVersion()); Reply reply = new WrongDistributionReply(cachedClusterState.toString(true)); reply.addError(new Error(DocumentProtocol.ERROR_WRONG_DISTRIBUTION, "Too few distribution bits used for given cluster state"));
private int getDistributorSeed(BucketId bucket, ClusterState state) { return ((int) bucket.getRawId()) & distributionBitMasks[state.getDistributionBitCount()]; }
/** Returns the serialized form of this cluster state */ // TODO: Don't rely on toString for that @Override public String toString() { return toString(false); }
@Override public boolean clusterUp() { return clusterState != null && clusterState.getClusterState().oneOf("u"); }
private boolean normalizedNodeStateSimilarToIgnoringInitProgress( final NodeType nodeType, final NodeState lhs, final NodeState rhs) { final NodeState lhsNormalized = (lhs != null ? lhs : defaultUpNodeState(nodeType)); final NodeState rhsNormalized = (rhs != null ? rhs : defaultUpNodeState(nodeType)); return lhsNormalized.similarToIgnoringInitProgress(rhsNormalized); }
public ClusterState(String serialized) throws ParseException { nodeCount.add(0); nodeCount.add(0); deserialize(serialized); }
private void resetCachedStateIfClusterStateVersionLikelyRolledBack(ClusterState newState) { if (cachedClusterState != null && cachedClusterState.getVersion() > newState.getVersion()) { if (++oldClusterVersionGottenCount >= maxOldClusterVersionBeforeSendingRandom) { oldClusterVersionGottenCount = 0; cachedClusterState = null; } } }
private static boolean allDistributorsDown(Group g, ClusterState clusterState) { if (g.isLeafGroup()) { for (ConfiguredNode node : g.getNodes()) { NodeState ns = clusterState.getNodeState(new Node(NodeType.DISTRIBUTOR, node.index())); if (ns.getState().oneOf("ui")) return false; } } else { for (Group childGroup : g.getSubgroups().values()) { if (!allDistributorsDown(childGroup, clusterState)) return false; } } return true; } private Group getIdealDistributorGroup(BucketId bucket, ClusterState clusterState, Group parent, int redundancy) {
private int getGroupSeed(BucketId bucket, ClusterState state, Group group) { int seed = ((int) bucket.getRawId()) & distributionBitMasks[state.getDistributionBitCount()]; seed ^= group.getDistributionHash(); return seed; }
private boolean normalizedNodeStateSimilarTo(final NodeType nodeType, final NodeState lhs, final NodeState rhs) { final NodeState lhsNormalized = (lhs != null ? lhs : defaultUpNodeState(nodeType)); final NodeState rhsNormalized = (rhs != null ? rhs : defaultUpNodeState(nodeType)); return lhsNormalized.similarTo(rhsNormalized); }
int distributorNodeCount = getNodeCount(NodeType.DISTRIBUTOR); int storageNodeCount = getNodeCount(NodeType.STORAGE); while (distributorNodeCount > 0 && getNodeState(new Node(NodeType.DISTRIBUTOR, distributorNodeCount - 1)).getState().equals(State.DOWN)) --distributorNodeCount; while (storageNodeCount > 0 && getNodeState(new Node(NodeType.STORAGE, storageNodeCount - 1)).getState().equals(State.DOWN)) --storageNodeCount;
public ClusterStateImpl(byte[] serialized) throws ParseException { ByteBuffer buf = ByteBuffer.wrap(serialized); int clusterStateLength = buf.getInt(); byte[] clusterState = new byte[clusterStateLength]; buf.get(clusterState); clusterIndex = buf.getShort(); int distributionLength = buf.getInt(); byte[] distribution = new byte[distributionLength]; buf.get(distribution); this.clusterState = new com.yahoo.vdslib.state.ClusterState(new String(clusterState)); this.distribution = new Distribution("raw:" + new String(distribution)); }