Search in sources :

Example 21 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridDhtCacheAdapter method beginMultiUpdate.

/**
 * Starts multi-update lock. Will wait for topology future is ready.
 *
 * @return Topology version.
 * @throws IgniteCheckedException If failed.
 */
public AffinityTopologyVersion beginMultiUpdate() throws IgniteCheckedException {
    IgniteBiTuple<IgniteUuid, GridDhtTopologyFuture> tup = multiTxHolder.get();
    if (tup != null)
        throw new IgniteCheckedException("Nested multi-update locks are not supported");
    GridDhtPartitionTopology top = ctx.group().topology();
    top.readLock();
    GridDhtTopologyFuture topFut;
    AffinityTopologyVersion topVer;
    try {
        // While we are holding read lock, register lock future for partition release future.
        IgniteUuid lockId = IgniteUuid.fromUuid(ctx.localNodeId());
        topVer = top.readyTopologyVersion();
        MultiUpdateFuture fut = new MultiUpdateFuture(topVer);
        MultiUpdateFuture old = multiTxFuts.putIfAbsent(lockId, fut);
        assert old == null;
        topFut = top.topologyVersionFuture();
        multiTxHolder.set(F.t(lockId, topFut));
    } finally {
        top.readUnlock();
    }
    topFut.get();
    return topVer;
}
Also used : IgniteCheckedException(org.apache.ignite.IgniteCheckedException) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteUuid(org.apache.ignite.lang.IgniteUuid)

Example 22 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridDhtPartitionTopologyImpl method updateTopologyVersion.

/**
 * {@inheritDoc}
 */
@Override
public void updateTopologyVersion(GridDhtTopologyFuture exchFut, @NotNull DiscoCache discoCache, long updSeq, boolean stopping) throws IgniteInterruptedCheckedException {
    U.writeLock(lock);
    try {
        AffinityTopologyVersion exchTopVer = exchFut.initialVersion();
        // Update is correct if topology version is newer or in case of newer discovery caches.
        boolean isCorrectUpdate = exchTopVer.compareTo(readyTopVer) > 0 || (exchTopVer.compareTo(readyTopVer) == 0 && this.discoCache != null && discoCache.version().compareTo(this.discoCache.version()) > 0);
        assert isCorrectUpdate : "Invalid topology version [grp=" + grp.cacheOrGroupName() + ", topVer=" + readyTopVer + ", exchTopVer=" + exchTopVer + ", discoCacheVer=" + (this.discoCache != null ? this.discoCache.version() : "None") + ", exchDiscoCacheVer=" + discoCache.version() + ", fut=" + exchFut + ']';
        this.stopping = stopping;
        updateSeq.setIfGreater(updSeq);
        topReadyFut = exchFut;
        rebalancedTopVer = AffinityTopologyVersion.NONE;
        lastTopChangeVer = exchTopVer;
        this.discoCache = discoCache;
    } finally {
        lock.writeLock().unlock();
    }
}
Also used : AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)

Example 23 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridDhtPartitionTopologyImpl method afterExchange.

/**
 * {@inheritDoc}
 */
