Search in sources :

Example 31 with Pair

use of voldemort.utils.Pair in project voldemort by voldemort.

the class StreamingSlopPusherJob method run.

public void run() {
    // load the metadata before each run, in case the cluster is changed
    loadMetadata();
    // don't try to run slop pusher job when rebalancing
    if (metadataStore.getServerStateUnlocked().equals(MetadataStore.VoldemortState.REBALANCING_MASTER_SERVER)) {
        logger.error("Cannot run slop pusher job since Voldemort server is rebalancing");
        return;
    }
    boolean terminatedEarly = false;
    Date startTime = new Date();
    logger.info("Started streaming slop pusher job at " + startTime);
    SlopStorageEngine slopStorageEngine = storeRepo.getSlopStore();
    ClosableIterator<Pair<ByteArray, Versioned<Slop>>> iterator = null;
    if (adminClient == null) {
        adminClient = new AdminClient(cluster, new AdminClientConfig().setMaxConnectionsPerNode(1));
    }
    if (voldemortConfig.getSlopZonesDownToTerminate() > 0) {
        // Populating the zone mapping for early termination
        zoneMapping.clear();
        for (Node n : cluster.getNodes()) {
            if (failureDetector.isAvailable(n)) {
                Set<Integer> nodes = zoneMapping.get(n.getZoneId());
                if (nodes == null) {
                    nodes = Sets.newHashSet();
                    zoneMapping.put(n.getZoneId(), nodes);
                }
                nodes.add(n.getId());
            }
        }
        // Check how many zones are down
        int zonesDown = 0;
        for (Zone zone : cluster.getZones()) {
            if (zoneMapping.get(zone.getId()) == null || zoneMapping.get(zone.getId()).size() == 0)
                zonesDown++;
        }
        // Terminate early
        if (voldemortConfig.getSlopZonesDownToTerminate() <= zoneMapping.size() && zonesDown >= voldemortConfig.getSlopZonesDownToTerminate()) {
            logger.info("Completed streaming slop pusher job at " + startTime + " early because " + zonesDown + " zones are down");
            stopAdminClient();
            return;
        }
    }
    // Clearing the statistics
    AtomicLong attemptedPushes = new AtomicLong(0);
    for (Node node : cluster.getNodes()) {
        attemptedByNode.put(node.getId(), 0L);
        succeededByNode.put(node.getId(), 0L);
    }
    Set<String> storeNames = StoreDefinitionUtils.getStoreNamesSet(metadataStore.getStoreDefList());
    acquireRepairPermit();
    try {
        StorageEngine<ByteArray, Slop, byte[]> slopStore = slopStorageEngine.asSlopStore();
        iterator = slopStore.entries();
        while (iterator.hasNext()) {
            Pair<ByteArray, Versioned<Slop>> keyAndVal;
            try {
                keyAndVal = iterator.next();
                Versioned<Slop> versioned = keyAndVal.getSecond();
                // Track the scan progress
                if (this.streamStats != null) {
                    this.streamStats.reportStreamingSlopScan();
                }
                // Retrieve the node
                int nodeId = versioned.getValue().getNodeId();
                // check for dead slops
                if (isSlopDead(cluster, storeNames, versioned.getValue())) {
                    handleDeadSlop(slopStorageEngine, keyAndVal);
                    // ignore it.
                    continue;
                }
                Node node = cluster.getNodeById(nodeId);
                attemptedPushes.incrementAndGet();
                Long attempted = attemptedByNode.get(nodeId);
                attemptedByNode.put(nodeId, attempted + 1L);
                if (attemptedPushes.get() % 10000 == 0)
                    logger.info("Attempted pushing " + attemptedPushes + " slops");
                if (logger.isTraceEnabled())
                    logger.trace("Pushing slop for " + versioned.getValue().getNodeId() + " and store  " + versioned.getValue().getStoreName() + " of key: " + versioned.getValue().getKey());
                if (failureDetector.isAvailable(node)) {
                    SynchronousQueue<Versioned<Slop>> slopQueue = slopQueues.get(nodeId);
                    if (slopQueue == null) {
                        // No previous slop queue, add one
                        slopQueue = new SynchronousQueue<Versioned<Slop>>();
                        slopQueues.put(nodeId, slopQueue);
                        consumerResults.add(consumerExecutor.submit(new SlopConsumer(nodeId, slopQueue, slopStorageEngine)));
                    }
                    boolean offered = slopQueue.offer(versioned, voldemortConfig.getClientRoutingTimeoutMs(), TimeUnit.MILLISECONDS);
                    if (!offered) {
                        if (logger.isDebugEnabled())
                            logger.debug("No consumer appeared for slop in " + voldemortConfig.getClientConnectionTimeoutMs() + " ms");
                    }
                    readThrottler.maybeThrottle(nBytesRead(keyAndVal));
                } else {
                    logger.trace(node + " declared down, won't push slop");
                }
            } catch (RejectedExecutionException e) {
                throw new VoldemortException("Ran out of threads in executor", e);
            }
        }
    } catch (InterruptedException e) {
        logger.warn("Interrupted exception", e);
        terminatedEarly = true;
    } catch (Exception e) {
        logger.error(e, e);
        terminatedEarly = true;
    } finally {
        try {
            if (iterator != null)
                iterator.close();
        } catch (Exception e) {
            logger.warn("Failed to close iterator cleanly as database might be closed", e);
        }
        // Adding the poison pill
        for (SynchronousQueue<Versioned<Slop>> slopQueue : slopQueues.values()) {
            try {
                slopQueue.put(END);
            } catch (InterruptedException e) {
                logger.warn("Error putting poison pill", e);
            }
        }
        for (Future result : consumerResults) {
            try {
                result.get();
            } catch (Exception e) {
                logger.warn("Exception in consumer", e);
            }
        }
        // Only if exception didn't take place do we update the counts
        if (!terminatedEarly) {
            Map<Integer, Long> outstanding = Maps.newHashMapWithExpectedSize(cluster.getNumberOfNodes());
            for (int nodeId : succeededByNode.keySet()) {
                logger.info("Slops to node " + nodeId + " - Succeeded - " + succeededByNode.get(nodeId) + " - Attempted - " + attemptedByNode.get(nodeId));
                outstanding.put(nodeId, attemptedByNode.get(nodeId) - succeededByNode.get(nodeId));
            }
            slopStorageEngine.resetStats(outstanding);
            logger.info("Completed streaming slop pusher job which started at " + startTime);
        } else {
            for (int nodeId : succeededByNode.keySet()) {
                logger.info("Slops to node " + nodeId + " - Succeeded - " + succeededByNode.get(nodeId) + " - Attempted - " + attemptedByNode.get(nodeId));
            }
            logger.info("Completed early streaming slop pusher job which started at " + startTime);
        }
        // Shut down admin client as not to waste connections
        consumerResults.clear();
        slopQueues.clear();
        stopAdminClient();
        this.repairPermits.release(this.getClass().getCanonicalName());
    }
}
Also used : Versioned(voldemort.versioning.Versioned) Node(voldemort.cluster.Node) VoldemortException(voldemort.VoldemortException) ByteArray(voldemort.utils.ByteArray) SlopStorageEngine(voldemort.store.slop.SlopStorageEngine) Pair(voldemort.utils.Pair) AdminClientConfig(voldemort.client.protocol.admin.AdminClientConfig) Zone(voldemort.cluster.Zone) Date(java.util.Date) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) RejectedExecutionException(java.util.concurrent.RejectedExecutionException) VoldemortException(voldemort.VoldemortException) UnreachableStoreException(voldemort.store.UnreachableStoreException) AtomicLong(java.util.concurrent.atomic.AtomicLong) AtomicLong(java.util.concurrent.atomic.AtomicLong) Future(java.util.concurrent.Future) Slop(voldemort.store.slop.Slop) AdminClient(voldemort.client.protocol.admin.AdminClient)

