Search in sources :

Example 6 with GridDhtPartitionMap

use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap in project ignite by apache.

the class GridDhtPartitionTopologyImpl method update.

/**
 * {@inheritDoc}
 */
@SuppressWarnings({ "MismatchedQueryAndUpdateOfCollection" })
@Override
public boolean update(@Nullable AffinityTopologyVersion exchangeVer, GridDhtPartitionFullMap partMap, @Nullable CachePartitionFullCountersMap incomeCntrMap, Set<Integer> partsToReload, @Nullable AffinityTopologyVersion msgTopVer) {
    if (log.isDebugEnabled()) {
        log.debug("Updating full partition map [grp=" + grp.cacheOrGroupName() + ", exchVer=" + exchangeVer + ", fullMap=" + fullMapString() + ']');
    }
    assert partMap != null;
    ctx.database().checkpointReadLock();
    try {
        lock.writeLock().lock();
        try {
            if (stopping || !lastTopChangeVer.initialized() || // Ignore message not-related to exchange if exchange is in progress.
            (exchangeVer == null && !lastTopChangeVer.equals(readyTopVer)))
                return false;
            if (incomeCntrMap != null) {
                // update local counters in partitions
                for (int i = 0; i < locParts.length(); i++) {
                    GridDhtLocalPartition part = locParts.get(i);
                    if (part == null)
                        continue;
                    if (part.state() == OWNING || part.state() == MOVING) {
                        long updCntr = incomeCntrMap.updateCounter(part.id());
                        if (updCntr != 0 && updCntr > part.updateCounter())
                            part.updateCounter(updCntr);
                    }
                }
            }
            if (exchangeVer != null) {
                // Ignore if exchange already finished or new exchange started.
                if (readyTopVer.compareTo(exchangeVer) > 0 || lastTopChangeVer.compareTo(exchangeVer) > 0) {
                    U.warn(log, "Stale exchange id for full partition map update (will ignore) [" + "grp=" + grp.cacheOrGroupName() + ", lastTopChange=" + lastTopChangeVer + ", readTopVer=" + readyTopVer + ", exchVer=" + exchangeVer + ']');
                    return false;
                }
            }
            if (msgTopVer != null && lastTopChangeVer.compareTo(msgTopVer) > 0) {
                U.warn(log, "Stale version for full partition map update message (will ignore) [" + "grp=" + grp.cacheOrGroupName() + ", lastTopChange=" + lastTopChangeVer + ", readTopVer=" + readyTopVer + ", msgVer=" + msgTopVer + ']');
                return false;
            }
            boolean fullMapUpdated = (node2part == null);
            if (node2part != null) {
                for (GridDhtPartitionMap part : node2part.values()) {
                    GridDhtPartitionMap newPart = partMap.get(part.nodeId());
                    if (shouldOverridePartitionMap(part, newPart)) {
                        fullMapUpdated = true;
                        if (log.isDebugEnabled()) {
                            log.debug("Overriding partition map in full update map [" + "grp=" + grp.cacheOrGroupName() + ", exchVer=" + exchangeVer + ", curPart=" + mapString(part) + ", newPart=" + mapString(newPart) + ']');
                        }
                        if (newPart.nodeId().equals(ctx.localNodeId()))
                            updateSeq.setIfGreater(newPart.updateSequence());
                    } else {
                        // If for some nodes current partition has a newer map,
                        // then we keep the newer value.
                        partMap.put(part.nodeId(), part);
                    }
                }
                // Check that we have new nodes.
                for (GridDhtPartitionMap part : partMap.values()) {
                    if (fullMapUpdated)
                        break;
                    fullMapUpdated = !node2part.containsKey(part.nodeId());
                }
                // Remove entry if node left.
                for (Iterator<UUID> it = partMap.keySet().iterator(); it.hasNext(); ) {
                    UUID nodeId = it.next();
                    if (!ctx.discovery().alive(nodeId)) {
                        if (log.isDebugEnabled())
                            log.debug("Removing left node from full map update [grp=" + grp.cacheOrGroupName() + ", nodeId=" + nodeId + ", partMap=" + partMap + ']');
                        it.remove();
                    }
                }
            } else {
                GridDhtPartitionMap locNodeMap = partMap.get(ctx.localNodeId());
                if (locNodeMap != null)
                    updateSeq.setIfGreater(locNodeMap.updateSequence());
            }
            if (!fullMapUpdated) {
                if (log.isDebugEnabled()) {
                    log.debug("No updates for full partition map (will ignore) [" + "grp=" + grp.cacheOrGroupName() + ", lastExch=" + lastTopChangeVer + ", exchVer=" + exchangeVer + ", curMap=" + node2part + ", newMap=" + partMap + ']');
                }
                return false;
            }
            if (exchangeVer != null) {
                assert exchangeVer.compareTo(readyTopVer) >= 0 && exchangeVer.compareTo(lastTopChangeVer) >= 0;
                lastTopChangeVer = readyTopVer = exchangeVer;
            }
            node2part = partMap;
            if (exchangeVer == null && !grp.isReplicated() && (readyTopVer.initialized() && readyTopVer.compareTo(diffFromAffinityVer) >= 0)) {
                AffinityAssignment affAssignment = grp.affinity().readyAffinity(readyTopVer);
                for (Map.Entry<UUID, GridDhtPartitionMap> e : partMap.entrySet()) {
                    for (Map.Entry<Integer, GridDhtPartitionState> e0 : e.getValue().entrySet()) {
                        int p = e0.getKey();
                        Set<UUID> diffIds = diffFromAffinity.get(p);
                        if ((e0.getValue() == MOVING || e0.getValue() == OWNING || e0.getValue() == RENTING) && !affAssignment.getIds(p).contains(e.getKey())) {
                            if (diffIds == null)
                                diffFromAffinity.put(p, diffIds = U.newHashSet(3));
                            diffIds.add(e.getKey());
                        } else {
                            if (diffIds != null && diffIds.remove(e.getKey())) {
                                if (diffIds.isEmpty())
                                    diffFromAffinity.remove(p);
                            }
                        }
                    }
                }
                diffFromAffinityVer = readyTopVer;
            }
            boolean changed = false;
            GridDhtPartitionMap nodeMap = partMap.get(ctx.localNodeId());
            if (nodeMap != null && grp.persistenceEnabled() && readyTopVer.initialized()) {
                for (Map.Entry<Integer, GridDhtPartitionState> e : nodeMap.entrySet()) {
                    int p = e.getKey();
                    GridDhtPartitionState state = e.getValue();
                    if (state == OWNING) {
                        GridDhtLocalPartition locPart = locParts.get(p);
                        assert locPart != null : grp.cacheOrGroupName();
                        if (locPart.state() == MOVING) {
                            boolean success = locPart.own();
                            assert success : locPart;
                            changed |= success;
                        }
                    } else if (state == MOVING) {
                        GridDhtLocalPartition locPart = locParts.get(p);
                        if (!partsToReload.contains(p)) {
                            if (locPart == null || locPart.state() == EVICTED)
                                locPart = createPartition(p);
                            if (locPart.state() == OWNING) {
                                locPart.moving();
                                changed = true;
                            }
                        } else {
                            if (locPart == null || locPart.state() == EVICTED) {
                                createPartition(p);
                                changed = true;
                            } else if (locPart.state() == OWNING || locPart.state() == MOVING) {
                                if (locPart.state() == OWNING)
                                    locPart.moving();
                                locPart.clearAsync();
                                changed = true;
                            } else if (locPart.state() == RENTING) {
                                // Try to prevent partition eviction.
                                if (locPart.reserve()) {
                                    try {
                                        locPart.moving();
                                        locPart.clearAsync();
                                    } finally {
                                        locPart.release();
                                    }
                                } else // In other case just recreate it.
                                {
                                    assert locPart.state() == EVICTED;
                                    createPartition(p);
                                }
                                changed = true;
                            }
                        }
                    }
                }
            }
            long updateSeq = this.updateSeq.incrementAndGet();
            if (readyTopVer.initialized() && readyTopVer.equals(lastTopChangeVer)) {
                AffinityAssignment aff = grp.affinity().readyAffinity(readyTopVer);
                if (exchangeVer == null)
                    changed |= checkEvictions(updateSeq, aff);
                updateRebalanceVersion(aff.assignment());
            }
            consistencyCheck();
            if (log.isDebugEnabled()) {
                log.debug("Partition map after full update [grp=" + grp.cacheOrGroupName() + ", map=" + fullMapString() + ']');
            }
            if (changed)
                ctx.exchange().scheduleResendPartitions();
            return changed;
        } finally {
            lock.writeLock().unlock();
        }
    } finally {
        ctx.database().checkpointReadUnlock();
    }
}
Also used : AffinityAssignment(org.apache.ignite.internal.processors.affinity.AffinityAssignment) GridDhtPartitionMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) UUID(java.util.UUID) GridPartitionStateMap(org.apache.ignite.internal.util.GridPartitionStateMap) CachePartitionFullCountersMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionFullCountersMap) Map(java.util.Map) HashMap(java.util.HashMap) GridDhtPartitionFullMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap) CachePartitionPartialCountersMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionPartialCountersMap) GridDhtPartitionMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap)

