Search in sources :

Example 16 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class RaftTest method createClient.

private RaftClient createClient(List<RaftMember> members) throws Throwable {
    final MemberId memberId = nextNodeId();
    final List<MemberId> memberIds = members.stream().map(RaftMember::memberId).collect(Collectors.toList());
    final RaftClient client = RaftClient.builder().withMemberId(memberId).withPartitionId(PartitionId.from("test", 1)).withProtocol(protocolFactory.newClientProtocol(memberId)).build();
    client.connect(memberIds).thenRun(this::resume);
    await(30000);
    clients.add(client);
    return client;
}
Also used : MemberId(io.atomix.cluster.MemberId)

Example 17 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class RaftTest method testSnapshotSentOnDataLoss.

@Test
public void testSnapshotSentOnDataLoss() throws Throwable {
    final List<RaftMember> members = Lists.newArrayList(createMember(), createMember(), createMember());
    final Map<MemberId, RaftStorage> storages = members.stream().map(RaftMember::memberId).collect(Collectors.toMap(Function.identity(), this::createStorage));
    final Map<MemberId, RaftServer> servers = storages.entrySet().stream().collect(Collectors.toMap(Map.Entry::getKey, this::createServer));
    // wait for cluster to start
    startCluster(servers);
    // fill two segments then compact so we have at least one snapshot
    final RaftClient client = createClient(members);
    final TestPrimitive primitive = createPrimitive(client);
    fillSegment(primitive);
    fillSegment(primitive);
    Futures.allOf(servers.values().stream().map(RaftServer::compact)).thenRun(this::resume);
    await(30000);
    // partition into leader/followers
    final Map<Boolean, List<RaftMember>> collect = members.stream().collect(Collectors.partitioningBy(m -> servers.get(m.memberId()).isLeader()));
    final RaftMember leader = collect.get(true).get(0);
    final RaftStorage leaderStorage = storages.get(leader.memberId());
    final RaftMember slave = collect.get(false).get(0);
    final RaftStorage slaveStorage = storages.get(slave.memberId());
    // shutdown client + primitive
    primitive.close().thenCompose(nothing -> client.close()).thenRun(this::resume);
    await(30000);
    // shutdown other node
    final RaftMember other = collect.get(false).get(1);
    servers.get(other.memberId()).shutdown().thenRun(this::resume);
    await(30000);
    // shutdown slave and recreate from scratch
    final RaftServer slaveServer = recreateServerWithDataLoss(leader, slave, servers.get(slave.memberId()), slaveStorage);
    assertEquals(leaderStorage.openSnapshotStore().getCurrentSnapshotIndex(), slaveStorage.openSnapshotStore().getCurrentSnapshotIndex());
    // and again a second time to ensure the snapshot index of the member is reset
    recreateServerWithDataLoss(leader, slave, slaveServer, slaveStorage);
    assertEquals(leaderStorage.openSnapshotStore().getCurrentSnapshotIndex(), slaveStorage.openSnapshotStore().getCurrentSnapshotIndex());
}
Also used : RaftClusterEvent(io.atomix.protocols.raft.cluster.RaftClusterEvent) RaftMember(io.atomix.protocols.raft.cluster.RaftMember) TimeoutException(java.util.concurrent.TimeoutException) AsyncPrimitive(io.atomix.primitive.AsyncPrimitive) SessionId(io.atomix.primitive.session.SessionId) ClusterMembershipService(io.atomix.cluster.ClusterMembershipService) PrimitiveInfo(io.atomix.primitive.PrimitiveInfo) PrimitiveManagementService(io.atomix.primitive.PrimitiveManagementService) DefaultOperationId(io.atomix.primitive.operation.impl.DefaultOperationId) SessionMetadata(io.atomix.primitive.session.SessionMetadata) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) PrimitiveConfig(io.atomix.primitive.config.PrimitiveConfig) After(org.junit.After) Duration(java.time.Duration) Map(java.util.Map) Session(io.atomix.primitive.session.Session) Path(java.nio.file.Path) ConcurrentTestCase(net.jodah.concurrentunit.ConcurrentTestCase) SimpleFileVisitor(java.nio.file.SimpleFileVisitor) ProxyClient(io.atomix.primitive.proxy.ProxyClient) InitializeEntry(io.atomix.protocols.raft.storage.log.entry.InitializeEntry) PrimitiveBuilder(io.atomix.primitive.PrimitiveBuilder) PrimitiveState(io.atomix.primitive.PrimitiveState) Event(io.atomix.primitive.event.Event) Set(java.util.Set) RaftStorage(io.atomix.protocols.raft.storage.RaftStorage) Instant(java.time.Instant) CommandEntry(io.atomix.protocols.raft.storage.log.entry.CommandEntry) Collectors(java.util.stream.Collectors) Sets(com.google.common.collect.Sets) SingleThreadContext(io.atomix.utils.concurrent.SingleThreadContext) ThreadContext(io.atomix.utils.concurrent.ThreadContext) PrimitiveRegistry(io.atomix.primitive.PrimitiveRegistry) Matchers.any(org.mockito.Matchers.any) FileVisitResult(java.nio.file.FileVisitResult) List(java.util.List) PrimitiveService(io.atomix.primitive.service.PrimitiveService) ServiceConfig(io.atomix.primitive.service.ServiceConfig) KeepAliveEntry(io.atomix.protocols.raft.storage.log.entry.KeepAliveEntry) MetadataEntry(io.atomix.protocols.raft.storage.log.entry.MetadataEntry) BackupOutput(io.atomix.primitive.service.BackupOutput) RandomStringUtils(org.apache.commons.lang3.RandomStringUtils) PrimitiveException(io.atomix.primitive.PrimitiveException) Serializer(io.atomix.utils.serializer.Serializer) QueryEntry(io.atomix.protocols.raft.storage.log.entry.QueryEntry) Mockito.mock(org.mockito.Mockito.mock) BackupInput(io.atomix.primitive.service.BackupInput) IntStream(java.util.stream.IntStream) SyncPrimitive(io.atomix.primitive.SyncPrimitive) OperationType(io.atomix.primitive.operation.OperationType) CompletableFuture(java.util.concurrent.CompletableFuture) Function(java.util.function.Function) PartitionId(io.atomix.primitive.partition.PartitionId) ArrayList(java.util.ArrayList) StorageLevel(io.atomix.storage.StorageLevel) HashSet(java.util.HashSet) PrimitiveOperation(io.atomix.primitive.operation.PrimitiveOperation) Lists(com.google.common.collect.Lists) ConfigurationEntry(io.atomix.protocols.raft.storage.log.entry.ConfigurationEntry) DefaultRaftMember(io.atomix.protocols.raft.cluster.impl.DefaultRaftMember) OpenSessionEntry(io.atomix.protocols.raft.storage.log.entry.OpenSessionEntry) MemberId(io.atomix.cluster.MemberId) TestRaftProtocolFactory(io.atomix.protocols.raft.protocol.TestRaftProtocolFactory) Futures(io.atomix.utils.concurrent.Futures) Before(org.junit.Before) AbstractAsyncPrimitive(io.atomix.primitive.AbstractAsyncPrimitive) CloseSessionEntry(io.atomix.protocols.raft.storage.log.entry.CloseSessionEntry) Files(java.nio.file.Files) Assert.assertNotNull(org.junit.Assert.assertNotNull) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) IOException(java.io.IOException) Mockito.when(org.mockito.Mockito.when) BasicFileAttributes(java.nio.file.attribute.BasicFileAttributes) Command(io.atomix.primitive.operation.Command) File(java.io.File) Query(io.atomix.primitive.operation.Query) Configuration(io.atomix.protocols.raft.storage.system.Configuration) ExecutionException(java.util.concurrent.ExecutionException) TimeUnit(java.util.concurrent.TimeUnit) Consumer(java.util.function.Consumer) AtomicLong(java.util.concurrent.atomic.AtomicLong) AbstractPrimitiveService(io.atomix.primitive.service.AbstractPrimitiveService) Namespace(io.atomix.utils.serializer.Namespace) Ignore(org.junit.Ignore) Paths(java.nio.file.Paths) PrimitiveType(io.atomix.primitive.PrimitiveType) PrimitiveProtocol(io.atomix.primitive.protocol.PrimitiveProtocol) DefaultProxyClient(io.atomix.primitive.proxy.impl.DefaultProxyClient) SessionClient(io.atomix.primitive.session.SessionClient) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) RaftMember(io.atomix.protocols.raft.cluster.RaftMember) DefaultRaftMember(io.atomix.protocols.raft.cluster.impl.DefaultRaftMember) MemberId(io.atomix.cluster.MemberId) RaftStorage(io.atomix.protocols.raft.storage.RaftStorage) List(java.util.List) ArrayList(java.util.ArrayList) Map(java.util.Map) Test(org.junit.Test)

