Search in sources :

Example 1 with ServerNetworkResponseMetrics

use of com.github.ambry.network.ServerNetworkResponseMetrics in project ambry by linkedin.

the class AmbryRequests method handleAdminRequest.

/**
 * Handles an administration request. These requests can query for or change the internal state of the server.
 * @param request the request that needs to be handled.
 * @throws InterruptedException if response sending is interrupted.
 * @throws IOException if there are I/O errors carrying our the required operation.
 */
private void handleAdminRequest(Request request) throws InterruptedException, IOException {
    long requestQueueTime = SystemTime.getInstance().milliseconds() - request.getStartTimeInMs();
    long totalTimeSpent = requestQueueTime;
    long startTime = SystemTime.getInstance().milliseconds();
    DataInputStream requestStream = new DataInputStream(request.getInputStream());
    AdminRequest adminRequest = AdminRequest.readFrom(requestStream, clusterMap);
    Histogram processingTimeHistogram = null;
    Histogram responseQueueTimeHistogram = null;
    Histogram responseSendTimeHistogram = null;
    Histogram requestTotalTimeHistogram = null;
    AdminResponse response = null;
    try {
        switch(adminRequest.getType()) {
            case TriggerCompaction:
                metrics.triggerCompactionRequestQueueTimeInMs.update(requestQueueTime);
                metrics.triggerCompactionRequestRate.mark();
                processingTimeHistogram = metrics.triggerCompactionResponseQueueTimeInMs;
                responseQueueTimeHistogram = metrics.triggerCompactionResponseQueueTimeInMs;
                responseSendTimeHistogram = metrics.triggerCompactionResponseSendTimeInMs;
                requestTotalTimeHistogram = metrics.triggerCompactionRequestTotalTimeInMs;
                response = handleTriggerCompactionRequest(adminRequest);
                break;
            case RequestControl:
                metrics.requestControlRequestQueueTimeInMs.update(requestQueueTime);
                metrics.requestControlRequestRate.mark();
                processingTimeHistogram = metrics.requestControlResponseQueueTimeInMs;
                responseQueueTimeHistogram = metrics.requestControlResponseQueueTimeInMs;
                responseSendTimeHistogram = metrics.requestControlResponseSendTimeInMs;
                requestTotalTimeHistogram = metrics.requestControlRequestTotalTimeInMs;
                response = handleRequestControlRequest(requestStream, adminRequest);
                break;
            case ReplicationControl:
                metrics.replicationControlRequestQueueTimeInMs.update(requestQueueTime);
                metrics.replicationControlRequestRate.mark();
                processingTimeHistogram = metrics.replicationControlResponseQueueTimeInMs;
                responseQueueTimeHistogram = metrics.replicationControlResponseQueueTimeInMs;
                responseSendTimeHistogram = metrics.replicationControlResponseSendTimeInMs;
                requestTotalTimeHistogram = metrics.replicationControlRequestTotalTimeInMs;
                response = handleReplicationControlRequest(requestStream, adminRequest);
                break;
            case CatchupStatus:
                metrics.catchupStatusRequestQueueTimeInMs.update(requestQueueTime);
                metrics.catchupStatusRequestRate.mark();
                processingTimeHistogram = metrics.catchupStatusResponseQueueTimeInMs;
                responseQueueTimeHistogram = metrics.catchupStatusResponseQueueTimeInMs;
                responseSendTimeHistogram = metrics.catchupStatusResponseSendTimeInMs;
                requestTotalTimeHistogram = metrics.catchupStatusRequestTotalTimeInMs;
                response = handleCatchupStatusRequest(requestStream, adminRequest);
                break;
            case BlobStoreControl:
                metrics.blobStoreControlRequestQueueTimeInMs.update(requestQueueTime);
                metrics.blobStoreControlRequestRate.mark();
                processingTimeHistogram = metrics.blobStoreControlRequestQueueTimeInMs;
                responseQueueTimeHistogram = metrics.blobStoreControlRequestQueueTimeInMs;
                responseSendTimeHistogram = metrics.blobStoreControlResponseSendTimeInMs;
                requestTotalTimeHistogram = metrics.blobStoreControlRequestTotalTimeInMs;
                response = handleBlobStoreControlRequest(requestStream, adminRequest);
                break;
        }
    } catch (Exception e) {
        logger.error("Unknown exception for admin request {}", adminRequest, e);
        metrics.unExpectedAdminOperationError.inc();
        response = new AdminResponse(adminRequest.getCorrelationId(), adminRequest.getClientId(), ServerErrorCode.Unknown_Error);
        switch(adminRequest.getType()) {
            case CatchupStatus:
                response = new CatchupStatusAdminResponse(false, response);
                break;
        }
    } finally {
        long processingTime = SystemTime.getInstance().milliseconds() - startTime;
        totalTimeSpent += processingTime;
        publicAccessLogger.info("{} {} processingTime {}", adminRequest, response, processingTime);
        processingTimeHistogram.update(processingTime);
    }
    requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTimeHistogram, responseSendTimeHistogram, requestTotalTimeHistogram, null, null, totalTimeSpent));
}
Also used : CatchupStatusAdminRequest(com.github.ambry.protocol.CatchupStatusAdminRequest) AdminRequest(com.github.ambry.protocol.AdminRequest) ReplicationControlAdminRequest(com.github.ambry.protocol.ReplicationControlAdminRequest) RequestControlAdminRequest(com.github.ambry.protocol.RequestControlAdminRequest) BlobStoreControlAdminRequest(com.github.ambry.protocol.BlobStoreControlAdminRequest) ServerNetworkResponseMetrics(com.github.ambry.network.ServerNetworkResponseMetrics) CatchupStatusAdminResponse(com.github.ambry.protocol.CatchupStatusAdminResponse) AdminResponse(com.github.ambry.protocol.AdminResponse) Histogram(com.codahale.metrics.Histogram) CatchupStatusAdminResponse(com.github.ambry.protocol.CatchupStatusAdminResponse) DataInputStream(java.io.DataInputStream) StoreException(com.github.ambry.store.StoreException) IOException(java.io.IOException) MessageFormatException(com.github.ambry.messageformat.MessageFormatException)