Example 7 with GridDhtPartitionMap

use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap in project ignite by apache.

the class GridDhtPartitionTopologyImpl method rebuildDiff.

/**
 * Rebuilds {@link #diffFromAffinity} from given assignment.
 *
 * @param affAssignment New affinity assignment.
 */
private void rebuildDiff(AffinityAssignment affAssignment) {
    assert lock.isWriteLockedByCurrentThread();
    if (node2part == null)
        return;
    if (FAST_DIFF_REBUILD) {
        Collection<UUID> affNodes = F.nodeIds(ctx.discovery().cacheGroupAffinityNodes(grp.groupId(), affAssignment.topologyVersion()));
        for (Map.Entry<Integer, Set<UUID>> e : diffFromAffinity.entrySet()) {
            int p = e.getKey();
            Iterator<UUID> iter = e.getValue().iterator();
            while (iter.hasNext()) {
                UUID nodeId = iter.next();
                if (!affNodes.contains(nodeId) || affAssignment.getIds(p).contains(nodeId))
                    iter.remove();
            }
        }
    } else {
        for (Map.Entry<UUID, GridDhtPartitionMap> e : node2part.entrySet()) {
            UUID nodeId = e.getKey();
            for (Map.Entry<Integer, GridDhtPartitionState> e0 : e.getValue().entrySet()) {
                Integer p0 = e0.getKey();
                GridDhtPartitionState state = e0.getValue();
                Set<UUID> ids = diffFromAffinity.get(p0);
                if ((state == MOVING || state == OWNING || state == RENTING) && !affAssignment.getIds(p0).contains(nodeId)) {
                    if (ids == null)
                        diffFromAffinity.put(p0, ids = U.newHashSet(3));
                    ids.add(nodeId);
                } else {
                    if (ids != null)
                        ids.remove(nodeId);
                }
            }
        }
    }
    diffFromAffinityVer = affAssignment.topologyVersion();
}
Also used : Set(java.util.Set) HashSet(java.util.HashSet) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) GridDhtPartitionMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap) UUID(java.util.UUID) GridPartitionStateMap(org.apache.ignite.internal.util.GridPartitionStateMap) CachePartitionFullCountersMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionFullCountersMap) Map(java.util.Map) HashMap(java.util.HashMap) GridDhtPartitionFullMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap) CachePartitionPartialCountersMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionPartialCountersMap) GridDhtPartitionMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap)

