Search in sources :

Example 51 with PartitionReplica

use of com.hazelcast.internal.partition.PartitionReplica in project hazelcast by hazelcast.

the class MigrationManager method commitMigrationToDestinationAsync.

/**
 * Sends a {@link MigrationCommitOperation} to the destination and returns {@code true} if the new partition state
 * was applied on the destination.
 */
@SuppressWarnings({ "checkstyle:npathcomplexity", "checkstyle:cyclomaticcomplexity", "checkstyle:methodlength" })
private CompletionStage<Boolean> commitMigrationToDestinationAsync(final MigrationInfo migration) {
    PartitionReplica destination = migration.getDestination();
    if (destination.isIdentical(node.getLocalMember())) {
        if (logger.isFinestEnabled()) {
            logger.finest("Shortcutting migration commit, since destination is master. -> " + migration);
        }
        return CompletableFuture.completedFuture(Boolean.TRUE);
    }
    Member member = node.getClusterService().getMember(destination.address(), destination.uuid());
    if (member == null) {
        logger.warning("Cannot commit " + migration + ". Destination " + destination + " is not a member anymore");
        return CompletableFuture.completedFuture(Boolean.FALSE);
    }
    try {
        if (logger.isFinestEnabled()) {
            logger.finest("Sending migration commit operation to " + destination + " for " + migration);
        }
        migration.setStatus(MigrationStatus.SUCCESS);
        UUID destinationUuid = member.getUuid();
        MigrationCommitOperation operation = new MigrationCommitOperation(migration, destinationUuid);
        InvocationFuture<Boolean> future = nodeEngine.getOperationService().createInvocationBuilder(SERVICE_NAME, operation, destination.address()).setTryCount(Integer.MAX_VALUE).setCallTimeout(memberHeartbeatTimeoutMillis).invoke();
        return future.handleAsync((done, t) -> {
            // Inspect commit result;
            // - if there's an exception, either retry or fail
            // - if result is true then success, otherwise failure
            logger.fine("Migration commit response received -> " + migration + ", success: " + done + ", failure: " + t);
            if (t != null) {
                logMigrationCommitFailure(migration, t);
                if (t instanceof OperationTimeoutException || t.getCause() instanceof OperationTimeoutException) {
                    return COMMIT_RETRY;
                }
                return COMMIT_FAILURE;
            }
            return done ? COMMIT_SUCCESS : COMMIT_FAILURE;
        }, asyncExecutor).thenComposeAsync(result -> {
            switch(result) {
                case COMMIT_SUCCESS:
                    return CompletableFuture.completedFuture(true);
                case COMMIT_FAILURE:
                    return CompletableFuture.completedFuture(false);
                case COMMIT_RETRY:
                    logger.fine("Retrying migration commit for -> " + migration);
                    return commitMigrationToDestinationAsync(migration);
                default:
                    throw new IllegalArgumentException("Unknown migration commit result: " + result);
            }
        }, asyncExecutor).handleAsync((result, t) -> {
            if (t != null) {
                logMigrationCommitFailure(migration, t);
                return false;
            }
            if (logger.isFineEnabled()) {
                logger.fine("Migration commit result " + result + " from " + destination + " for " + migration);
            }
            return result;
        }, asyncExecutor);
    } catch (Throwable t) {
        logMigrationCommitFailure(migration, t);
        return CompletableFuture.completedFuture(Boolean.FALSE);
    }
}
Also used : MigrationCommitOperation(com.hazelcast.internal.partition.operation.MigrationCommitOperation) Address(com.hazelcast.cluster.Address) HazelcastInstanceNotActiveException(com.hazelcast.core.HazelcastInstanceNotActiveException) InvocationFuture(com.hazelcast.spi.impl.operationservice.impl.InvocationFuture) Arrays(java.util.Arrays) PartitionRuntimeState(com.hazelcast.internal.partition.PartitionRuntimeState) ShutdownResponseOperation(com.hazelcast.internal.partition.operation.ShutdownResponseOperation) Preconditions(com.hazelcast.internal.util.Preconditions) ScheduledFuture(java.util.concurrent.ScheduledFuture) PartitionStateVersionMismatchException(com.hazelcast.internal.partition.PartitionStateVersionMismatchException) Clock(com.hazelcast.internal.util.Clock) MIGRATION_METRIC_MIGRATION_MANAGER_MIGRATION_ACTIVE(com.hazelcast.internal.metrics.MetricDescriptorConstants.MIGRATION_METRIC_MIGRATION_MANAGER_MIGRATION_ACTIVE) Member(com.hazelcast.cluster.Member) BiFunction(java.util.function.BiFunction) IntConsumer(java.util.function.IntConsumer) ASYNC_EXECUTOR(com.hazelcast.spi.impl.executionservice.ExecutionService.ASYNC_EXECUTOR) InternalCompletableFuture(com.hazelcast.spi.impl.InternalCompletableFuture) MigrationStateImpl(com.hazelcast.internal.partition.MigrationStateImpl) Future(java.util.concurrent.Future) PartitionTableView(com.hazelcast.internal.partition.PartitionTableView) MigrationCommitOperation(com.hazelcast.internal.partition.operation.MigrationCommitOperation) DATA_MEMBER_SELECTOR(com.hazelcast.cluster.memberselector.MemberSelectors.DATA_MEMBER_SELECTOR) Int2ObjectHashMap(com.hazelcast.internal.util.collection.Int2ObjectHashMap) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) MigrationRequestOperation(com.hazelcast.internal.partition.operation.MigrationRequestOperation) Map(java.util.Map) BOOLEAN(com.hazelcast.internal.metrics.ProbeUnit.BOOLEAN) PARTITIONS_PREFIX(com.hazelcast.internal.metrics.MetricDescriptorConstants.PARTITIONS_PREFIX) PersistenceConfig(com.hazelcast.config.PersistenceConfig) IntHashSet(com.hazelcast.internal.util.collection.IntHashSet) PARTITION_FRAGMENTED_MIGRATION_ENABLED(com.hazelcast.spi.properties.ClusterProperty.PARTITION_FRAGMENTED_MIGRATION_ENABLED) InternalPartition(com.hazelcast.internal.partition.InternalPartition) IPartitionLostEvent(com.hazelcast.internal.partition.IPartitionLostEvent) Probe(com.hazelcast.internal.metrics.Probe) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Set(java.util.Set) BlockingQueue(java.util.concurrent.BlockingQueue) TargetNotMemberException(com.hazelcast.spi.exception.TargetNotMemberException) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) PARTITION_CHUNKED_MIGRATION_ENABLED(com.hazelcast.spi.properties.ClusterProperty.PARTITION_CHUNKED_MIGRATION_ENABLED) Node(com.hazelcast.instance.impl.Node) ClusterProperty(com.hazelcast.spi.properties.ClusterProperty) Objects(java.util.Objects) ArrayBlockingQueue(java.util.concurrent.ArrayBlockingQueue) List(java.util.List) CompletionStage(java.util.concurrent.CompletionStage) OperationTimeoutException(com.hazelcast.core.OperationTimeoutException) PartitionIdSet(com.hazelcast.internal.util.collection.PartitionIdSet) Queue(java.util.Queue) MigrationStatus(com.hazelcast.internal.partition.MigrationInfo.MigrationStatus) MEGABYTES(com.hazelcast.memory.MemoryUnit.MEGABYTES) ReplicaMigrationEvent(com.hazelcast.partition.ReplicaMigrationEvent) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) HashMap(java.util.HashMap) CompletableFuture(java.util.concurrent.CompletableFuture) ExecutionService(com.hazelcast.spi.impl.executionservice.ExecutionService) OperationServiceImpl(com.hazelcast.spi.impl.operationservice.impl.OperationServiceImpl) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) ConcurrentMap(java.util.concurrent.ConcurrentMap) Level(java.util.logging.Level) MigrationEndpoint(com.hazelcast.internal.partition.MigrationEndpoint) HashSet(java.util.HashSet) PARTITION_MIGRATION_TIMEOUT(com.hazelcast.spi.properties.ClusterProperty.PARTITION_MIGRATION_TIMEOUT) ILogger(com.hazelcast.logging.ILogger) Operation(com.hazelcast.spi.impl.operationservice.Operation) PartitionReplica(com.hazelcast.internal.partition.PartitionReplica) FinalizeMigrationOperation(com.hazelcast.internal.partition.operation.FinalizeMigrationOperation) LinkedList(java.util.LinkedList) ClusterServiceImpl(com.hazelcast.internal.cluster.impl.ClusterServiceImpl) PartitionStateOperation(com.hazelcast.internal.partition.operation.PartitionStateOperation) LinkedHashSet(java.util.LinkedHashSet) Timer(com.hazelcast.internal.util.Timer) NodeEngineImpl(com.hazelcast.spi.impl.NodeEngineImpl) CoalescingDelayedTrigger(com.hazelcast.internal.util.scheduler.CoalescingDelayedTrigger) Iterator(java.util.Iterator) Executor(java.util.concurrent.Executor) MigrationParticipant(com.hazelcast.internal.partition.impl.MigrationInterceptor.MigrationParticipant) MemberLeftException(com.hazelcast.core.MemberLeftException) HazelcastProperties(com.hazelcast.spi.properties.HazelcastProperties) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) PARTITION_CHUNKED_MAX_MIGRATING_DATA_IN_MB(com.hazelcast.spi.properties.ClusterProperty.PARTITION_CHUNKED_MAX_MIGRATING_DATA_IN_MB) PartitionReplicaSyncRequest(com.hazelcast.internal.partition.operation.PartitionReplicaSyncRequest) Lock(java.util.concurrent.locks.Lock) SERVICE_NAME(com.hazelcast.internal.partition.IPartitionService.SERVICE_NAME) MigrationDecisionCallback(com.hazelcast.internal.partition.impl.MigrationPlanner.MigrationDecisionCallback) PromotionCommitOperation(com.hazelcast.internal.partition.operation.PromotionCommitOperation) ClusterState(com.hazelcast.cluster.ClusterState) PublishCompletedMigrationsOperation(com.hazelcast.internal.partition.operation.PublishCompletedMigrationsOperation) MigrationInfo(com.hazelcast.internal.partition.MigrationInfo) PARTITION_MIGRATION_INTERVAL(com.hazelcast.spi.properties.ClusterProperty.PARTITION_MIGRATION_INTERVAL) OperationService(com.hazelcast.spi.impl.operationservice.OperationService) Comparator(java.util.Comparator) Collections(java.util.Collections) PartitionReplica(com.hazelcast.internal.partition.PartitionReplica) OperationTimeoutException(com.hazelcast.core.OperationTimeoutException) UUID(java.util.UUID) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) Member(com.hazelcast.cluster.Member)