Example 2 with ServerNetworkResponseMetrics

use of com.github.ambry.network.ServerNetworkResponseMetrics in project ambry by linkedin.

the class AmbryRequests method handleReplicaMetadataRequest.

public void handleReplicaMetadataRequest(Request request) throws IOException, InterruptedException {
    ReplicaMetadataRequest replicaMetadataRequest = ReplicaMetadataRequest.readFrom(new DataInputStream(request.getInputStream()), clusterMap, findTokenFactory);
    long requestQueueTime = SystemTime.getInstance().milliseconds() - request.getStartTimeInMs();
    long totalTimeSpent = requestQueueTime;
    metrics.replicaMetadataRequestQueueTimeInMs.update(requestQueueTime);
    metrics.replicaMetadataRequestRate.mark();
    List<ReplicaMetadataRequestInfo> replicaMetadataRequestInfoList = replicaMetadataRequest.getReplicaMetadataRequestInfoList();
    int partitionCnt = replicaMetadataRequestInfoList.size();
    long startTimeInMs = SystemTime.getInstance().milliseconds();
    ReplicaMetadataResponse response = null;
    try {
        List<ReplicaMetadataResponseInfo> replicaMetadataResponseList = new ArrayList<ReplicaMetadataResponseInfo>(partitionCnt);
        for (ReplicaMetadataRequestInfo replicaMetadataRequestInfo : replicaMetadataRequestInfoList) {
            long partitionStartTimeInMs = SystemTime.getInstance().milliseconds();
            PartitionId partitionId = replicaMetadataRequestInfo.getPartitionId();
            ServerErrorCode error = validateRequest(partitionId, RequestOrResponseType.ReplicaMetadataRequest);
            logger.trace("{} Time used to validate metadata request: {}", partitionId, (SystemTime.getInstance().milliseconds() - partitionStartTimeInMs));
            if (error != ServerErrorCode.No_Error) {
                logger.error("Validating replica metadata request failed with error {} for partition {}", error, partitionId);
                ReplicaMetadataResponseInfo replicaMetadataResponseInfo = new ReplicaMetadataResponseInfo(partitionId, error);
                replicaMetadataResponseList.add(replicaMetadataResponseInfo);
            } else {
                try {
                    FindToken findToken = replicaMetadataRequestInfo.getToken();
                    String hostName = replicaMetadataRequestInfo.getHostName();
                    String replicaPath = replicaMetadataRequestInfo.getReplicaPath();
                    Store store = storageManager.getStore(partitionId);
                    partitionStartTimeInMs = SystemTime.getInstance().milliseconds();
                    FindInfo findInfo = store.findEntriesSince(findToken, replicaMetadataRequest.getMaxTotalSizeOfEntriesInBytes());
                    logger.trace("{} Time used to find entry since: {}", partitionId, (SystemTime.getInstance().milliseconds() - partitionStartTimeInMs));
                    partitionStartTimeInMs = SystemTime.getInstance().milliseconds();
                    replicationManager.updateTotalBytesReadByRemoteReplica(partitionId, hostName, replicaPath, findInfo.getFindToken().getBytesRead());
                    logger.trace("{} Time used to update total bytes read: {}", partitionId, (SystemTime.getInstance().milliseconds() - partitionStartTimeInMs));
                    partitionStartTimeInMs = SystemTime.getInstance().milliseconds();
                    long remoteReplicaLagInBytes = replicationManager.getRemoteReplicaLagFromLocalInBytes(partitionId, hostName, replicaPath);
                    logger.trace("{} Time used to get remote replica lag in bytes: {}", partitionId, (SystemTime.getInstance().milliseconds() - partitionStartTimeInMs));
                    ReplicaMetadataResponseInfo replicaMetadataResponseInfo = new ReplicaMetadataResponseInfo(partitionId, findInfo.getFindToken(), findInfo.getMessageEntries(), remoteReplicaLagInBytes);
                    replicaMetadataResponseList.add(replicaMetadataResponseInfo);
                } catch (StoreException e) {
                    logger.error("Store exception on a replica metadata request with error code " + e.getErrorCode() + " for partition " + partitionId, e);
                    if (e.getErrorCode() == StoreErrorCodes.IOError) {
                        metrics.storeIOError.inc();
                    } else {
                        metrics.unExpectedStoreFindEntriesError.inc();
                    }
                    ReplicaMetadataResponseInfo replicaMetadataResponseInfo = new ReplicaMetadataResponseInfo(partitionId, ErrorMapping.getStoreErrorMapping(e.getErrorCode()));
                    replicaMetadataResponseList.add(replicaMetadataResponseInfo);
                }
            }
        }
        response = new ReplicaMetadataResponse(replicaMetadataRequest.getCorrelationId(), replicaMetadataRequest.getClientId(), ServerErrorCode.No_Error, replicaMetadataResponseList);
    } catch (Exception e) {
        logger.error("Unknown exception for request " + replicaMetadataRequest, e);
        response = new ReplicaMetadataResponse(replicaMetadataRequest.getCorrelationId(), replicaMetadataRequest.getClientId(), ServerErrorCode.Unknown_Error);
    } finally {
        long processingTime = SystemTime.getInstance().milliseconds() - startTimeInMs;
        totalTimeSpent += processingTime;
        publicAccessLogger.info("{} {} processingTime {}", replicaMetadataRequest, response, processingTime);
        logger.trace("{} {} processingTime {}", replicaMetadataRequest, response, processingTime);
        metrics.replicaMetadataRequestProcessingTimeInMs.update(processingTime);
    }
    requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(metrics.replicaMetadataResponseQueueTimeInMs, metrics.replicaMetadataSendTimeInMs, metrics.replicaMetadataTotalTimeInMs, null, null, totalTimeSpent));
}
Also used : ServerNetworkResponseMetrics(com.github.ambry.network.ServerNetworkResponseMetrics) ReplicaMetadataResponse(com.github.ambry.protocol.ReplicaMetadataResponse) ReplicaMetadataResponseInfo(com.github.ambry.protocol.ReplicaMetadataResponseInfo) ArrayList(java.util.ArrayList) Store(com.github.ambry.store.Store) DataInputStream(java.io.DataInputStream) PartitionId(com.github.ambry.clustermap.PartitionId) ServerErrorCode(com.github.ambry.commons.ServerErrorCode) StoreException(com.github.ambry.store.StoreException) IOException(java.io.IOException) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) StoreException(com.github.ambry.store.StoreException) ReplicaMetadataRequest(com.github.ambry.protocol.ReplicaMetadataRequest) ReplicaMetadataRequestInfo(com.github.ambry.protocol.ReplicaMetadataRequestInfo) FindToken(com.github.ambry.store.FindToken) FindInfo(com.github.ambry.store.FindInfo)