Example 8 with GridDhtPartitionMap

use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap in project ignite by apache.

the class GridDhtPartitionTopologyImpl method localPartitionMap.

/**
 * {@inheritDoc}
 */
@Override
public GridDhtPartitionMap localPartitionMap() {
    GridPartitionStateMap map = new GridPartitionStateMap(locParts.length());
    lock.readLock().lock();
    try {
        for (int i = 0; i < locParts.length(); i++) {
            GridDhtLocalPartition part = locParts.get(i);
            if (part == null)
                continue;
            map.put(i, part.state());
        }
        GridDhtPartitionMap locPartMap = node2part != null ? node2part.get(ctx.localNodeId()) : null;
        return new GridDhtPartitionMap(ctx.localNodeId(), updateSeq.get(), locPartMap != null ? locPartMap.topologyVersion() : readyTopVer, map, true);
    } finally {
        lock.readLock().unlock();
    }
}
Also used : GridDhtPartitionMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap) GridPartitionStateMap(org.apache.ignite.internal.util.GridPartitionStateMap)

Example 9 with GridDhtPartitionMap

use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap in project ignite by apache.

the class GridClientPartitionTopology method updateLocal.

/**
 * Updates value for single partition.
 *
 * @param p Partition.
 * @param nodeId Node ID.
 * @param state State.
 * @param updateSeq Update sequence.
 */