Example 52 with PartitionReplica

use of com.hazelcast.internal.partition.PartitionReplica in project hazelcast by hazelcast.

the class MigrationManager method scheduleActiveMigrationFinalization.

/**
 * Finalizes the active migration if it is equal to the {@code migrationInfo} or if this node was a backup replica before
 * the migration (see {@link FinalizeMigrationOperation}).
 * Acquires the partition service lock.
 */
void scheduleActiveMigrationFinalization(final MigrationInfo migrationInfo) {
    partitionServiceLock.lock();
    try {
        MigrationInfo activeMigrationInfo = getActiveMigration(migrationInfo.getPartitionId());
        if (migrationInfo.equals(activeMigrationInfo)) {
            activeMigrationInfo.setStatus(migrationInfo.getStatus());
            if (logger.isFineEnabled()) {
                logger.fine("Scheduled finalization of " + activeMigrationInfo);
            }
            finalizeMigration(activeMigrationInfo);
            return;
        }
        PartitionReplica source = migrationInfo.getSource();
        if (source != null && migrationInfo.getSourceCurrentReplicaIndex() > 0 && source.isIdentical(node.getLocalMember())) {
            // This is former backup replica owner.
            // Former backup owner does not participate in migration transaction, data always copied
            // from the primary replica. Former backup replica is not notified about this migration
            // until the migration is committed on destination. Active migration is not set
            // for this migration.
            // This path can be executed multiple times,
            // when a periodic update (latest completed migrations or the whole partition table) is received
            // and a new migration request is submitted concurrently.
            // That's why, migration should be validated by partition table, to determine whether
            // this migration finalization is already processed or not.
            InternalPartitionImpl partition = partitionStateManager.getPartitionImpl(migrationInfo.getPartitionId());
            if (migrationInfo.getStatus() == MigrationStatus.SUCCESS && migrationInfo.getSourceNewReplicaIndex() != partition.getReplicaIndex(source)) {
                if (logger.isFinestEnabled()) {
                    logger.finest("Already finalized " + migrationInfo + " on former backup replica. -> " + partition);
                }
                return;
            }
            if (logger.isFineEnabled()) {
                logger.fine("Scheduled finalization of " + migrationInfo + " on former backup replica.");
            }
            finalizeMigration(migrationInfo);
        }
    } finally {
        partitionServiceLock.unlock();
    }
}
Also used : MigrationInfo(com.hazelcast.internal.partition.MigrationInfo) PartitionReplica(com.hazelcast.internal.partition.PartitionReplica)