@Override
public boolean afterExchange(GridDhtPartitionsExchangeFuture exchFut) {
    boolean changed = false;
    int num = grp.affinity().partitions();
    AffinityTopologyVersion topVer = exchFut.context().events().topologyVersion();
    assert grp.affinity().lastVersion().equals(topVer) : "Affinity is not initialized " + "[grp=" + grp.cacheOrGroupName() + ", topVer=" + topVer + ", affVer=" + grp.affinity().lastVersion() + ", fut=" + exchFut + ']';
    ctx.database().checkpointReadLock();
    try {
        lock.writeLock().lock();
        try {
            if (stopping)
                return false;
            assert readyTopVer.initialized() : readyTopVer;
            assert lastTopChangeVer.equals(readyTopVer);
            if (log.isDebugEnabled()) {
                log.debug("Partition map before afterExchange [grp=" + grp.cacheOrGroupName() + ", exchId=" + exchFut.exchangeId() + ", fullMap=" + fullMapString() + ']');
            }
            long updateSeq = this.updateSeq.incrementAndGet();
            for (int p = 0; p < num; p++) {
                GridDhtLocalPartition locPart = localPartition0(p, topVer, false, false, false);
                if (partitionLocalNode(p, topVer)) {
                    // which obviously has not happened at this point.
                    if (locPart == null) {
                        if (log.isDebugEnabled()) {
                            log.debug("Skipping local partition afterExchange (will not create) [" + "grp=" + grp.cacheOrGroupName() + ", p=" + p + ']');
                        }
                        continue;
                    }
                    GridDhtPartitionState state = locPart.state();
                    if (state == MOVING) {
                        if (grp.rebalanceEnabled()) {
                            Collection<ClusterNode> owners = owners(p);
                            // If there are no other owners, then become an owner.
                            if (F.isEmpty(owners)) {
                                boolean owned = locPart.own();
                                assert owned : "Failed to own partition [grp=" + grp.cacheOrGroupName() + ", locPart=" + locPart + ']';
                                updateSeq = updateLocal(p, locPart.state(), updateSeq, topVer);
                                changed = true;
                                if (grp.eventRecordable(EVT_CACHE_REBALANCE_PART_DATA_LOST)) {
                                    DiscoveryEvent discoEvt = exchFut.events().lastEvent();
                                    grp.addRebalanceEvent(p, EVT_CACHE_REBALANCE_PART_DATA_LOST, discoEvt.eventNode(), discoEvt.type(), discoEvt.timestamp());
                                }
                                if (log.isDebugEnabled()) {
                                    log.debug("Owned partition [grp=" + grp.cacheOrGroupName() + ", part=" + locPart + ']');
                                }
                            } else if (log.isDebugEnabled())
                                log.debug("Will not own partition (there are owners to rebalance from) [grp=" + grp.cacheOrGroupName() + ", locPart=" + locPart + ", owners = " + owners + ']');
                        } else
                            updateSeq = updateLocal(p, locPart.state(), updateSeq, topVer);
                    }
                } else {
                    if (locPart != null) {
                        GridDhtPartitionState state = locPart.state();
                        if (state == MOVING) {
                            locPart.rent(false);
                            updateSeq = updateLocal(p, locPart.state(), updateSeq, topVer);
                            changed = true;
                            if (log.isDebugEnabled()) {
                                log.debug("Evicting " + state + " partition (it does not belong to affinity) [" + "grp=" + grp.cacheOrGroupName() + ", part=" + locPart + ']');
                            }
                        }
                    }
                }
            }
            AffinityAssignment aff = grp.affinity().readyAffinity(topVer);
            if (node2part != null && node2part.valid())
                changed |= checkEvictions(updateSeq, aff);
            updateRebalanceVersion(aff.assignment());
            consistencyCheck();
        } finally {
            lock.writeLock().unlock();
        }
    } finally {
        ctx.database().checkpointReadUnlock();
    }
    return changed;
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) AffinityAssignment(org.apache.ignite.internal.processors.affinity.AffinityAssignment) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) DiscoveryEvent(org.apache.ignite.events.DiscoveryEvent)

Example 24 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class DataStreamerImpl method load0.

/**
 * @param entries Entries.
 * @param resFut Result future.
 * @param activeKeys Active keys.
 * @param remaps Remaps count.
 */