Example 32 with Pair

use of voldemort.utils.Pair in project voldemort by voldemort.

the class MetadataStore method initStoreDefinitions.

/**
     * Function to go through all the store definitions contained in the STORES
     * directory and
     * 
     * 1. Update metadata cache.
     * 
     * 2. Update STORES_KEY by stitching together all these keys.
     * 
     * 3. Update 'storeNames' list.
     * 
     * This method is not thread safe. It is expected that the caller of this
     * method will correctly handle concurrency issues. Currently this is not an
     * issue since its invoked by init, put, add and delete store all of which
     * use locks to deal with any concurrency related issues.
     */
private void initStoreDefinitions(Version storesXmlVersion) {
    if (this.storeDefinitionsStorageEngine == null) {
        throw new VoldemortException("The store definitions directory is empty");
    }
    String allStoreDefinitions = "<stores>";
    Version finalStoresXmlVersion = null;
    if (storesXmlVersion != null) {
        finalStoresXmlVersion = storesXmlVersion;
    }
    this.storeNames.clear();
    ClosableIterator<Pair<String, Versioned<String>>> storesIterator = this.storeDefinitionsStorageEngine.entries();
    // Some test setups may result in duplicate entries for 'store' element.
    // Do the de-dup here
    Map<String, Versioned<String>> storeNameToDefMap = new HashMap<String, Versioned<String>>();
    Version maxVersion = null;
    while (storesIterator.hasNext()) {
        Pair<String, Versioned<String>> storeDetail = storesIterator.next();
        String storeName = storeDetail.getFirst();
        Versioned<String> versionedStoreDef = storeDetail.getSecond();
        storeNameToDefMap.put(storeName, versionedStoreDef);
        Version curVersion = versionedStoreDef.getVersion();
        // Get the highest version from all the store entries
        if (maxVersion == null) {
            maxVersion = curVersion;
        } else if (maxVersion.compare(curVersion) == Occurred.BEFORE) {
            maxVersion = curVersion;
        }
    }
    // 'stores.xml' key
    if (finalStoresXmlVersion == null) {
        finalStoresXmlVersion = maxVersion;
    }
    // Go through all the individual stores and update metadata
    for (Entry<String, Versioned<String>> storeEntry : storeNameToDefMap.entrySet()) {
        String storeName = storeEntry.getKey();
        Versioned<String> versionedStoreDef = storeEntry.getValue();
        // Add all the store names to the list of storeNames
        this.storeNames.add(storeName);
        this.metadataCache.put(storeName, new Versioned<Object>(versionedStoreDef.getValue(), versionedStoreDef.getVersion()));
    }
    Collections.sort(this.storeNames);
    for (String storeName : this.storeNames) {
        Versioned<String> versionedStoreDef = storeNameToDefMap.get(storeName);
        // Stitch together to form the complete store definition list.
        allStoreDefinitions += versionedStoreDef.getValue();
    }
    allStoreDefinitions += "</stores>";
    // Update cache with the composite store definition list.
    metadataCache.put(STORES_KEY, convertStringToObject(STORES_KEY, new Versioned<String>(allStoreDefinitions, finalStoresXmlVersion)));
}
Also used : Versioned(voldemort.versioning.Versioned) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap) VoldemortException(voldemort.VoldemortException) Version(voldemort.versioning.Version) Pair(voldemort.utils.Pair)