Example 53 with PartitionReplica

use of com.hazelcast.internal.partition.PartitionReplica in project hazelcast by hazelcast.

the class PartitionReplicaStateChecker method hasMissingReplicaOwners.

private boolean hasMissingReplicaOwners() {
    if (!needsReplicaStateCheck()) {
        return false;
    }
    int memberGroupsSize = partitionStateManager.getMemberGroupsSize();
    int replicaCount = Math.min(InternalPartition.MAX_REPLICA_COUNT, memberGroupsSize);
    ClusterServiceImpl clusterService = node.getClusterService();
    ClusterState clusterState = clusterService.getClusterState();
    for (InternalPartition partition : partitionStateManager.getPartitions()) {
        for (int index = 0; index < replicaCount; index++) {
            PartitionReplica replica = partition.getReplica(index);
            if (replica == null) {
                if (logger.isFinestEnabled()) {
                    logger.finest("Missing replica=" + index + " for partitionId=" + partition.getPartitionId());
                }
                return true;
            }
            // because to be able to change cluster state, we ensure that there are no ongoing/pending migrations
            if (clusterService.getMember(replica.address(), replica.uuid()) == null && (clusterState.isJoinAllowed() || !clusterService.isMissingMember(replica.address(), replica.uuid()))) {
                if (logger.isFinestEnabled()) {
                    logger.finest("Unknown replica owner= " + replica + ", partitionId=" + partition.getPartitionId() + ", replica=" + index);
                }
                return true;
            }
        }
    }
    return false;
}
Also used : ClusterState(com.hazelcast.cluster.ClusterState) PartitionReplica(com.hazelcast.internal.partition.PartitionReplica) ClusterServiceImpl(com.hazelcast.internal.cluster.impl.ClusterServiceImpl) InternalPartition(com.hazelcast.internal.partition.InternalPartition)