private void load0(Collection<? extends DataStreamerEntry> entries, final GridFutureAdapter<Object> resFut, @Nullable final Collection<KeyCacheObjectWrapper> activeKeys, final int remaps) {
    try {
        assert entries != null;
        final boolean remap = remaps > 0;
        if (!remap) {
            // Failed data should be processed prior to new data.
            acquireRemapSemaphore();
        }
        if (!isWarningPrinted) {
            synchronized (this) {
                if (!allowOverwrite() && !isWarningPrinted) {
                    U.warn(log, "Data streamer will not overwrite existing cache entries for better performance " + "(to change, set allowOverwrite to true)");
                }
                isWarningPrinted = true;
            }
        }
        Map<ClusterNode, Collection<DataStreamerEntry>> mappings = new HashMap<>();
        boolean initPda = ctx.deploy().enabled() && jobPda == null;
        GridCacheAdapter cache = ctx.cache().internalCache(cacheName);
        if (cache == null)
            throw new IgniteCheckedException("Cache not created or already destroyed.");
        GridCacheContext cctx = cache.context();
        GridCacheGateway gate = null;
        AffinityTopologyVersion topVer;
        if (!cctx.isLocal())
            topVer = ctx.cache().context().exchange().lastTopologyFuture().get();
        else
            topVer = ctx.cache().context().exchange().readyAffinityVersion();
        List<List<ClusterNode>> assignments = cctx.affinity().assignments(topVer);
        if (!allowOverwrite() && !cctx.isLocal()) {
            // Cases where cctx required.
            gate = cctx.gate();
            gate.enter();
        }
        try {
            for (DataStreamerEntry entry : entries) {
                List<ClusterNode> nodes;
                try {
                    KeyCacheObject key = entry.getKey();
                    assert key != null;
                    if (initPda) {
                        if (cacheObjCtx.addDeploymentInfo())
                            jobPda = new DataStreamerPda(key.value(cacheObjCtx, false), entry.getValue() != null ? entry.getValue().value(cacheObjCtx, false) : null, rcvr);
                        else if (rcvr != null)
                            jobPda = new DataStreamerPda(rcvr);
                        initPda = false;
                    }
                    if (key.partition() == -1)
                        key.partition(cctx.affinity().partition(key, false));
                    nodes = nodes(key, topVer, cctx);
                } catch (IgniteCheckedException e) {
                    resFut.onDone(e);
                    return;
                }
                if (F.isEmpty(nodes)) {
                    resFut.onDone(new ClusterTopologyException("Failed to map key to node " + "(no nodes with cache found in topology) [infos=" + entries.size() + ", cacheName=" + cacheName + ']'));
                    return;
                }
                for (ClusterNode node : nodes) {
                    Collection<DataStreamerEntry> col = mappings.get(node);
                    if (col == null)
                        mappings.put(node, col = new ArrayList<>());
                    col.add(entry);
                }
            }
            for (final Map.Entry<ClusterNode, Collection<DataStreamerEntry>> e : mappings.entrySet()) {
                final UUID nodeId = e.getKey().id();
                Buffer buf = bufMappings.get(nodeId);
                if (buf == null) {
                    Buffer old = bufMappings.putIfAbsent(nodeId, buf = new Buffer(e.getKey()));
                    if (old != null)
                        buf = old;
                }
                final Collection<DataStreamerEntry> entriesForNode = e.getValue();
                IgniteInClosure<IgniteInternalFuture<?>> lsnr = new IgniteInClosure<IgniteInternalFuture<?>>() {

                    @Override
                    public void apply(IgniteInternalFuture<?> t) {
                        try {
                            t.get();
                            if (activeKeys != null) {
                                for (DataStreamerEntry e : entriesForNode) activeKeys.remove(new KeyCacheObjectWrapper(e.getKey()));
                                if (activeKeys.isEmpty())
                                    resFut.onDone();
                            } else {
                                assert entriesForNode.size() == 1;
                                // That has been a single key,
                                // so complete result future right away.
                                resFut.onDone();
                            }
                        } catch (IgniteClientDisconnectedCheckedException e1) {
                            if (log.isDebugEnabled())
                                log.debug("Future finished with disconnect error [nodeId=" + nodeId + ", err=" + e1 + ']');
                            resFut.onDone(e1);
                        } catch (IgniteCheckedException e1) {
                            if (log.isDebugEnabled())
                                log.debug("Future finished with error [nodeId=" + nodeId + ", err=" + e1 + ']');
                            if (cancelled) {
                                resFut.onDone(new IgniteCheckedException("Data streamer has been cancelled: " + DataStreamerImpl.this, e1));
                            } else if (remaps + 1 > maxRemapCnt) {
                                resFut.onDone(new IgniteCheckedException("Failed to finish operation (too many remaps): " + remaps, e1));
                            } else {
                                try {
                                    remapSem.acquire();
                                    final Runnable r = new Runnable() {

                                        @Override
                                        public void run() {
                                            try {
                                                if (cancelled)
                                                    closedException();
                                                load0(entriesForNode, resFut, activeKeys, remaps + 1);
                                            } catch (Throwable ex) {
                                                resFut.onDone(new IgniteCheckedException("DataStreamer remapping failed. ", ex));
                                            } finally {
                                                remapSem.release();
                                            }
                                        }
                                    };
                                    dataToRemap.add(r);
                                    if (!remapOwning.get() && remapOwning.compareAndSet(false, true)) {
                                        ctx.closure().callLocalSafe(new GPC<Boolean>() {

                                            @Override
                                            public Boolean call() {
                                                boolean locked = true;
                                                while (locked || !dataToRemap.isEmpty()) {
                                                    if (!locked && !remapOwning.compareAndSet(false, true))
                                                        return false;
                                                    try {
                                                        Runnable r = dataToRemap.poll();
                                                        if (r != null)
                                                            r.run();
                                                    } finally {
                                                        if (!dataToRemap.isEmpty())
                                                            locked = true;
                                                        else {
                                                            remapOwning.set(false);
                                                            locked = false;
                                                        }
                                                    }
                                                }
                                                return true;
                                            }
                                        }, true);
                                    }
                                } catch (InterruptedException e2) {
                                    resFut.onDone(e2);
                                }
                            }
                        }
                    }
                };
                GridCompoundFuture opFut = new SilentCompoundFuture();
                opFut.listen(lsnr);
                final List<GridFutureAdapter<?>> futs;
                try {
                    futs = buf.update(entriesForNode, topVer, assignments, opFut, remap);
                    opFut.markInitialized();
                } catch (IgniteInterruptedCheckedException e1) {
                    resFut.onDone(e1);
                    return;
                }
                if (ctx.discovery().node(nodeId) == null) {
                    if (bufMappings.remove(nodeId, buf)) {
                        final Buffer buf0 = buf;
                        waitAffinityAndRun(new Runnable() {

                            @Override
                            public void run() {
                                buf0.onNodeLeft();
                                if (futs != null) {
                                    Throwable ex = new ClusterTopologyCheckedException("Failed to wait for request completion (node has left): " + nodeId);
                                    for (int i = 0; i < futs.size(); i++) futs.get(i).onDone(ex);
                                }
                            }
                        }, ctx.discovery().topologyVersion(), false);
                    }
                }
            }
        } finally {
            if (gate != null)
                gate.leave();
        }
    } catch (Exception ex) {
        resFut.onDone(new IgniteCheckedException("DataStreamer data loading failed.", ex));
    }
}
Also used : ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) IgniteInternalFuture(org.apache.ignite.internal.IgniteInternalFuture) IgniteInterruptedException(org.apache.ignite.IgniteInterruptedException) GridCompoundFuture(org.apache.ignite.internal.util.future.GridCompoundFuture) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) GridCacheAdapter(org.apache.ignite.internal.processors.cache.GridCacheAdapter) GridFutureAdapter(org.apache.ignite.internal.util.future.GridFutureAdapter) ArrayList(java.util.ArrayList) List(java.util.List) GridCacheGateway(org.apache.ignite.internal.processors.cache.GridCacheGateway) UUID(java.util.UUID) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) KeyCacheObject(org.apache.ignite.internal.processors.cache.KeyCacheObject) ClusterNode(org.apache.ignite.cluster.ClusterNode) GridCacheContext(org.apache.ignite.internal.processors.cache.GridCacheContext) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) IgniteCheckedException(org.apache.ignite.IgniteCheckedException) IgniteDataStreamerTimeoutException(org.apache.ignite.IgniteDataStreamerTimeoutException) IgniteInterruptedException(org.apache.ignite.IgniteInterruptedException) IgniteInterruptedCheckedException(org.apache.ignite.internal.IgniteInterruptedCheckedException) ClusterTopologyServerNotFoundException(org.apache.ignite.internal.cluster.ClusterTopologyServerNotFoundException) IgniteClientDisconnectedCheckedException(org.apache.ignite.internal.IgniteClientDisconnectedCheckedException) IgniteException(org.apache.ignite.IgniteException) GridCacheEntryRemovedException(org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException) IgniteFutureTimeoutCheckedException(org.apache.ignite.internal.IgniteFutureTimeoutCheckedException) ClusterTopologyException(org.apache.ignite.cluster.ClusterTopologyException) CacheException(javax.cache.CacheException) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException) GridDhtInvalidPartitionException(org.apache.ignite.internal.processors.cache.distributed.dht.GridDhtInvalidPartitionException) Collection(java.util.Collection) IgniteInClosure(org.apache.ignite.lang.IgniteInClosure) IgniteClientDisconnectedCheckedException(org.apache.ignite.internal.IgniteClientDisconnectedCheckedException) ClusterTopologyException(org.apache.ignite.cluster.ClusterTopologyException) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) ConcurrentMap(java.util.concurrent.ConcurrentMap) ClusterTopologyCheckedException(org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)