private void updateLocal(int p, UUID nodeId, GridDhtPartitionState state, long updateSeq) {
    assert lock.isWriteLockedByCurrentThread();
    assert nodeId.equals(cctx.localNodeId());
    // In case if node joins, get topology at the time of joining node.
    ClusterNode oldest = discoCache.oldestAliveServerNode();
    // If this node became the oldest node.
    if (cctx.localNode().equals(oldest)) {
        long seq = node2part.updateSequence();
        if (seq != updateSeq) {
            if (seq > updateSeq) {
                if (this.updateSeq.get() < seq) {
                    // Update global counter if necessary.
                    boolean b = this.updateSeq.compareAndSet(this.updateSeq.get(), seq + 1);
                    assert b : "Invalid update sequence [updateSeq=" + updateSeq + ", seq=" + seq + ", curUpdateSeq=" + this.updateSeq.get() + ", node2part=" + node2part.toFullString() + ']';
                    updateSeq = seq + 1;
                } else
                    updateSeq = seq;
            }
            node2part.updateSequence(updateSeq);
        }
    }
    GridDhtPartitionMap map = node2part.get(nodeId);
    if (map == null)
        node2part.put(nodeId, map = new GridDhtPartitionMap(nodeId, updateSeq, topVer, GridPartitionStateMap.EMPTY, false));
    map.updateSequence(updateSeq, topVer);
    map.put(p, state);
    Set<UUID> ids = part2node.get(p);
    if (ids == null)
        part2node.put(p, ids = U.newHashSet(3));
    ids.add(nodeId);
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) GridDhtPartitionMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap) UUID(java.util.UUID)

Example 10 with GridDhtPartitionMap

use of org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap in project ignite by apache.

the class GridClientPartitionTopology method setOwners.

/**
 * {@inheritDoc}
 */
@Override
public Set<UUID> setOwners(int p, Set<UUID> owners, boolean haveHistory, boolean updateSeq) {
    Set<UUID> result = haveHistory ? Collections.<UUID>emptySet() : new HashSet<UUID>();
    lock.writeLock().lock();
    try {
        for (Map.Entry<UUID, GridDhtPartitionMap> e : node2part.entrySet()) {
            GridDhtPartitionMap partMap = e.getValue();
            UUID remoteNodeId = e.getKey();
            if (!partMap.containsKey(p))
                continue;
            if (partMap.get(p) == OWNING && !owners.contains(remoteNodeId)) {
                partMap.put(p, MOVING);
                if (!haveHistory)
                    result.add(remoteNodeId);
                partMap.updateSequence(partMap.updateSequence() + 1, partMap.topologyVersion());
                U.warn(log, "Partition has been scheduled for rebalancing due to outdated update counter " + "[nodeId=" + remoteNodeId + ", groupId=" + grpId + ", partId=" + p + ", haveHistory=" + haveHistory + "]");
            }
        }
        part2node.put(p, owners);
        if (updateSeq)
            this.updateSeq.incrementAndGet();
    } finally {
        lock.writeLock().unlock();
    }
    return result;
}
Also used : GridDhtPartitionMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap) UUID(java.util.UUID) GridPartitionStateMap(org.apache.ignite.internal.util.GridPartitionStateMap) CachePartitionFullCountersMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionFullCountersMap) HashMap(java.util.HashMap) Map(java.util.Map) GridDhtPartitionFullMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap) CachePartitionPartialCountersMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionPartialCountersMap) GridDhtPartitionMap(org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap)

Aggregations

GridDhtPartitionMap (org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionMap)67 UUID (java.util.UUID)47 GridDhtPartitionFullMap (org.apache.ignite.internal.processors.cache.distributed.dht.preloader.GridDhtPartitionFullMap)46 Map (java.util.Map)41 HashMap (java.util.HashMap)36 GridPartitionStateMap (org.apache.ignite.internal.util.GridPartitionStateMap)32 CachePartitionPartialCountersMap (org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionPartialCountersMap)30 CachePartitionFullCountersMap (org.apache.ignite.internal.processors.cache.distributed.dht.preloader.CachePartitionFullCountersMap)28 ClusterNode (org.apache.ignite.cluster.ClusterNode)20 HashSet (java.util.HashSet)14 AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)10 Set (java.util.Set)9 AtomicInteger (java.util.concurrent.atomic.AtomicInteger)8 AffinityAssignment (org.apache.ignite.internal.processors.affinity.AffinityAssignment)8 ArrayList (java.util.ArrayList)7 Ignite (org.apache.ignite.Ignite)7 IgniteKernal (org.apache.ignite.internal.IgniteKernal)7 GridDhtPartitionState (org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionState)7 GridDhtPartitionTopology (org.apache.ignite.internal.processors.cache.distributed.dht.topology.GridDhtPartitionTopology)7 List (java.util.List)6