Example 54 with PartitionReplica

use of com.hazelcast.internal.partition.PartitionReplica in project hazelcast by hazelcast.

the class PartitionStateManager method initializePartitionAssignments.

/**
 * Arranges the partitions if:
 * <ul>
 * <li>this instance {@link NodeExtension#isStartCompleted()}</li>
 * <li>the cluster state allows migrations. See {@link ClusterState#isMigrationAllowed()}</li>
 * </ul>
 * This will also set the manager state to initialized (if not already) and invoke the
 * {@link DefaultPartitionReplicaInterceptor} for all changed replicas which
 * will cancel replica synchronizations and increase the partition state version.
 *
 * @param excludedMembers members which are to be excluded from the new layout
 * @return if the new partition was assigned
 * @throws HazelcastException if the partition state generator failed to arrange the partitions
 */
boolean initializePartitionAssignments(Set<Member> excludedMembers) {
    if (!isPartitionAssignmentAllowed()) {
        return false;
    }
    Collection<MemberGroup> memberGroups = createMemberGroups(excludedMembers);
    if (memberGroups.isEmpty()) {
        logger.warning("No member group is available to assign partition ownership...");
        return false;
    }
    logger.info("Initializing cluster partition table arrangement...");
    PartitionReplica[][] newState = partitionStateGenerator.arrange(memberGroups, partitions);
    if (newState.length != partitionCount) {
        throw new HazelcastException("Invalid partition count! " + "Expected: " + partitionCount + ", Actual: " + newState.length);
    }
    for (int partitionId = 0; partitionId < partitionCount; partitionId++) {
        InternalPartitionImpl partition = partitions[partitionId];
        PartitionReplica[] replicas = newState[partitionId];
        partition.setReplicas(replicas);
    }
    ClusterState clusterState = node.getClusterService().getClusterState();
    if (!clusterState.isMigrationAllowed()) {
        // cluster state is either changed or locked, reset state back and fail.
        reset();
        logger.warning("Partitions can't be assigned since cluster-state= " + clusterState);
        return false;
    }
    setInitialized();
    return true;
}
Also used : MemberGroup(com.hazelcast.spi.partitiongroup.MemberGroup) ClusterState(com.hazelcast.cluster.ClusterState) HazelcastException(com.hazelcast.core.HazelcastException) PartitionReplica(com.hazelcast.internal.partition.PartitionReplica)