Example 3 with ServerNetworkResponseMetrics

use of com.github.ambry.network.ServerNetworkResponseMetrics in project ambry by linkedin.

the class AmbryRequests method sendGetResponse.

private void sendGetResponse(RequestResponseChannel requestResponseChannel, GetResponse response, Request request, Histogram responseQueueTime, Histogram responseSendTime, Histogram requestTotalTime, long totalTimeSpent, long blobSize, MessageFormatFlags flags, ServerMetrics metrics) throws InterruptedException {
    if (blobSize <= ServerMetrics.smallBlob) {
        if (flags == MessageFormatFlags.Blob || flags == MessageFormatFlags.All) {
            if (response.getError() == ServerErrorCode.No_Error) {
                metrics.markGetBlobRequestRateBySize(blobSize);
                requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, metrics.getSmallBlobSendTimeInMs, metrics.getSmallBlobTotalTimeInMs, totalTimeSpent));
            } else {
                requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, null, null, totalTimeSpent));
            }
        } else {
            requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, null, null, totalTimeSpent));
        }
    } else if (blobSize <= ServerMetrics.mediumBlob) {
        if (flags == MessageFormatFlags.Blob || flags == MessageFormatFlags.All) {
            if (response.getError() == ServerErrorCode.No_Error) {
                metrics.markGetBlobRequestRateBySize(blobSize);
                requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, metrics.getMediumBlobSendTimeInMs, metrics.getMediumBlobTotalTimeInMs, totalTimeSpent));
            } else {
                requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, null, null, totalTimeSpent));
            }
        } else {
            requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, null, null, totalTimeSpent));
        }
    } else {
        if (flags == MessageFormatFlags.Blob || flags == MessageFormatFlags.All) {
            if (response.getError() == ServerErrorCode.No_Error) {
                metrics.markGetBlobRequestRateBySize(blobSize);
                requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, metrics.getLargeBlobSendTimeInMs, metrics.getLargeBlobTotalTimeInMs, totalTimeSpent));
            } else {
                requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, null, null, totalTimeSpent));
            }
        } else {
            requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(responseQueueTime, responseSendTime, requestTotalTime, null, null, totalTimeSpent));
        }
    }
}
Also used : ServerNetworkResponseMetrics(com.github.ambry.network.ServerNetworkResponseMetrics)