Example 18 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class RaftSessionConnection method sendRequest.

/**
 * Sends the given request attempt to the cluster.
 */
protected <T extends RaftRequest, U extends RaftResponse> void sendRequest(T request, BiFunction<MemberId, T, CompletableFuture<U>> sender, int count, CompletableFuture<U> future) {
    MemberId node = next();
    if (node != null) {
        log.trace("Sending {} to {}", request, node);
        int selectionId = this.selectionId;
        sender.apply(node, request).whenCompleteAsync((r, e) -> {
            if (e != null || r != null) {
                handleResponse(request, sender, count, selectionId, node, r, e, future);
            } else {
                future.complete(null);
            }
        }, context);
    } else {
        future.completeExceptionally(new ConnectException("Failed to connect to the cluster"));
    }
}
Also used : MemberId(io.atomix.cluster.MemberId) ConnectException(java.net.ConnectException)

Example 19 with MemberId

use of io.atomix.cluster.MemberId in project zeppelin by apache.

the class ClusterManager method start.

public void start() {
    if (!zConf.isClusterMode()) {
        return;
    }
    // RaftClient Thread
    new Thread(new Runnable() {

        @Override
        public void run() {
            LOGGER.info("RaftClientThread run() >>>");
            int raftClientPort = 0;
            try {
                raftClientPort = RemoteInterpreterUtils.findRandomAvailablePortOnAllLocalInterfaces();
            } catch (IOException e) {
                LOGGER.error(e.getMessage());
            }
            MemberId memberId = MemberId.from(zeplServerHost + ":" + raftClientPort);
            Address address = Address.from(zeplServerHost, raftClientPort);
            raftAddressMap.put(memberId, address);
            MessagingService messagingManager = NettyMessagingService.builder().withAddress(address).build().start().join();
            RaftClientProtocol protocol = new RaftClientMessagingProtocol(messagingManager, protocolSerializer, raftAddressMap::get);
            raftClient = RaftClient.builder().withMemberId(memberId).withPartitionId(PartitionId.from("partition", 1)).withProtocol(protocol).build();
            raftClient.connect(clusterMemberIds).join();
            raftSessionClient = createProxy(raftClient);
            LOGGER.info("RaftClientThread run() <<<");
        }
    }).start();
    // Cluster Meta Consume Thread
    new Thread(new Runnable() {

        @Override
        public void run() {
            try {
                while (getRunning().get()) {
                    ClusterMetaEntity metaEntity = clusterMetaQueue.peek();
                    if (null != metaEntity) {
                        // Determine whether the client is connected
                        int retry = 0;
                        while (!raftInitialized()) {
                            retry++;
                            if (0 == retry % 30) {
                                LOGGER.warn("Raft incomplete initialization! retry[{}]", retry);
                            }
                            Thread.sleep(100);
                        }
                        boolean success = false;
                        switch(metaEntity.getOperation()) {
                            case DELETE_OPERATION:
                                success = deleteClusterMeta(metaEntity);
                                break;
                            case PUT_OPERATION:
                                success = putClusterMeta(metaEntity);
                                break;
                        }
                        if (true == success) {
                            // The operation was successfully deleted
                            clusterMetaQueue.remove(metaEntity);
                            LOGGER.info("Cluster Meta Consume success! {}", metaEntity);
                        } else {
                            LOGGER.error("Cluster Meta Consume faild!");
                        }
                    } else {
                        Thread.sleep(100);
                    }
                }
            } catch (InterruptedException e) {
                LOGGER.error(e.getMessage());
            }
        }
    }).start();
}
Also used : RaftClientProtocol(io.atomix.protocols.raft.protocol.RaftClientProtocol) Address(io.atomix.utils.net.Address) InetAddress(java.net.InetAddress) IOException(java.io.IOException) MessagingService(io.atomix.cluster.messaging.MessagingService) NettyMessagingService(io.atomix.cluster.messaging.impl.NettyMessagingService) MemberId(io.atomix.cluster.MemberId) ClusterMetaEntity(org.apache.zeppelin.cluster.meta.ClusterMetaEntity) RaftClientMessagingProtocol(org.apache.zeppelin.cluster.protocol.RaftClientMessagingProtocol)