Example 25 with AffinityTopologyVersion

use of org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion in project ignite by apache.

the class GridDhtAtomicAbstractUpdateFuture method addWriteEntry.

/**
 * @param affAssignment Affinity assignment.
 * @param entry Entry to map.
 * @param val Value to write.
 * @param entryProcessor Entry processor.
 * @param ttl TTL (optional).
 * @param conflictExpireTime Conflict expire time (optional).
 * @param conflictVer Conflict version (optional).
 * @param addPrevVal If {@code true} sends previous value to backups.
 * @param prevVal Previous value.
 * @param updateCntr Partition update counter.
 */
@SuppressWarnings("ForLoopReplaceableByForEach")
final void addWriteEntry(AffinityAssignment affAssignment, GridDhtCacheEntry entry, @Nullable CacheObject val, EntryProcessor<Object, Object, Object> entryProcessor, long ttl, long conflictExpireTime, @Nullable GridCacheVersion conflictVer, boolean addPrevVal, @Nullable CacheObject prevVal, long updateCntr) {
    AffinityTopologyVersion topVer = updateReq.topologyVersion();
    List<ClusterNode> affNodes = affAssignment.get(entry.partition());
    // Client has seen that rebalancing finished, it is safe to use affinity mapping.
    List<ClusterNode> dhtNodes = updateReq.affinityMapping() ? affNodes : cctx.dht().topology().nodes(entry.partition(), affAssignment, affNodes);
    if (dhtNodes == null)
        dhtNodes = affNodes;
    if (log.isDebugEnabled())
        log.debug("Mapping entry to DHT nodes [nodes=" + U.nodeIds(dhtNodes) + ", entry=" + entry + ']');
    CacheWriteSynchronizationMode syncMode = updateReq.writeSynchronizationMode();
    addDhtKey(entry.key(), dhtNodes);
    for (int i = 0; i < dhtNodes.size(); i++) {
        ClusterNode node = dhtNodes.get(i);
        UUID nodeId = node.id();
        if (!nodeId.equals(cctx.localNodeId())) {
            GridDhtAtomicAbstractUpdateRequest updateReq = mappings.get(nodeId);
            if (updateReq == null) {
                updateReq = createRequest(node.id(), futId, writeVer, syncMode, topVer, ttl, conflictExpireTime, conflictVer);
                mappings.put(nodeId, updateReq);
            }
            updateReq.addWriteValue(entry.key(), val, entryProcessor, ttl, conflictExpireTime, conflictVer, addPrevVal, prevVal, updateCntr);
        }
    }
}
Also used : ClusterNode(org.apache.ignite.cluster.ClusterNode) AffinityTopologyVersion(org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion) CacheWriteSynchronizationMode(org.apache.ignite.cache.CacheWriteSynchronizationMode) UUID(java.util.UUID)