Example 4 with ServerNetworkResponseMetrics

use of com.github.ambry.network.ServerNetworkResponseMetrics in project ambry by linkedin.

the class AmbryRequests method handleUndeleteRequest.

@Override
public void handleUndeleteRequest(NetworkRequest request) throws IOException, InterruptedException {
    UndeleteRequest undeleteRequest;
    if (request instanceof LocalChannelRequest) {
        // This is a case where handleUndeleteRequest is called when frontends are talking to Azure. In this case, this method
        // is called by request handler threads running within the frontend router itself. So, the request can be directly
        // referenced as java objects without any need for deserialization.
        undeleteRequest = (UndeleteRequest) ((LocalChannelRequest) request).getRequestInfo().getRequest();
    } else {
        undeleteRequest = UndeleteRequest.readFrom(new DataInputStream(request.getInputStream()), clusterMap);
    }
    long requestQueueTime = SystemTime.getInstance().milliseconds() - request.getStartTimeInMs();
    long totalTimeSpent = requestQueueTime;
    metrics.undeleteBlobRequestQueueTimeInMs.update(requestQueueTime);
    metrics.undeleteBlobRequestRate.mark();
    long startTime = SystemTime.getInstance().milliseconds();
    UndeleteResponse response = null;
    Store storeToUndelete;
    StoreKey convertedStoreKey;
    try {
        convertedStoreKey = getConvertedStoreKeys(Collections.singletonList(undeleteRequest.getBlobId())).get(0);
        ServerErrorCode error = validateRequest(undeleteRequest.getBlobId().getPartition(), RequestOrResponseType.UndeleteRequest, false);
        if (error != ServerErrorCode.No_Error) {
            logger.error("Validating undelete request failed with error {} for request {}", error, undeleteRequest);
            response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), error);
        } else {
            BlobId convertedBlobId = (BlobId) convertedStoreKey;
            MessageInfo info = new MessageInfo.Builder(convertedBlobId, -1, convertedBlobId.getAccountId(), convertedBlobId.getContainerId(), undeleteRequest.getOperationTimeMs()).isUndeleted(true).lifeVersion(MessageInfo.LIFE_VERSION_FROM_FRONTEND).build();
            storeToUndelete = storeManager.getStore(undeleteRequest.getBlobId().getPartition());
            short lifeVersion = storeToUndelete.undelete(info);
            response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), lifeVersion);
            if (notification != null) {
                notification.onBlobReplicaUndeleted(currentNode.getHostname(), currentNode.getPort(), convertedStoreKey.getID(), BlobReplicaSourceType.PRIMARY);
            }
        }
    } catch (StoreException e) {
        boolean logInErrorLevel = false;
        if (e.getErrorCode() == StoreErrorCodes.ID_Not_Found) {
            metrics.idNotFoundError.inc();
        } else if (e.getErrorCode() == StoreErrorCodes.TTL_Expired) {
            metrics.ttlExpiredError.inc();
        } else if (e.getErrorCode() == StoreErrorCodes.ID_Deleted_Permanently) {
            metrics.idDeletedError.inc();
        } else if (e.getErrorCode() == StoreErrorCodes.Life_Version_Conflict) {
            metrics.lifeVersionConflictError.inc();
        } else if (e.getErrorCode() == StoreErrorCodes.ID_Not_Deleted) {
            metrics.idNotDeletedError.inc();
        } else if (e.getErrorCode() == StoreErrorCodes.ID_Undeleted) {
            metrics.idUndeletedError.inc();
        } else if (e.getErrorCode() == StoreErrorCodes.Authorization_Failure) {
            metrics.undeleteAuthorizationFailure.inc();
        } else {
            logInErrorLevel = true;
            metrics.unExpectedStoreUndeleteError.inc();
        }
        if (logInErrorLevel) {
            logger.error("Store exception on a undelete with error code {} for request {}", e.getErrorCode(), undeleteRequest, e);
        } else {
            logger.trace("Store exception on a undelete with error code {} for request {}", e.getErrorCode(), undeleteRequest, e);
        }
        if (e.getErrorCode() == StoreErrorCodes.ID_Undeleted) {
            if (e instanceof IdUndeletedStoreException) {
                response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), ((IdUndeletedStoreException) e).getLifeVersion(), ServerErrorCode.Blob_Already_Undeleted);
            } else {
                response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), MessageInfo.LIFE_VERSION_FROM_FRONTEND, ServerErrorCode.Blob_Already_Undeleted);
            }
        } else {
            response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), ErrorMapping.getStoreErrorMapping(e.getErrorCode()));
        }
    } catch (Exception e) {
        logger.error("Unknown exception for undelete request {}", undeleteRequest, e);
        response = new UndeleteResponse(undeleteRequest.getCorrelationId(), undeleteRequest.getClientId(), ServerErrorCode.Unknown_Error);
        metrics.unExpectedStoreUndeleteError.inc();
    } finally {
        long processingTime = SystemTime.getInstance().milliseconds() - startTime;
        totalTimeSpent += processingTime;
        publicAccessLogger.info("{} {} processingTime {}", undeleteRequest, response, processingTime);
        metrics.undeleteBlobProcessingTimeInMs.update(processingTime);
    }
    requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(metrics.undeleteBlobResponseQueueTimeInMs, metrics.undeleteBlobSendTimeInMs, metrics.undeleteBlobTotalTimeInMs, null, null, totalTimeSpent));
}
Also used : ServerNetworkResponseMetrics(com.github.ambry.network.ServerNetworkResponseMetrics) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) Store(com.github.ambry.store.Store) DataInputStream(java.io.DataInputStream) StoreKey(com.github.ambry.store.StoreKey) ServerErrorCode(com.github.ambry.server.ServerErrorCode) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) StoreException(com.github.ambry.store.StoreException) IOException(java.io.IOException) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) MessageInfo(com.github.ambry.store.MessageInfo) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) StoreException(com.github.ambry.store.StoreException) LocalChannelRequest(com.github.ambry.network.LocalRequestResponseChannel.LocalChannelRequest) BlobId(com.github.ambry.commons.BlobId)

