Package org.elasticsearch.cluster.routing

Examples of org.elasticsearch.cluster.routing.MutableShardRouting


    @Override
    public RerouteExplanation execute(RoutingAllocation allocation, boolean explain) throws ElasticsearchException {
        DiscoveryNode discoNode = allocation.nodes().resolveNode(node);

        MutableShardRouting shardRouting = null;
        for (MutableShardRouting routing : allocation.routingNodes().unassigned()) {
            if (routing.shardId().equals(shardId)) {
                // prefer primaries first to allocate
                if (shardRouting == null || routing.primary()) {
                    shardRouting = routing;
                }
            }
        }

        if (shardRouting == null) {
            if (explain) {
                return new RerouteExplanation(this, allocation.decision(Decision.NO, "allocate_allocation_command",
                        "failed to find " + shardId + " on the list of unassigned shards"));
            }
            throw new ElasticsearchIllegalArgumentException("[allocate] failed to find " + shardId + " on the list of unassigned shards");
        }

        if (shardRouting.primary() && !allowPrimary) {
            if (explain) {
                return new RerouteExplanation(this, allocation.decision(Decision.NO, "allocate_allocation_command",
                        "trying to allocate a primary shard " + shardId + ", which is disabled"));
            }
            throw new ElasticsearchIllegalArgumentException("[allocate] trying to allocate a primary shard " + shardId + ", which is disabled");
        }

        RoutingNode routingNode = allocation.routingNodes().node(discoNode.id());
        if (routingNode == null) {
            if (!discoNode.dataNode()) {
                if (explain) {
                    return new RerouteExplanation(this, allocation.decision(Decision.NO, "allocate_allocation_command",
                            "Allocation can only be done on data nodes, not [" + node + "]"));
                }
                throw new ElasticsearchIllegalArgumentException("Allocation can only be done on data nodes, not [" + node + "]");
            } else {
                if (explain) {
                    return new RerouteExplanation(this, allocation.decision(Decision.NO, "allocate_allocation_command",
                            "Could not find [" + node + "] among the routing nodes"));
                }
                throw new ElasticsearchIllegalStateException("Could not find [" + node + "] among the routing nodes");
            }
        }

        Decision decision = allocation.deciders().canAllocate(shardRouting, routingNode, allocation);
        if (decision.type() == Decision.Type.NO) {
            if (explain) {
                return new RerouteExplanation(this, decision);
            }
            throw new ElasticsearchIllegalArgumentException("[allocate] allocation of " + shardId + " on node " + discoNode + " is not allowed, reason: " + decision);
        }
        // go over and remove it from the unassigned
        for (Iterator<MutableShardRouting> it = allocation.routingNodes().unassigned().iterator(); it.hasNext(); ) {
            if (it.next() != shardRouting) {
                continue;
            }
            it.remove();
            allocation.routingNodes().assign(shardRouting, routingNode.nodeId());
            if (shardRouting.primary()) {
                // we need to clear the post allocation flag, since its an explicit allocation of the primary shard
                // and we want to force allocate it (and create a new index for it)
                allocation.routingNodes().addClearPostAllocationFlag(shardRouting.shardId());
            }
            break;
        }
        return new RerouteExplanation(this, decision);
    }
View Full Code Here


            }
            if (decision.type() == Decision.Type.THROTTLE) {
                // its being throttled, maybe have a flag to take it into account and fail? for now, just do it since the "user" wants it...
            }

            allocation.routingNodes().assign(new MutableShardRouting(shardRouting.index(), shardRouting.id(),
                    toRoutingNode.nodeId(), shardRouting.currentNodeId(), shardRouting.restoreSource(),
                    shardRouting.primary(), ShardRoutingState.INITIALIZING, shardRouting.version() + 1), toRoutingNode.nodeId());

            allocation.routingNodes().relocate(shardRouting, toRoutingNode.nodeId());
        }