Example 20 with MemberId

use of io.atomix.cluster.MemberId in project atomix by atomix.

the class AntiEntropyMapDelegate method antiEntropyCheckLocalItems.

/**
 * Processes anti-entropy ad from peer by taking following actions: 1. If peer has an old entry, updates peer. 2. If
 * peer indicates an entry is removed and has a more recent timestamp than the local entry, update local state.
 */
private List<MapDelegateEvent<K, V>> antiEntropyCheckLocalItems(AntiEntropyAdvertisement ad) {
    final List<MapDelegateEvent<K, V>> externalEvents = Lists.newLinkedList();
    final MemberId sender = ad.sender();
    final List<MemberId> peers = ImmutableList.of(sender);
    Set<String> staleOrMissing = new HashSet<>();
    Set<String> locallyUnknown = new HashSet<>(ad.digest().keySet());
    items.forEach((key, localValue) -> {
        locallyUnknown.remove(key);
        MapValue.Digest remoteValueDigest = ad.digest().get(key);
        if (remoteValueDigest == null || localValue.isNewerThan(remoteValueDigest.timestamp())) {
            // local value is more recent, push to sender
            queueUpdate(new UpdateEntry(key, localValue), peers);
        } else if (remoteValueDigest.isNewerThan(localValue.digest()) && remoteValueDigest.isTombstone()) {
            // remote value is more recent and a tombstone: update local value
            MapValue tombstone = MapValue.tombstone(remoteValueDigest.timestamp());
            MapValue previousValue = removeInternal(key, Optional.empty(), Optional.of(tombstone));
            if (previousValue != null && previousValue.isAlive()) {
                externalEvents.add(new MapDelegateEvent<>(REMOVE, decodeKey(key), previousValue.get(this::decodeValue)));
            }
        } else if (remoteValueDigest.isNewerThan(localValue.digest())) {
            // Not a tombstone and remote is newer
            staleOrMissing.add(key);
        }
    });
    // Keys missing in local map
    staleOrMissing.addAll(locallyUnknown);
    // Request updates that we missed out on
    sendUpdateRequestToPeer(sender, staleOrMissing);
    return externalEvents;
}
Also used : MemberId(io.atomix.cluster.MemberId) MapDelegateEvent(io.atomix.primitive.protocol.map.MapDelegateEvent) HashSet(java.util.HashSet)

Aggregations

MemberId (io.atomix.cluster.MemberId)24 CompletableFuture (java.util.concurrent.CompletableFuture)10 ArrayList (java.util.ArrayList)9 List (java.util.List)7 Consumer (java.util.function.Consumer)7 Collectors (java.util.stream.Collectors)7 PrimitiveType (io.atomix.primitive.PrimitiveType)6 Futures (io.atomix.utils.concurrent.Futures)6 SessionId (io.atomix.primitive.session.SessionId)5 RaftMember (io.atomix.protocols.raft.cluster.RaftMember)5 Configuration (io.atomix.protocols.raft.storage.system.Configuration)5 Instant (java.time.Instant)5 Collections (java.util.Collections)5 Map (java.util.Map)5 TestClusterMembershipService (io.atomix.cluster.TestClusterMembershipService)4 PrimitiveBuilder (io.atomix.primitive.PrimitiveBuilder)4 PrimitiveManagementService (io.atomix.primitive.PrimitiveManagementService)4 PrimitiveConfig (io.atomix.primitive.config.PrimitiveConfig)4 PartitionId (io.atomix.primitive.partition.PartitionId)4 AbstractPrimitiveService (io.atomix.primitive.service.AbstractPrimitiveService)4