use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class BufferedJournalApplier method resume.
/**
* Resumes the applier. This method will apply all buffered entries before returning.
*
* @throws IOException
*/
public void resume() throws IOException {
try (LockResource stateLock = new LockResource(mStateLock)) {
Preconditions.checkState(mSuspended, "Not suspended");
Preconditions.checkState(!mResumeInProgress, "Resume in progress");
mResumeInProgress = true;
LOG.info("Resuming state machine from sequence: {}", mLastAppliedSequence);
}
cancelCatchup();
/**
* Applies all buffered entries.
*
* It doesn't block state until
* -> buffer contains few elements ( RESUME_LOCK_BUFFER_SIZE_WATERMARK )
* -> was running for a long time ( RESUME_LOCK_TIME_LIMIT_MS )
*/
try {
// Mark resume start time.
long resumeStartTimeMs = System.currentTimeMillis();
// Lock initially if few or none elements in the queue.
if (mSuspendBuffer.size() <= RESUME_LOCK_BUFFER_SIZE_WATERMARK) {
mStateLock.lock();
}
while (!mSuspendBuffer.isEmpty()) {
applyToMaster(mSuspendBuffer.remove());
// Check whether to lock the state now.
boolean lockSubmission = !mStateLock.isHeldByCurrentThread() && (mSuspendBuffer.size() <= RESUME_LOCK_BUFFER_SIZE_WATERMARK || (System.currentTimeMillis() - resumeStartTimeMs) > RESUME_LOCK_TIME_LIMIT_MS);
if (lockSubmission) {
mStateLock.lock();
}
}
} finally {
mSuspended = false;
mResumeInProgress = false;
mCatchupThread = null;
mStateLock.unlock();
}
}
use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class BufferedJournalApplier method suspend.
/**
* Suspend the applier.
*
* After this call, journal entries will be buffered until {@link #resume()} or
* {@link #catchup(long)} is called.
*
* @throws IOException
*/
public void suspend() throws IOException {
try (LockResource stateLock = new LockResource(mStateLock)) {
Preconditions.checkState(!mSuspended, "Already suspended");
mSuspended = true;
LOG.info("Suspended state machine at sequence: {}", mLastAppliedSequence);
}
}
use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class DefaultBlockMaster method generateBlockInfo.
/**
* Generates block info, including worker locations, for a block id.
* This requires no locks on the {@link MasterWorkerInfo} because it is only reading
* final fields.
*
* @param blockId a block id
* @return optional block info, empty if the block does not exist
*/
private Optional<BlockInfo> generateBlockInfo(long blockId) throws UnavailableException {
if (mSafeModeManager.isInSafeMode()) {
throw new UnavailableException(ExceptionMessage.MASTER_IN_SAFEMODE.getMessage());
}
BlockMeta block;
List<BlockLocation> blockLocations;
try (LockResource r = lockBlock(blockId)) {
Optional<BlockMeta> blockOpt = mBlockStore.getBlock(blockId);
if (!blockOpt.isPresent()) {
return Optional.empty();
}
block = blockOpt.get();
blockLocations = new ArrayList<>(mBlockStore.getLocations(blockId));
}
// Sort the block locations by their alias ordinal in the master storage tier mapping
Collections.sort(blockLocations, Comparator.comparingInt(o -> mGlobalStorageTierAssoc.getOrdinal(o.getTier())));
List<alluxio.wire.BlockLocation> locations = new ArrayList<>();
for (BlockLocation location : blockLocations) {
MasterWorkerInfo workerInfo = mWorkers.getFirstByField(ID_INDEX, location.getWorkerId());
if (workerInfo != null) {
// worker metadata is intentionally not locked here because:
// - it would be an incorrect order (correct order is lock worker first, then block)
// - only uses getters of final variables
locations.add(new alluxio.wire.BlockLocation().setWorkerId(location.getWorkerId()).setWorkerAddress(workerInfo.getWorkerAddress()).setTierAlias(location.getTier()).setMediumType(location.getMediumType()));
}
}
return Optional.of(new BlockInfo().setBlockId(blockId).setLength(block.getLength()).setLocations(locations));
}
use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class DefaultBlockMaster method processWorkerAddedBlocks.
/**
* Updates the worker and block metadata for blocks added to a worker.
*
* You should lock externally with {@link MasterWorkerInfo#lockWorkerMeta(EnumSet, boolean)}
* with {@link WorkerMetaLockSection#BLOCKS} specified.
* An exclusive lock is required.
*
* @param workerInfo The worker metadata object
* @param addedBlockIds A mapping from storage tier alias to a list of block ids added
*/
private void processWorkerAddedBlocks(MasterWorkerInfo workerInfo, Map<BlockLocation, List<Long>> addedBlockIds) {
long invalidBlockCount = 0;
for (Map.Entry<BlockLocation, List<Long>> entry : addedBlockIds.entrySet()) {
for (long blockId : entry.getValue()) {
try (LockResource r = lockBlock(blockId)) {
Optional<BlockMeta> block = mBlockStore.getBlock(blockId);
if (block.isPresent()) {
workerInfo.addBlock(blockId);
BlockLocation location = entry.getKey();
Preconditions.checkState(location.getWorkerId() == workerInfo.getId(), "BlockLocation has a different workerId %s from the request sender's workerId %s", location.getWorkerId(), workerInfo.getId());
mBlockStore.addLocation(blockId, location);
mLostBlocks.remove(blockId);
} else {
invalidBlockCount++;
// The block is not recognized and should therefore be purged from the worker
// The file may have been removed when the worker was lost
workerInfo.scheduleRemoveFromWorker(blockId);
LOG.debug("Invalid block: {} from worker {}.", blockId, workerInfo.getWorkerAddress().getHost());
}
}
}
}
if (invalidBlockCount > 0) {
LOG.warn("{} invalid blocks found on worker {} in total", invalidBlockCount, workerInfo.getWorkerAddress().getHost());
}
}
use of alluxio.resource.LockResource in project alluxio by Alluxio.
the class DefaultBlockMaster method commitBlock.
// TODO(binfan): check the logic is correct or not when commitBlock is a retry
@Override
public void commitBlock(long workerId, long usedBytesOnTier, String tierAlias, String mediumType, long blockId, long length) throws NotFoundException, UnavailableException {
LOG.debug("Commit block from workerId: {}, usedBytesOnTier: {}, blockId: {}, length: {}", workerId, usedBytesOnTier, blockId, length);
MasterWorkerInfo worker = mWorkers.getFirstByField(ID_INDEX, workerId);
// TODO(peis): Check lost workers as well.
if (worker == null) {
throw new NotFoundException(ExceptionMessage.NO_WORKER_FOUND.getMessage(workerId));
}
try (JournalContext journalContext = createJournalContext()) {
// The worker metadata must be locked before the blocks
try (LockResource lr = worker.lockWorkerMeta(EnumSet.of(WorkerMetaLockSection.USAGE, WorkerMetaLockSection.BLOCKS), false)) {
try (LockResource r = lockBlock(blockId)) {
Optional<BlockMeta> block = mBlockStore.getBlock(blockId);
if (!block.isPresent() || block.get().getLength() != length) {
if (block.isPresent() && block.get().getLength() != Constants.UNKNOWN_SIZE) {
LOG.warn("Rejecting attempt to change block length from {} to {}", block.get().getLength(), length);
} else {
mBlockStore.putBlock(blockId, BlockMeta.newBuilder().setLength(length).build());
BlockInfoEntry blockInfo = BlockInfoEntry.newBuilder().setBlockId(blockId).setLength(length).build();
journalContext.append(JournalEntry.newBuilder().setBlockInfo(blockInfo).build());
}
}
// Update the block metadata with the new worker location.
mBlockStore.addLocation(blockId, BlockLocation.newBuilder().setWorkerId(workerId).setTier(tierAlias).setMediumType(mediumType).build());
// This worker has this block, so it is no longer lost.
mLostBlocks.remove(blockId);
// Update the worker information for this new block.
// TODO(binfan): when retry commitBlock on master is expected, make sure metrics are not
// double counted.
worker.addBlock(blockId);
worker.updateUsedBytes(tierAlias, usedBytesOnTier);
}
}
worker.updateLastUpdatedTimeMs();
}
}
Aggregations