View Full Code Here

                    }
                    RoutingNode target = routingNodes.node(currentNode.getNodeId());
                    Decision decision = allocation.deciders().canAllocate(shard, target, allocation);
                    if (decision.type() == Type.YES) { // TODO maybe we can respect throttling here too?
                        sourceNode.removeShard(shard);
                        final MutableShardRouting initializingShard = new MutableShardRouting(shard.index(), shard.id(), currentNode.getNodeId(),
                                shard.currentNodeId(), shard.restoreSource(), shard.primary(), INITIALIZING, shard.version() + 1);
                        currentNode.addShard(initializingShard, decision);
                        routingNodes.assign(initializingShard, target.nodeId());
                        routingNodes.relocate(shard, target.nodeId()); // set the node to relocate after we added the initializing shard
                        if (logger.isTraceEnabled()) {
View Full Code Here

            int primaryLength = primary.length;
            ArrayUtil.timSort(primary, comparator);
            final Set<ModelNode> throttledNodes = new IdentityHashSet<>();
            do {
                for (int i = 0; i < primaryLength; i++) {
                    MutableShardRouting shard = primary[i];
                    if (!shard.primary()) {
                        boolean drop = deciders.canAllocate(shard, allocation).type() == Type.NO;
                        if (drop) {
                            ignoredUnassigned.add(shard);
                            while(i < primaryLength-1 && comparator.compare(primary[i], primary[i+1]) == 0) {
                                ignoredUnassigned.add(primary[++i]);
                            }
                            continue;
                        } else {
                            while(i < primaryLength-1 && comparator.compare(primary[i], primary[i+1]) == 0) {
                                secondary[secondaryLength++] = primary[++i];
                            }
                        }
                    }
                    assert !shard.assignedToNode() : shard;
                    /* find an node with minimal weight we can allocate on*/
                    float minWeight = Float.POSITIVE_INFINITY;
                    ModelNode minNode = null;
                    Decision decision = null;
                    if (throttledNodes.size() < nodes.size()) {
                        /* Don't iterate over an identity hashset here the
                         * iteration order is different for each run and makes testing hard */
                        for (ModelNode node : nodes.values()) {
                            if (throttledNodes.contains(node)) {
                                continue;
                            }
                            /*
                             * The shard we add is removed below to simulate the
                             * addition for weight calculation we use Decision.ALWAYS to
                             * not violate the not null condition.
                             */
                            if (!node.containsShard(shard)) {
                                node.addShard(shard, Decision.ALWAYS);
                                float currentWeight = weight.weight(Operation.ALLOCATE, this, node, shard.index());
                                /*
                                 * Remove the shard from the node again this is only a
                                 * simulation
                                 */
                                Decision removed = node.removeShard(shard);
                                assert removed != null;
                                /*
                                 * Unless the operation is not providing any gains we
                                 * don't check deciders
                                 */
                                if (currentWeight <= minWeight) {
                                    Decision currentDecision = deciders.canAllocate(shard, routingNodes.node(node.getNodeId()), allocation);
                                    NOUPDATE:
                                    if (currentDecision.type() == Type.YES || currentDecision.type() == Type.THROTTLE) {
                                        if (currentWeight == minWeight) {
                                            /*  we have an equal weight tie breaking:
                                             *  1. if one decision is YES prefer it
                                             *  2. prefer the node that holds the primary for this index with the next id in the ring ie.
                                             *  for the 3 shards 2 replica case we try to build up:
                                             *    1 2 0
                                             *    2 0 1
                                             *    0 1 2
                                             *  such that if we need to tie-break we try to prefer the node holding a shard with the minimal id greater
                                             *  than the id of the shard we need to assign. This works find when new indices are created since
                                             *  primaries are added first and we only add one shard set a time in this algorithm.
                                             */
                                            if (currentDecision.type() == decision.type()) {
                                                final int repId = shard.id();
                                                final int nodeHigh = node.highestPrimary(shard.index());
                                                final int minNodeHigh = minNode.highestPrimary(shard.index());
                                                if ((((nodeHigh > repId && minNodeHigh > repId) || (nodeHigh < repId && minNodeHigh < repId)) && (nodeHigh < minNodeHigh))
                                                        || (nodeHigh > minNodeHigh && nodeHigh > repId && minNodeHigh < repId)) {
                                                    minNode = node;
                                                    minWeight = currentWeight;
                                                    decision = currentDecision;
                                                } else {
                                                    break NOUPDATE;
                                                }
                                            } else if (currentDecision.type() != Type.YES) {
                                                break NOUPDATE;
                                            }
                                        }
                                        minNode = node;
                                        minWeight = currentWeight;
                                        decision = currentDecision;
                                    }
                                }
                            }
                        }
                    }
                    assert decision != null && minNode != null || decision == null && minNode == null;
                    if (minNode != null) {
                        minNode.addShard(shard, decision);
                        if (decision.type() == Type.YES) {
                            if (logger.isTraceEnabled()) {
                                logger.trace("Assigned shard [{}] to [{}]", shard, minNode.getNodeId());
                            }
                            routingNodes.assign(shard, routingNodes.node(minNode.getNodeId()).nodeId());
                            changed = true;
                            continue; // don't add to ignoreUnassigned
                        } else {
                            final RoutingNode node = routingNodes.node(minNode.getNodeId());
                            if (deciders.canAllocate(node, allocation).type() != Type.YES) {
                                if (logger.isTraceEnabled()) {
                                    logger.trace("Can not allocate on node [{}] remove from round decisin [{}]", node, decision.type());
                                }
                                throttledNodes.add(minNode);
                            }
                        }
                        if (logger.isTraceEnabled()) {
                            logger.trace("No eligable node found to assign shard [{}] decision [{}]", shard, decision.type());
                        }
                    } else if (logger.isTraceEnabled()) {
                        logger.trace("No Node found to assign shard [{}]", shard);
                    }
                    ignoredUnassigned.add(shard);
                    if (!shard.primary()) { // we could not allocate it and we are a replica - check if we can ignore the other replicas
                        while(secondaryLength > 0 && comparator.compare(shard, secondary[secondaryLength-1]) == 0) {
                            ignoredUnassigned.add(secondary[--secondaryLength]);
                        }
                    }
                }
View Full Code Here

                if (logger.isTraceEnabled()) {
                    logger.trace("Try relocating shard for index index [{}] from node [{}] to node [{}]", idx, maxNode.getNodeId(),
                            minNode.getNodeId());
                }
                final RoutingNode node = routingNodes.node(minNode.getNodeId());
                MutableShardRouting candidate = null;
                final AllocationDeciders deciders = allocation.deciders();
                /* make a copy since we modify this list in the loop */
                final ArrayList<MutableShardRouting> shards = new ArrayList<>(index.getAllShards());
                for (MutableShardRouting shard : shards) {
                    if (shard.started()) {
                        // skip initializing, unassigned and relocating shards we can't relocate them anyway
                        Decision allocationDecision = deciders.canAllocate(shard, node, allocation);
                        Decision rebalanceDecision = deciders.canRebalance(shard, allocation);
                        if (((allocationDecision.type() == Type.YES) || (allocationDecision.type() == Type.THROTTLE))
                                && ((rebalanceDecision.type() == Type.YES) || (rebalanceDecision.type() == Type.THROTTLE))) {
                            Decision srcDecision;
                            if ((srcDecision = maxNode.removeShard(shard)) != null) {
                                minNode.addShard(shard, srcDecision);
                                final float delta = weight.weight(operation, this, minNode, idx) - weight.weight(operation, this, maxNode, idx);
                                if (delta < minCost ||
                                        (candidate != null && delta == minCost && candidate.id() > shard.id())) {
                                    /* this last line is a tie-breaker to make the shard allocation alg deterministic
                                     * otherwise we rely on the iteration order of the index.getAllShards() which is a set.*/
                                    minCost = delta;
                                    candidate = shard;
                                    decision = new Decision.Multi().add(allocationDecision).add(rebalanceDecision);
                                }
                                minNode.removeShard(shard);
                                maxNode.addShard(shard, srcDecision);
                            }
                        }
                    }
                }

                if (candidate != null) {
                 
                    /* allocate on the model even if not throttled */
                    maxNode.removeShard(candidate);
                    minNode.addShard(candidate, decision);
                    if (decision.type() == Type.YES) { /* only allocate on the cluster if we are not throttled */
                        if (logger.isTraceEnabled()) {
                            logger.trace("Relocate shard [{}] from node [{}] to node [{}]", candidate, maxNode.getNodeId(),
                                    minNode.getNodeId());
                        }
                        /* now allocate on the cluster - if we are started we need to relocate the shard */
                        if (candidate.started()) {
                            RoutingNode lowRoutingNode = routingNodes.node(minNode.getNodeId());
                            routingNodes.assign(new MutableShardRouting(candidate.index(), candidate.id(), lowRoutingNode.nodeId(), candidate
                                    .currentNodeId(), candidate.restoreSource(), candidate.primary(), INITIALIZING, candidate.version() + 1), lowRoutingNode.nodeId());
                            routingNodes.relocate(candidate, lowRoutingNode.nodeId());

                        } else {
                            assert candidate.unassigned();
                            routingNodes.assign(candidate, routingNodes.node(minNode.getNodeId()).nodeId());
                        }
                        return true;

                    }
View Full Code Here

        Iterator<MutableShardRouting> unassignedIterator = routingNodes.unassigned().iterator();
        int lastNode = 0;

        while (unassignedIterator.hasNext()) {
            MutableShardRouting shard = unassignedIterator.next();
            // do the allocation, finding the least "busy" node
            for (int i = 0; i < nodes.length; i++) {
                RoutingNode node = nodes[lastNode];
                lastNode++;
                if (lastNode == nodes.length) {
                    lastNode = 0;
                }

                Decision decision = allocation.deciders().canAllocate(shard, node, allocation);
                if (decision.type() == Decision.Type.YES) {
                    int numberOfShardsToAllocate = routingNodes.requiredAverageNumberOfShardsPerNode() - node.size();
                    if (numberOfShardsToAllocate <= 0) {
                        continue;
                    }

                    changed = true;
                    allocation.routingNodes().assign(shard, node.nodeId());
                    unassignedIterator.remove();
                    break;
                }
            }
        }

        // allocate all the unassigned shards above the average per node.
        for (Iterator<MutableShardRouting> it = routingNodes.unassigned().iterator(); it.hasNext(); ) {
            MutableShardRouting shard = it.next();
            // go over the nodes and try and allocate the remaining ones
            for (RoutingNode routingNode : sortedNodesLeastToHigh(allocation)) {
                Decision decision = allocation.deciders().canAllocate(shard, routingNode, allocation);
                if (decision.type() == Decision.Type.YES) {
                    changed = true;
View Full Code Here

                    }

                    Decision allocateDecision = allocation.deciders().canAllocate(startedShard, lowRoutingNode, allocation);
                    if (allocateDecision.type() == Decision.Type.YES) {
                        changed = true;
                        allocation.routingNodes().assign(new MutableShardRouting(startedShard.index(), startedShard.id(),
                                lowRoutingNode.nodeId(), startedShard.currentNodeId(), startedShard.restoreSource(),
                                startedShard.primary(), INITIALIZING, startedShard.version() + 1), lowRoutingNode.nodeId());

                        allocation.routingNodes().relocate(startedShard, lowRoutingNode.nodeId());
                        relocated = true;
View Full Code Here

            if (nodeToCheck.nodeId().equals(node.nodeId())) {
                continue;
            }
            Decision decision = allocation.deciders().canAllocate(shardRouting, nodeToCheck, allocation);
            if (decision.type() == Decision.Type.YES) {
                allocation.routingNodes().assign(new MutableShardRouting(shardRouting.index(), shardRouting.id(),
                        nodeToCheck.nodeId(), shardRouting.currentNodeId(), shardRouting.restoreSource(),
                        shardRouting.primary(), INITIALIZING, shardRouting.version() + 1), nodeToCheck.nodeId());

                allocation.routingNodes().relocate(shardRouting, nodeToCheck.nodeId());
                changed = true;
View Full Code Here

    public Decision canAllocate(ShardRouting shardRouting, RoutingAllocation allocation) {
        if (shardRouting.primary()) {
            return allocation.decision(Decision.YES, NAME, "shard is primary");
        }
        MutableShardRouting primary = allocation.routingNodes().activePrimary(shardRouting);
        if (primary == null) {
            return allocation.decision(Decision.NO, NAME, "primary shard is not yet active");
        }
        return allocation.decision(Decision.YES, NAME, "primary is already active");
    }
View Full Code Here

        if (sourceNodeId == null) { // we allocate - check primary
            if (shardRouting.primary()) {
                // we are the primary we can allocate wherever
                return allocation.decision(Decision.YES, NAME, "primary shard can be allocated anywhere");
            }
            final MutableShardRouting primary = allocation.routingNodes().activePrimary(shardRouting);
            if (primary == null) { // we have a primary - it's a start ;)
                return allocation.decision(Decision.YES, NAME, "no active primary shard yet");
            }
            sourceNodeId = primary.currentNodeId();
        }
        return isVersionCompatible(allocation.routingNodes(), sourceNodeId, node, allocation);

    }
View Full Code Here

TOP

Related Classes of org.elasticsearch.cluster.routing.MutableShardRouting

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.