Example 33 with Pair

use of voldemort.utils.Pair in project voldemort by voldemort.

the class AdminRebalanceTest method checkRO.

private void checkRO(Cluster cluster) {
    for (StoreDefinition storeDef : Lists.newArrayList(storeDef1, storeDef2)) {
        Map<Integer, Set<Pair<Integer, Integer>>> nodeToPartitions = ROTestUtils.getNodeIdToAllPartitions(cluster, storeDef, true);
        for (Map.Entry<Integer, Set<Pair<Integer, Integer>>> entry : nodeToPartitions.entrySet()) {
            int nodeId = entry.getKey();
            Set<Pair<Integer, Integer>> buckets = entry.getValue();
            assertEquals(servers[nodeId].getMetadataStore().getCluster(), cluster);
            ReadOnlyStorageEngine engine = (ReadOnlyStorageEngine) servers[nodeId].getStoreRepository().getStorageEngine(storeDef.getName());
            HashMap<Object, Integer> storeBuckets = engine.getChunkedFileSet().getChunkIdToNumChunks();
            for (Pair<Integer, Integer> bucket : buckets) {
                if (bucket.getFirst() < storeDef.getReplicationFactor())
                    assertEquals(storeBuckets.containsKey(Pair.create(bucket.getSecond(), bucket.getFirst())), true);
            }
        }
    }
}
Also used : Set(java.util.Set) ReadOnlyStorageEngine(voldemort.store.readonly.ReadOnlyStorageEngine) StoreDefinition(voldemort.store.StoreDefinition) Map(java.util.Map) HashMap(java.util.HashMap) Pair(voldemort.utils.Pair)

Example 34 with Pair

use of voldemort.utils.Pair in project voldemort by voldemort.

the class BaseStreamingClient method commitToVoldemort.

/**
     * Flush the network buffer and write all entries to the serve. then wait
     * for an ack from the server. This is a blocking call. It is invoked on
     * every Commit batch size of entries, It is also called on the close
     * session call
     * 
     * @param storeNamesToCommit List of stores to be flushed and committed
     * 
     */