Example 5 with ServerNetworkResponseMetrics

use of com.github.ambry.network.ServerNetworkResponseMetrics in project ambry by linkedin.

the class AmbryRequests method handleReplicaMetadataRequest.

@Override
public void handleReplicaMetadataRequest(NetworkRequest request) throws IOException, InterruptedException {
    if (replicationEngine == null) {
        throw new UnsupportedOperationException("Replication not supported on this node.");
    }
    ReplicaMetadataRequest replicaMetadataRequest = ReplicaMetadataRequest.readFrom(new DataInputStream(request.getInputStream()), clusterMap, findTokenHelper);
    long requestQueueTime = SystemTime.getInstance().milliseconds() - request.getStartTimeInMs();
    long totalTimeSpent = requestQueueTime;
    metrics.replicaMetadataRequestQueueTimeInMs.update(requestQueueTime);
    metrics.replicaMetadataRequestRate.mark();
    List<ReplicaMetadataRequestInfo> replicaMetadataRequestInfoList = replicaMetadataRequest.getReplicaMetadataRequestInfoList();
    int partitionCnt = replicaMetadataRequestInfoList.size();
    long startTimeInMs = SystemTime.getInstance().milliseconds();
    ReplicaMetadataResponse response = null;
    try {
        List<ReplicaMetadataResponseInfo> replicaMetadataResponseList = new ArrayList<>(partitionCnt);
        for (ReplicaMetadataRequestInfo replicaMetadataRequestInfo : replicaMetadataRequestInfoList) {
            long partitionStartTimeInMs = SystemTime.getInstance().milliseconds();
            PartitionId partitionId = replicaMetadataRequestInfo.getPartitionId();
            ReplicaType replicaType = replicaMetadataRequestInfo.getReplicaType();
            ServerErrorCode error = validateRequest(partitionId, RequestOrResponseType.ReplicaMetadataRequest, false);
            logger.trace("{} Time used to validate metadata request: {}", partitionId, (SystemTime.getInstance().milliseconds() - partitionStartTimeInMs));
            if (error != ServerErrorCode.No_Error) {
                logger.error("Validating replica metadata request failed with error {} for partition {}", error, partitionId);
                ReplicaMetadataResponseInfo replicaMetadataResponseInfo = new ReplicaMetadataResponseInfo(partitionId, replicaType, error, ReplicaMetadataResponse.getCompatibleResponseVersion(replicaMetadataRequest.getVersionId()));
                replicaMetadataResponseList.add(replicaMetadataResponseInfo);
            } else {
                try {
                    FindToken findToken = replicaMetadataRequestInfo.getToken();
                    String hostName = replicaMetadataRequestInfo.getHostName();
                    String replicaPath = replicaMetadataRequestInfo.getReplicaPath();
                    Store store = storeManager.getStore(partitionId);
                    partitionStartTimeInMs = SystemTime.getInstance().milliseconds();
                    FindInfo findInfo = store.findEntriesSince(findToken, replicaMetadataRequest.getMaxTotalSizeOfEntriesInBytes(), hostName, replicaPath);
                    logger.trace("{} Time used to find entry since: {}", partitionId, (SystemTime.getInstance().milliseconds() - partitionStartTimeInMs));
                    partitionStartTimeInMs = SystemTime.getInstance().milliseconds();
                    long totalBytesRead = findInfo.getFindToken().getBytesRead();
                    replicationEngine.updateTotalBytesReadByRemoteReplica(partitionId, hostName, replicaPath, totalBytesRead);
                    logger.trace("{} Time used to update total bytes read: {}", partitionId, (SystemTime.getInstance().milliseconds() - partitionStartTimeInMs));
                    partitionStartTimeInMs = SystemTime.getInstance().milliseconds();
                    logger.trace("{} Time used to get remote replica lag in bytes: {}", partitionId, (SystemTime.getInstance().milliseconds() - partitionStartTimeInMs));
                    ReplicaMetadataResponseInfo replicaMetadataResponseInfo = new ReplicaMetadataResponseInfo(partitionId, replicaType, findInfo.getFindToken(), findInfo.getMessageEntries(), getRemoteReplicaLag(store, totalBytesRead), ReplicaMetadataResponse.getCompatibleResponseVersion(replicaMetadataRequest.getVersionId()));
                    if (replicaMetadataResponseInfo.getTotalSizeOfAllMessages() > 5 * replicaMetadataRequest.getMaxTotalSizeOfEntriesInBytes()) {
                        logger.debug("{} generated a metadata response {} where the cumulative size of messages is {}", replicaMetadataRequest, replicaMetadataResponseInfo, replicaMetadataResponseInfo.getTotalSizeOfAllMessages());
                        metrics.replicationResponseMessageSizeTooHigh.inc();
                    }
                    replicaMetadataResponseList.add(replicaMetadataResponseInfo);
                    metrics.replicaMetadataTotalSizeOfMessages.update(replicaMetadataResponseInfo.getTotalSizeOfAllMessages());
                } catch (StoreException e) {
                    logger.error("Store exception on a replica metadata request with error code {} for partition {}", e.getErrorCode(), partitionId, e);
                    if (e.getErrorCode() == StoreErrorCodes.IOError) {
                        metrics.storeIOError.inc();
                    } else {
                        metrics.unExpectedStoreFindEntriesError.inc();
                    }
                    ReplicaMetadataResponseInfo replicaMetadataResponseInfo = new ReplicaMetadataResponseInfo(partitionId, replicaType, ErrorMapping.getStoreErrorMapping(e.getErrorCode()), ReplicaMetadataResponse.getCompatibleResponseVersion(replicaMetadataRequest.getVersionId()));
                    replicaMetadataResponseList.add(replicaMetadataResponseInfo);
                }
            }
        }
        response = new ReplicaMetadataResponse(replicaMetadataRequest.getCorrelationId(), replicaMetadataRequest.getClientId(), ServerErrorCode.No_Error, replicaMetadataResponseList, ReplicaMetadataResponse.getCompatibleResponseVersion(replicaMetadataRequest.getVersionId()));
    } catch (Exception e) {
        logger.error("Unknown exception for request {}", replicaMetadataRequest, e);
        response = new ReplicaMetadataResponse(replicaMetadataRequest.getCorrelationId(), replicaMetadataRequest.getClientId(), ServerErrorCode.Unknown_Error, ReplicaMetadataResponse.getCompatibleResponseVersion(replicaMetadataRequest.getVersionId()));
    } finally {
        long processingTime = SystemTime.getInstance().milliseconds() - startTimeInMs;
        totalTimeSpent += processingTime;
        publicAccessLogger.info("{} {} processingTime {}", replicaMetadataRequest, response, processingTime);
        logger.trace("{} {} processingTime {}", replicaMetadataRequest, response, processingTime);
        metrics.replicaMetadataRequestProcessingTimeInMs.update(processingTime);
        // client id now has dc name at the end, for example: ClientId=replication-metadata-abc.example.com[dc1]
        String[] clientStrs = replicaMetadataRequest.getClientId().split("\\[");
        if (clientStrs.length > 1) {
            String clientDc = clientStrs[1].substring(0, clientStrs[1].length() - 1);
            if (!currentNode.getDatacenterName().equals(clientDc)) {
                metrics.updateCrossColoMetadataExchangeBytesRate(clientDc, response != null ? response.sizeInBytes() : 0L);
            }
        }
    }
    requestResponseChannel.sendResponse(response, request, new ServerNetworkResponseMetrics(metrics.replicaMetadataResponseQueueTimeInMs, metrics.replicaMetadataSendTimeInMs, metrics.replicaMetadataTotalTimeInMs, null, null, totalTimeSpent));
}
Also used : ServerNetworkResponseMetrics(com.github.ambry.network.ServerNetworkResponseMetrics) ArrayList(java.util.ArrayList) Store(com.github.ambry.store.Store) DataInputStream(java.io.DataInputStream) PartitionId(com.github.ambry.clustermap.PartitionId) ServerErrorCode(com.github.ambry.server.ServerErrorCode) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) StoreException(com.github.ambry.store.StoreException) IOException(java.io.IOException) MessageFormatException(com.github.ambry.messageformat.MessageFormatException) IdUndeletedStoreException(com.github.ambry.store.IdUndeletedStoreException) StoreException(com.github.ambry.store.StoreException) ReplicaType(com.github.ambry.clustermap.ReplicaType) FindToken(com.github.ambry.replication.FindToken) FindInfo(com.github.ambry.store.FindInfo)