Example 55 with PartitionReplica

use of com.hazelcast.internal.partition.PartitionReplica in project hazelcast by hazelcast.

the class PartitionStateManager method setInitialState.

/**
 * Sets the initial partition table and state version. If any partition has a replica, the partition state manager is
 * set to initialized, otherwise {@link #isInitialized()} stays uninitialized but the current state will be updated
 * nevertheless.
 *
 * @param partitionTable the initial partition table
 * @throws IllegalStateException if the partition manager has already been initialized
 */
void setInitialState(PartitionTableView partitionTable) {
    if (initialized) {
        throw new IllegalStateException("Partition table is already initialized!");
    }
    logger.info("Setting cluster partition table...");
    boolean foundReplica = false;
    PartitionReplica localReplica = PartitionReplica.from(node.getLocalMember());
    for (int partitionId = 0; partitionId < partitionCount; partitionId++) {
        InternalPartitionImpl partition = partitions[partitionId];
        InternalPartition newPartition = partitionTable.getPartition(partitionId);
        if (!foundReplica && newPartition != null) {
            for (int i = 0; i < InternalPartition.MAX_REPLICA_COUNT; i++) {
                foundReplica |= newPartition.getReplica(i) != null;
            }
        }
        partition.reset(localReplica);
        if (newPartition != null) {
            partition.setReplicasAndVersion(newPartition);
        }
    }
    if (foundReplica) {
        setInitialized();
    }
}
Also used : PartitionReplica(com.hazelcast.internal.partition.PartitionReplica) InternalPartition(com.hazelcast.internal.partition.InternalPartition) ReadonlyInternalPartition(com.hazelcast.internal.partition.ReadonlyInternalPartition)

Aggregations

PartitionReplica (com.hazelcast.internal.partition.PartitionReplica)103 ParallelJVMTest (com.hazelcast.test.annotation.ParallelJVMTest)51 QuickTest (com.hazelcast.test.annotation.QuickTest)51 Test (org.junit.Test)51 Address (com.hazelcast.cluster.Address)44 InternalPartition (com.hazelcast.internal.partition.InternalPartition)17 MigrationInfo (com.hazelcast.internal.partition.MigrationInfo)17 ArrayList (java.util.ArrayList)10 Member (com.hazelcast.cluster.Member)8 HazelcastInstance (com.hazelcast.core.HazelcastInstance)7 ClusterServiceImpl (com.hazelcast.internal.cluster.impl.ClusterServiceImpl)7 PartitionTableView (com.hazelcast.internal.partition.PartitionTableView)6 ReadonlyInternalPartition (com.hazelcast.internal.partition.ReadonlyInternalPartition)6 ClusterState (com.hazelcast.cluster.ClusterState)5 TestHazelcastInstanceFactory (com.hazelcast.test.TestHazelcastInstanceFactory)5 NodeEngine (com.hazelcast.spi.impl.NodeEngine)4 Operation (com.hazelcast.spi.impl.operationservice.Operation)4 HazelcastInstanceNotActiveException (com.hazelcast.core.HazelcastInstanceNotActiveException)3 MemberLeftException (com.hazelcast.core.MemberLeftException)3 InternalPartitionService (com.hazelcast.internal.partition.InternalPartitionService)3