@SuppressWarnings({ "unchecked", "rawtypes", "unused" })
private void commitToVoldemort(List<String> storeNamesToCommit) {
    if (logger.isDebugEnabled()) {
        logger.debug("Trying to commit to Voldemort");
    }
    boolean hasError = false;
    if (nodesToStream == null || nodesToStream.size() == 0) {
        if (logger.isDebugEnabled()) {
            logger.debug("No nodes to stream to. Returning.");
        }
        return;
    }
    for (Node node : nodesToStream) {
        for (String store : storeNamesToCommit) {
            if (!nodeIdStoreInitialized.get(new Pair(store, node.getId())))
                continue;
            nodeIdStoreInitialized.put(new Pair(store, node.getId()), false);
            DataOutputStream outputStream = nodeIdStoreToOutputStreamRequest.get(new Pair(store, node.getId()));
            try {
                ProtoUtils.writeEndOfStream(outputStream);
                outputStream.flush();
                DataInputStream inputStream = nodeIdStoreToInputStreamRequest.get(new Pair(store, node.getId()));
                VAdminProto.UpdatePartitionEntriesResponse.Builder updateResponse = ProtoUtils.readToBuilder(inputStream, VAdminProto.UpdatePartitionEntriesResponse.newBuilder());
                if (updateResponse.hasError()) {
                    hasError = true;
                }
            } catch (IOException e) {
                logger.error("Exception during commit", e);
                hasError = true;
                if (!faultyNodes.contains(node.getId()))
                    faultyNodes.add(node.getId());
            }
        }
    }
    if (streamingresults == null) {
        logger.warn("StreamingSession may not have been initialized since Variable streamingresults is null. Skipping callback ");
        return;
    }
    // remove redundant callbacks
    if (hasError) {
        logger.info("Invoking the Recovery Callback");
        Future future = streamingresults.submit(recoveryCallback);
        try {
            future.get();
        } catch (InterruptedException e1) {
            MARKED_BAD = true;
            logger.error("Recovery Callback failed", e1);
            throw new VoldemortException("Recovery Callback failed");
        } catch (ExecutionException e1) {
            MARKED_BAD = true;
            logger.error("Recovery Callback failed during execution", e1);
            throw new VoldemortException("Recovery Callback failed during execution");
        }
    } else {
        if (logger.isDebugEnabled()) {
            logger.debug("Commit successful");
            logger.debug("calling checkpoint callback");
        }
        Future future = streamingresults.submit(checkpointCallback);
        try {
            future.get();
        } catch (InterruptedException e1) {
            logger.warn("Checkpoint callback failed!", e1);
        } catch (ExecutionException e1) {
            logger.warn("Checkpoint callback failed during execution!", e1);
        }
    }
}
Also used : DataOutputStream(java.io.DataOutputStream) Node(voldemort.cluster.Node) IOException(java.io.IOException) DataInputStream(java.io.DataInputStream) VoldemortException(voldemort.VoldemortException) Future(java.util.concurrent.Future) ExecutionException(java.util.concurrent.ExecutionException) Pair(voldemort.utils.Pair)

Example 35 with Pair

use of voldemort.utils.Pair in project voldemort by voldemort.

the class BaseStreamingClient method cleanupSessions.

/**
     * Helper method to Close all open socket connections and checkin back to
     * the pool
     * 
     * @param storeNamesToCleanUp List of stores to be cleanedup from the current
     *        streaming session
     */
@SuppressWarnings({ "rawtypes", "unchecked" })
private void cleanupSessions(List<String> storeNamesToCleanUp) {
    logger.info("Performing cleanup");
    for (String store : storeNamesToCleanUp) {
        for (Node node : nodesToStream) {
            try {
                SocketAndStreams sands = nodeIdStoreToSocketAndStreams.get(new Pair(store, node.getId()));
                close(sands.getSocket());
                SocketDestination destination = nodeIdStoreToSocketRequest.get(new Pair(store, node.getId()));
                streamingSocketPool.checkin(destination, sands);
            } catch (Exception ioE) {
                logger.error(ioE);
            }
        }
    }
    cleanedUp = true;
}
Also used : SocketDestination(voldemort.store.socket.SocketDestination) Node(voldemort.cluster.Node) InsufficientOperationalNodesException(voldemort.store.InsufficientOperationalNodesException) VoldemortException(voldemort.VoldemortException) IOException(java.io.IOException) ExecutionException(java.util.concurrent.ExecutionException) Pair(voldemort.utils.Pair)

Aggregations

Pair (voldemort.utils.Pair)45 ByteArray (voldemort.utils.ByteArray)28 Versioned (voldemort.versioning.Versioned)25 VoldemortException (voldemort.VoldemortException)15 Node (voldemort.cluster.Node)15 IOException (java.io.IOException)14 StoreDefinition (voldemort.store.StoreDefinition)13 Test (org.junit.Test)11 File (java.io.File)10 VectorClock (voldemort.versioning.VectorClock)10 ArrayList (java.util.ArrayList)8 HashMap (java.util.HashMap)8 RoutingStrategyFactory (voldemort.routing.RoutingStrategyFactory)7 Cluster (voldemort.cluster.Cluster)6 DataOutputStream (java.io.DataOutputStream)5 FileNotFoundException (java.io.FileNotFoundException)5 Map (java.util.Map)5 ExecutionException (java.util.concurrent.ExecutionException)5 VoldemortFilter (voldemort.client.protocol.VoldemortFilter)5 DataInputStream (java.io.DataInputStream)4