Search in sources :

Example 1 with LSMComponentProperties

use of org.apache.asterix.replication.storage.LSMComponentProperties in project asterixdb by apache.

the class ReplicationManager method processJob.

/**
     * Processes the replication job based on its specifications
     *
     * @param job
     *            The replication job
     * @param replicasSockets
     *            The remote replicas sockets to send the request to.
     * @param requestBuffer
     *            The buffer to use to send the request.
     * @throws IOException
     */
private void processJob(IReplicationJob job, Map<String, SocketChannel> replicasSockets, ByteBuffer requestBuffer) throws IOException {
    try {
        //all of the job's files belong to a single storage partition.
        //get any of them to determine the partition from the file path.
        String jobFile = job.getJobFiles().iterator().next();
        IndexFileProperties indexFileRef = localResourceRepo.getIndexFileRef(jobFile);
        if (!replicationStrategy.isMatch(indexFileRef.getDatasetId())) {
            return;
        }
        int jobPartitionId = indexFileRef.getPartitionId();
        ByteBuffer responseBuffer = null;
        LSMIndexFileProperties asterixFileProperties = new LSMIndexFileProperties();
        if (requestBuffer == null) {
            requestBuffer = ByteBuffer.allocate(INITIAL_BUFFER_SIZE);
        }
        boolean isLSMComponentFile = job.getJobType() == ReplicationJobType.LSM_COMPONENT;
        try {
            //if there isn't already a connection, establish a new one
            if (replicasSockets == null) {
                replicasSockets = getActiveRemoteReplicasSockets();
            }
            int remainingFiles = job.getJobFiles().size();
            if (job.getOperation() == ReplicationOperation.REPLICATE) {
                //if the replication job is an LSM_COMPONENT, its properties are sent first, then its files.
                ILSMIndexReplicationJob LSMComponentJob = null;
                if (job.getJobType() == ReplicationJobType.LSM_COMPONENT) {
                    //send LSMComponent properties
                    LSMComponentJob = (ILSMIndexReplicationJob) job;
                    LSMComponentProperties lsmCompProp = new LSMComponentProperties(LSMComponentJob, nodeId);
                    requestBuffer = ReplicationProtocol.writeLSMComponentPropertiesRequest(lsmCompProp, requestBuffer);
                    sendRequest(replicasSockets, requestBuffer);
                }
                for (String filePath : job.getJobFiles()) {
                    remainingFiles--;
                    Path path = Paths.get(filePath);
                    if (Files.notExists(path)) {
                        LOGGER.log(Level.SEVERE, "File deleted before replication: " + filePath);
                        continue;
                    }
                    LOGGER.log(Level.INFO, "Replicating file: " + filePath);
                    //open file for reading
                    try (RandomAccessFile fromFile = new RandomAccessFile(filePath, "r");
                        FileChannel fileChannel = fromFile.getChannel()) {
                        long fileSize = fileChannel.size();
                        if (LSMComponentJob != null) {
                            /**
                                 * since this is LSM_COMPONENT REPLICATE job, the job will contain
                                 * only the component being replicated.
                                 */
                            ILSMDiskComponent diskComponent = LSMComponentJob.getLSMIndexOperationContext().getComponentsToBeReplicated().get(0);
                            long lsnOffset = LSMIndexUtil.getComponentFileLSNOffset(LSMComponentJob.getLSMIndex(), diskComponent, filePath);
                            asterixFileProperties.initialize(filePath, fileSize, nodeId, isLSMComponentFile, lsnOffset, remainingFiles == 0);
                        } else {
                            asterixFileProperties.initialize(filePath, fileSize, nodeId, isLSMComponentFile, -1L, remainingFiles == 0);
                        }
                        requestBuffer = ReplicationProtocol.writeFileReplicationRequest(requestBuffer, asterixFileProperties, ReplicationRequestType.REPLICATE_FILE);
                        Iterator<Map.Entry<String, SocketChannel>> iterator = replicasSockets.entrySet().iterator();
                        while (iterator.hasNext()) {
                            Map.Entry<String, SocketChannel> entry = iterator.next();
                            //if the remote replica is not interested in this partition, skip it.
                            if (!replica2PartitionsMap.get(entry.getKey()).contains(jobPartitionId)) {
                                continue;
                            }
                            SocketChannel socketChannel = entry.getValue();
                            //transfer request header & file
                            try {
                                NetworkingUtil.transferBufferToChannel(socketChannel, requestBuffer);
                                NetworkingUtil.sendFile(fileChannel, socketChannel);
                                if (asterixFileProperties.requiresAck()) {
                                    ReplicationRequestType responseType = waitForResponse(socketChannel, responseBuffer);
                                    if (responseType != ReplicationRequestType.ACK) {
                                        throw new IOException("Could not receive ACK from replica " + entry.getKey());
                                    }
                                }
                            } catch (IOException e) {
                                handleReplicationFailure(socketChannel, e);
                                iterator.remove();
                            } finally {
                                requestBuffer.position(0);
                            }
                        }
                    }
                }
            } else if (job.getOperation() == ReplicationOperation.DELETE) {
                for (String filePath : job.getJobFiles()) {
                    remainingFiles--;
                    asterixFileProperties.initialize(filePath, -1, nodeId, isLSMComponentFile, -1L, remainingFiles == 0);
                    ReplicationProtocol.writeFileReplicationRequest(requestBuffer, asterixFileProperties, ReplicationRequestType.DELETE_FILE);
                    Iterator<Map.Entry<String, SocketChannel>> iterator = replicasSockets.entrySet().iterator();
                    while (iterator.hasNext()) {
                        Map.Entry<String, SocketChannel> entry = iterator.next();
                        //if the remote replica is not interested in this partition, skip it.
                        if (!replica2PartitionsMap.get(entry.getKey()).contains(jobPartitionId)) {
                            continue;
                        }
                        SocketChannel socketChannel = entry.getValue();
                        try {
                            sendRequest(replicasSockets, requestBuffer);
                            if (asterixFileProperties.requiresAck()) {
                                waitForResponse(socketChannel, responseBuffer);
                            }
                        } catch (IOException e) {
                            handleReplicationFailure(socketChannel, e);
                            iterator.remove();
                        } finally {
                            requestBuffer.position(0);
                        }
                    }
                }
            }
        } finally {
            //if sync, close sockets with replicas since they wont be reused
            if (job.getExecutionType() == ReplicationExecutionType.SYNC) {
                closeReplicaSockets(replicasSockets);
            }
        }
    } finally {
        exitReplicatedLSMComponent(job);
    }
}
Also used : Path(java.nio.file.Path) SocketChannel(java.nio.channels.SocketChannel) LSMComponentProperties(org.apache.asterix.replication.storage.LSMComponentProperties) FileChannel(java.nio.channels.FileChannel) IOException(java.io.IOException) ILSMIndexReplicationJob(org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexReplicationJob) ByteBuffer(java.nio.ByteBuffer) ILSMDiskComponent(org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent) Entry(java.util.Map.Entry) RandomAccessFile(java.io.RandomAccessFile) LSMIndexFileProperties(org.apache.asterix.replication.storage.LSMIndexFileProperties) IndexFileProperties(org.apache.asterix.common.storage.IndexFileProperties) ReplicationRequestType(org.apache.asterix.replication.functions.ReplicationProtocol.ReplicationRequestType) LSMIndexFileProperties(org.apache.asterix.replication.storage.LSMIndexFileProperties) Iterator(java.util.Iterator) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(java.util.HashMap)

