/** * @return Entries map. */ private ConcurrentMap<KeyCacheObject, GridCacheMapEntry> createEntriesMap() { return new ConcurrentHashMap<>(Math.max(10, GridCacheAdapter.DFLT_START_CACHE_SIZE / grp.affinity().partitions()), 0.75f, Runtime.getRuntime().availableProcessors() * 2); }
/** * Creates non-existing partitions belong to given affinity {@code aff}. * * @param affVer Affinity version. * @param aff Affinity assignments. * @param updateSeq Update sequence. */ private void createPartitions(AffinityTopologyVersion affVer, List<List<ClusterNode>> aff, long updateSeq) { if (!grp.affinityNode()) return; int partitions = grp.affinity().partitions(); if (log.isDebugEnabled()) log.debug("Create non-existing partitions [grp=" + grp.cacheOrGroupName() + "]"); for (int p = 0; p < partitions; p++) { if (node2part != null && node2part.valid()) { if (localNode(p, aff)) { // This will make sure that all non-existing partitions // will be created in MOVING state. GridDhtLocalPartition locPart = getOrCreatePartition(p); updateSeq = updateLocal(p, locPart.state(), updateSeq, affVer); } } // If this node's map is empty, we pre-create local partitions, // so local map will be sent correctly during exchange. else if (localNode(p, aff)) getOrCreatePartition(p); } }
/** {@inheritDoc} */ @Override public Map<Integer, List<String>> getAffinityPartitionsAssignmentMap() { AffinityAssignment assignment = ctx.affinity().cachedAffinity(AffinityTopologyVersion.NONE); int part = 0; Map<Integer, List<String>> assignmentMap = new LinkedHashMap<>(); for (List<ClusterNode> partAssignment : assignment.assignment()) { List<String> partNodeIds = new ArrayList<>(partAssignment.size()); for (ClusterNode node : partAssignment) partNodeIds.add(node.id().toString()); assignmentMap.put(part, partNodeIds); part++; } return assignmentMap; }
/** * @param p Partition number. * @param topVer Topology version. * @return {@code True} if given partition belongs to local node. */ private boolean partitionLocalNode(int p, AffinityTopologyVersion topVer) { return grp.affinity().nodes(p, topVer).contains(ctx.localNode()); }
/** * @param topVer Topology version. * @return {@code True} if local node is primary for this partition. */ public boolean primary(AffinityTopologyVersion topVer) { List<ClusterNode> nodes = grp.affinity().cachedAffinity(topVer).get(id); return !nodes.isEmpty() && ctx.localNode().equals(nodes.get(0)); }
/** * @param cancel Cancel. */ public void onKernalStopCaches(boolean cancel) { IgniteCheckedException affErr = new IgniteCheckedException("Failed to wait for topology update, node is stopping."); for (CacheGroupContext grp : cacheGrps.values()) { GridAffinityAssignmentCache aff = grp.affinity(); aff.cancelFutures(affErr); } for (String cacheName : stopSeq) { GridCacheAdapter<?, ?> cache = caches.remove(cacheName); if (cache != null) { stoppedCaches.put(cacheName, cache); onKernalStop(cache, cancel); } } for (Map.Entry<String, GridCacheAdapter<?, ?>> entry : caches.entrySet()) { GridCacheAdapter<?, ?> cache = entry.getValue(); if (cache == caches.remove(entry.getKey())) { stoppedCaches.put(entry.getKey(), cache); onKernalStop(entry.getValue(), cancel); } } }
/** * @param topVer Topology version. * @return {@code True} if local node is backup for this partition. */ public boolean backup(AffinityTopologyVersion topVer) { List<ClusterNode> nodes = grp.affinity().cachedAffinity(topVer).get(id); return nodes.indexOf(ctx.localNode()) > 0; }
/** * */ private void onAllServersLeft() { assert cctx.kernalContext().clientNode() : cctx.localNode(); List<ClusterNode> empty = Collections.emptyList(); for (CacheGroupContext grp : cctx.cache().cacheGroups()) { List<List<ClusterNode>> affAssignment = new ArrayList<>(grp.affinity().partitions()); for (int i = 0; i < grp.affinity().partitions(); i++) affAssignment.add(empty); grp.affinity().idealAssignment(affAssignment); grp.affinity().initialize(initialVersion(), affAssignment); cctx.exchange().exchangerUpdateHeartbeat(); } }
/** {@inheritDoc} */ @Override public List<ClusterNode> nodes(int p, AffinityTopologyVersion topVer) { AffinityAssignment affAssignment = grp.affinity().cachedAffinity(topVer); List<ClusterNode> affNodes = affAssignment.get(p); List<ClusterNode> nodes = nodes0(p, affAssignment, affNodes); return nodes != null ? nodes : affNodes; }
/** {@inheritDoc} */ @Override public void start0() throws IgniteCheckedException { affFunction = cctx.config().getAffinity(); affMapper = cctx.config().getAffinityMapper(); aff = cctx.group().affinity(); }
/** {@inheritDoc} */ @Override public void afterStateRestored(AffinityTopologyVersion topVer) { lock.writeLock().lock(); try { long updateSeq = this.updateSeq.incrementAndGet(); initializeFullMap(updateSeq); for (int p = 0; p < grp.affinity().partitions(); p++) { GridDhtLocalPartition locPart = locParts.get(p); if (locPart == null) updateLocal(p, EVICTED, updateSeq, topVer); else { GridDhtPartitionState state = locPart.state(); updateLocal(p, state, updateSeq, topVer); // Restart cleaning. if (state == RENTING) locPart.clearAsync(); } } } finally { lock.writeLock().unlock(); } }
+ ". Topology version: " + topVer; aff = grp.affinity();
/** {@inheritDoc} */ @Override public boolean initPartitionsWhenAffinityReady(AffinityTopologyVersion affVer, GridDhtPartitionsExchangeFuture exchFut) throws IgniteInterruptedCheckedException { boolean needRefresh; ctx.database().checkpointReadLock(); try { U.writeLock(lock); try { if (stopping) return false; long updateSeq = this.updateSeq.incrementAndGet(); needRefresh = initPartitions(affVer, grp.affinity().readyAssignments(affVer), exchFut, updateSeq); consistencyCheck(); } finally { lock.writeLock().unlock(); } } finally { ctx.database().checkpointReadUnlock(); } return needRefresh; }
checkEvictions(updSeq, grp.affinity().readyAffinity(resTopVer));
/** * */ private abstract class MessageHandler<M> implements IgniteBiInClosure<UUID, M> { /** */ private static final long serialVersionUID = 0L; /** * @param nodeId Sender node ID. * @param msg Message. */ @Override public void apply(UUID nodeId, M msg) { ClusterNode node = cctx.node(nodeId); if (node == null) { if (log.isTraceEnabled()) log.trace("Received message from failed node [node=" + nodeId + ", msg=" + msg + ']'); return; } if (log.isTraceEnabled()) log.trace("Received message from node [node=" + nodeId + ", msg=" + msg + ']'); onMessage(node, msg); } /** * @param node Sender cluster node. * @param msg Message. */ protected abstract void onMessage(ClusterNode node, M msg); }
/** {@inheritDoc} */ @Override public boolean rebalanceRequired(AffinityTopologyVersion rebTopVer, GridDhtPartitionsExchangeFuture exchFut) { if (ctx.kernalContext().clientNode() || rebTopVer.equals(AffinityTopologyVersion.NONE)) return false; // No-op. if (exchFut.resetLostPartitionFor(grp.cacheOrGroupName())) return true; if (exchFut.localJoinExchange()) return true; // Required, can have outdated updSeq partition counter if node reconnects. if (!grp.affinity().cachedVersions().contains(rebTopVer)) { assert rebTopVer.compareTo(grp.localStartVersion()) <= 0 : "Empty hisroty allowed only for newly started cache group [rebTopVer=" + rebTopVer + ", localStartTopVer=" + grp.localStartVersion() + ']'; return true; // Required, since no history info available. } final IgniteInternalFuture<Boolean> rebFut = rebalanceFuture(); if (rebFut.isDone() && !rebFut.result()) return true; // Required, previous rebalance cancelled. AffinityTopologyVersion lastAffChangeTopVer = ctx.exchange().lastAffinityChangedTopologyVersion(exchFut.topologyVersion()); return lastAffChangeTopVer.compareTo(rebTopVer) > 0; }
/** * @param node Node. * @param vers Expected exchange versions. */ private void checkExchanges(Ignite node, long... vers) { IgniteKernal node0 = (IgniteKernal)node; List<AffinityTopologyVersion> expVers = new ArrayList<>(); for (long ver : vers) expVers.add(new AffinityTopologyVersion(ver)); List<AffinityTopologyVersion> doneVers = new ArrayList<>(); List<GridDhtPartitionsExchangeFuture> futs = node0.context().cache().context().exchange().exchangeFutures(); for (int i = futs.size() - 1; i >= 0; i--) { GridDhtPartitionsExchangeFuture fut = futs.get(i); if (!fut.isMerged() && fut.exchangeDone() && fut.firstEvent().type() != EVT_DISCOVERY_CUSTOM_EVT) { AffinityTopologyVersion resVer = fut.topologyVersion(); Assert.assertNotNull(resVer); doneVers.add(resVer); } } assertEquals(expVers, doneVers); for (CacheGroupContext grpCtx : node0.context().cache().cacheGroups()) { for (AffinityTopologyVersion ver : grpCtx.affinity().cachedVersions()) { if (ver.minorTopologyVersion() > 0) continue; assertTrue("Unexpected version [ver=" + ver + ", exp=" + expVers + ']', expVers.contains(ver)); } } }
if (centralizedAff) { // Last server node failed. for (CacheGroupContext grp : cctx.cache().cacheGroups()) { GridAffinityAssignmentCache aff = grp.affinity();