Aggregations

ServerNetworkResponseMetrics (com.github.ambry.network.ServerNetworkResponseMetrics)10 StoreException (com.github.ambry.store.StoreException)8 DataInputStream (java.io.DataInputStream)8 IOException (java.io.IOException)8 MessageFormatException (com.github.ambry.messageformat.MessageFormatException)7 Store (com.github.ambry.store.Store)6 ServerErrorCode (com.github.ambry.server.ServerErrorCode)4 IdUndeletedStoreException (com.github.ambry.store.IdUndeletedStoreException)4 MessageInfo (com.github.ambry.store.MessageInfo)4 BlobId (com.github.ambry.commons.BlobId)3 LocalChannelRequest (com.github.ambry.network.LocalRequestResponseChannel.LocalChannelRequest)3 ArrayList (java.util.ArrayList)3 Histogram (com.codahale.metrics.Histogram)2 PartitionId (com.github.ambry.clustermap.PartitionId)2 ServerErrorCode (com.github.ambry.commons.ServerErrorCode)2 AdminRequest (com.github.ambry.protocol.AdminRequest)2 AdminResponse (com.github.ambry.protocol.AdminResponse)2 BlobStoreControlAdminRequest (com.github.ambry.protocol.BlobStoreControlAdminRequest)2 CatchupStatusAdminRequest (com.github.ambry.protocol.CatchupStatusAdminRequest)2 CatchupStatusAdminResponse (com.github.ambry.protocol.CatchupStatusAdminResponse)2