Example 2 with LSMComponentProperties

use of org.apache.asterix.replication.storage.LSMComponentProperties in project asterixdb by apache.

the class ReplicationChannel method updateLSMComponentRemainingFiles.

private void updateLSMComponentRemainingFiles(String lsmComponentId) throws IOException {
    LSMComponentProperties lsmCompProp = lsmComponentId2PropertiesMap.get(lsmComponentId);
    int remainingFile = lsmCompProp.markFileComplete();
    //clean up when all the LSM component files have been received.
    if (remainingFile == 0) {
        if (lsmCompProp.getOpType() == LSMOperationType.FLUSH && lsmCompProp.getReplicaLSN() != null && replicaUniqueLSN2RemoteMapping.containsKey(lsmCompProp.getNodeUniqueLSN())) {
            int remainingIndexes = replicaUniqueLSN2RemoteMapping.get(lsmCompProp.getNodeUniqueLSN()).numOfFlushedIndexes.decrementAndGet();
            if (remainingIndexes == 0) {
                /**
                     * Note: there is a chance that this will never be removed because some
                     * index in the dataset was not flushed because it is empty. This could
                     * be solved by passing only the number of successfully flushed indexes.
                     */
                replicaUniqueLSN2RemoteMapping.remove(lsmCompProp.getNodeUniqueLSN());
            }
        }
        //delete mask to indicate that this component is now valid.
        replicaResourcesManager.markLSMComponentReplicaAsValid(lsmCompProp);
        lsmComponentId2PropertiesMap.remove(lsmComponentId);
        LOGGER.log(Level.INFO, "Completed LSMComponent " + lsmComponentId + " Replication.");
    }
}
Also used : LSMComponentProperties(org.apache.asterix.replication.storage.LSMComponentProperties)

Aggregations

LSMComponentProperties (org.apache.asterix.replication.storage.LSMComponentProperties)2 IOException (java.io.IOException)1 RandomAccessFile (java.io.RandomAccessFile)1 ByteBuffer (java.nio.ByteBuffer)1 FileChannel (java.nio.channels.FileChannel)1 SocketChannel (java.nio.channels.SocketChannel)1 Path (java.nio.file.Path)1 HashMap (java.util.HashMap)1 Iterator (java.util.Iterator)1 Map (java.util.Map)1 Entry (java.util.Map.Entry)1 ConcurrentHashMap (java.util.concurrent.ConcurrentHashMap)1 IndexFileProperties (org.apache.asterix.common.storage.IndexFileProperties)1 ReplicationRequestType (org.apache.asterix.replication.functions.ReplicationProtocol.ReplicationRequestType)1 LSMIndexFileProperties (org.apache.asterix.replication.storage.LSMIndexFileProperties)1 ILSMDiskComponent (org.apache.hyracks.storage.am.lsm.common.api.ILSMDiskComponent)1 ILSMIndexReplicationJob (org.apache.hyracks.storage.am.lsm.common.api.ILSMIndexReplicationJob)1