Aggregations

AffinityTopologyVersion (org.apache.ignite.internal.processors.affinity.AffinityTopologyVersion)386 ClusterNode (org.apache.ignite.cluster.ClusterNode)135 IgniteCheckedException (org.apache.ignite.IgniteCheckedException)116 ArrayList (java.util.ArrayList)85 IgniteInternalFuture (org.apache.ignite.internal.IgniteInternalFuture)74 List (java.util.List)63 UUID (java.util.UUID)63 Map (java.util.Map)62 Test (org.junit.Test)59 Ignite (org.apache.ignite.Ignite)51 HashMap (java.util.HashMap)47 ClusterTopologyCheckedException (org.apache.ignite.internal.cluster.ClusterTopologyCheckedException)47 IgniteEx (org.apache.ignite.internal.IgniteEx)46 GridCommonAbstractTest (org.apache.ignite.testframework.junits.common.GridCommonAbstractTest)40 IgniteException (org.apache.ignite.IgniteException)38 KeyCacheObject (org.apache.ignite.internal.processors.cache.KeyCacheObject)38 GridCacheEntryRemovedException (org.apache.ignite.internal.processors.cache.GridCacheEntryRemovedException)35 Nullable (org.jetbrains.annotations.Nullable)33 DiscoveryEvent (org.apache.ignite.events.DiscoveryEvent)32 GridCacheVersion (org.apache.ignite.internal.processors.cache.version.GridCacheVersion)32