Search in sources :

Example 1 with WorkerOutOfSpaceException

use of alluxio.exception.WorkerOutOfSpaceException in project alluxio by Alluxio.

the class UnderFileSystemBlockReader method updateBlockWriter.

/**
   * Updates the block writer given an offset to read. If the offset is beyond the current
   * position of the block writer, the block writer will be aborted.
   *
   * @param offset the read offset
   */
private void updateBlockWriter(long offset) throws IOException {
    try {
        if (mBlockWriter != null && offset > mBlockWriter.getPosition()) {
            mBlockWriter.close();
            mBlockWriter = null;
            mLocalBlockStore.abortBlock(mBlockMeta.getSessionId(), mBlockMeta.getBlockId());
        }
    } catch (BlockDoesNotExistException e) {
        // This can only happen when the session is expired.
        LOG.warn("Block {} does not exist when being aborted.", mBlockMeta.getBlockId());
    } catch (BlockAlreadyExistsException | InvalidWorkerStateException | IOException e) {
        // reader does not commit the block if it fails to abort the block.
        throw CommonUtils.castToIOException(e);
    }
    try {
        if (mBlockWriter == null && offset == 0 && !mNoCache) {
            BlockStoreLocation loc = BlockStoreLocation.anyDirInTier(mStorageTierAssoc.getAlias(0));
            String blockPath = mLocalBlockStore.createBlock(mBlockMeta.getSessionId(), mBlockMeta.getBlockId(), loc, mInitialBlockSize).getPath();
            mBlockWriter = new LocalFileBlockWriter(blockPath);
        }
    } catch (IOException | BlockAlreadyExistsException | WorkerOutOfSpaceException e) {
        // This can happen when there are concurrent UFS readers who are all trying to cache to block.
        LOG.debug("Failed to update block writer for UFS block [blockId: {}, ufsPath: {}, offset: {}]", mBlockMeta.getBlockId(), mBlockMeta.getUnderFileSystemPath(), offset, e);
        mBlockWriter = null;
    }
}
Also used : LocalFileBlockWriter(alluxio.worker.block.io.LocalFileBlockWriter) BlockAlreadyExistsException(alluxio.exception.BlockAlreadyExistsException) IOException(java.io.IOException) BlockDoesNotExistException(alluxio.exception.BlockDoesNotExistException) WorkerOutOfSpaceException(alluxio.exception.WorkerOutOfSpaceException) InvalidWorkerStateException(alluxio.exception.InvalidWorkerStateException)

Example 2 with WorkerOutOfSpaceException

use of alluxio.exception.WorkerOutOfSpaceException in project alluxio by Alluxio.

the class TieredBlockStore method createBlockMetaInternal.

/**
   * Creates a temp block meta only if allocator finds available space. This method will not trigger
   * any eviction.
   *
   * @param sessionId session Id
   * @param blockId block Id
   * @param location location to create the block
   * @param initialBlockSize initial block size in bytes
   * @param newBlock true if this temp block is created for a new block
   * @return a temp block created if successful, or null if allocation failed (instead of throwing
   *         {@link WorkerOutOfSpaceException} because allocation failure could be an expected case)
   * @throws BlockAlreadyExistsException if there is already a block with the same block id
   */
private TempBlockMeta createBlockMetaInternal(long sessionId, long blockId, BlockStoreLocation location, long initialBlockSize, boolean newBlock) throws BlockAlreadyExistsException {
    // block lock here since no sharing
    try (LockResource r = new LockResource(mMetadataWriteLock)) {
        if (newBlock) {
            checkTempBlockIdAvailable(blockId);
        }
        StorageDirView dirView = mAllocator.allocateBlockWithView(sessionId, initialBlockSize, location, getUpdatedView());
        if (dirView == null) {
            // Allocator fails to find a proper place for this new block.
            return null;
        }
        // TODO(carson): Add tempBlock to corresponding storageDir and remove the use of
        // StorageDirView.createTempBlockMeta.
        TempBlockMeta tempBlock = dirView.createTempBlockMeta(sessionId, blockId, initialBlockSize);
        try {
            // Add allocated temp block to metadata manager. This should never fail if allocator
            // correctly assigns a StorageDir.
            mMetaManager.addTempBlockMeta(tempBlock);
        } catch (WorkerOutOfSpaceException | BlockAlreadyExistsException e) {
            // If we reach here, allocator is not working properly
            LOG.error("Unexpected failure: {} bytes allocated at {} by allocator, " + "but addTempBlockMeta failed", initialBlockSize, location);
            throw Throwables.propagate(e);
        }
        return tempBlock;
    }
}
Also used : BlockAlreadyExistsException(alluxio.exception.BlockAlreadyExistsException) LockResource(alluxio.resource.LockResource) StorageDirView(alluxio.worker.block.meta.StorageDirView) TempBlockMeta(alluxio.worker.block.meta.TempBlockMeta) WorkerOutOfSpaceException(alluxio.exception.WorkerOutOfSpaceException)

Example 3 with WorkerOutOfSpaceException

use of alluxio.exception.WorkerOutOfSpaceException in project alluxio by Alluxio.

the class TieredBlockStore method freeSpaceInternal.

/**
   * Tries to get an eviction plan to free a certain amount of space in the given location, and
   * carries out this plan with the best effort.
   *
   * @param sessionId the session Id
   * @param availableBytes amount of space in bytes to free
   * @param location location of space
   * @throws WorkerOutOfSpaceException if it is impossible to achieve the free requirement
   * @throws IOException if I/O errors occur when removing or moving block files
   */
private void freeSpaceInternal(long sessionId, long availableBytes, BlockStoreLocation location) throws WorkerOutOfSpaceException, IOException {
    EvictionPlan plan;
    try (LockResource r = new LockResource(mMetadataReadLock)) {
        plan = mEvictor.freeSpaceWithView(availableBytes, location, getUpdatedView());
        // Absent plan means failed to evict enough space.
        if (plan == null) {
            throw new WorkerOutOfSpaceException(ExceptionMessage.NO_EVICTION_PLAN_TO_FREE_SPACE);
        }
    }
    // 1. remove blocks to make room.
    for (Pair<Long, BlockStoreLocation> blockInfo : plan.toEvict()) {
        try {
            removeBlockInternal(sessionId, blockInfo.getFirst(), blockInfo.getSecond());
        } catch (InvalidWorkerStateException e) {
            // Evictor is not working properly
            LOG.error("Failed to evict blockId {}, this is temp block", blockInfo.getFirst());
            continue;
        } catch (BlockDoesNotExistException e) {
            LOG.info("Failed to evict blockId {}, it could be already deleted", blockInfo.getFirst());
            continue;
        }
        synchronized (mBlockStoreEventListeners) {
            for (BlockStoreEventListener listener : mBlockStoreEventListeners) {
                listener.onRemoveBlockByWorker(sessionId, blockInfo.getFirst());
            }
        }
    }
    // 2. transfer blocks among tiers.
    // 2.1. group blocks move plan by the destination tier.
    Map<String, Set<BlockTransferInfo>> blocksGroupedByDestTier = new HashMap<>();
    for (BlockTransferInfo entry : plan.toMove()) {
        String alias = entry.getDstLocation().tierAlias();
        if (!blocksGroupedByDestTier.containsKey(alias)) {
            blocksGroupedByDestTier.put(alias, new HashSet<BlockTransferInfo>());
        }
        blocksGroupedByDestTier.get(alias).add(entry);
    }
    // 2.2. move blocks in the order of their dst tiers, from bottom to top
    for (int tierOrdinal = mStorageTierAssoc.size() - 1; tierOrdinal >= 0; --tierOrdinal) {
        Set<BlockTransferInfo> toMove = blocksGroupedByDestTier.get(mStorageTierAssoc.getAlias(tierOrdinal));
        if (toMove == null) {
            toMove = new HashSet<>();
        }
        for (BlockTransferInfo entry : toMove) {
            long blockId = entry.getBlockId();
            BlockStoreLocation oldLocation = entry.getSrcLocation();
            BlockStoreLocation newLocation = entry.getDstLocation();
            MoveBlockResult moveResult;
            try {
                moveResult = moveBlockInternal(sessionId, blockId, oldLocation, newLocation);
            } catch (InvalidWorkerStateException e) {
                // Evictor is not working properly
                LOG.error("Failed to evict blockId {}, this is temp block", blockId);
                continue;
            } catch (BlockAlreadyExistsException e) {
                continue;
            } catch (BlockDoesNotExistException e) {
                LOG.info("Failed to move blockId {}, it could be already deleted", blockId);
                continue;
            }
            if (moveResult.getSuccess()) {
                synchronized (mBlockStoreEventListeners) {
                    for (BlockStoreEventListener listener : mBlockStoreEventListeners) {
                        listener.onMoveBlockByWorker(sessionId, blockId, moveResult.getSrcLocation(), newLocation);
                    }
                }
            }
        }
    }
}
Also used : HashSet(java.util.HashSet) Set(java.util.Set) HashMap(java.util.HashMap) BlockTransferInfo(alluxio.worker.block.evictor.BlockTransferInfo) WorkerOutOfSpaceException(alluxio.exception.WorkerOutOfSpaceException) BlockAlreadyExistsException(alluxio.exception.BlockAlreadyExistsException) LockResource(alluxio.resource.LockResource) BlockDoesNotExistException(alluxio.exception.BlockDoesNotExistException) EvictionPlan(alluxio.worker.block.evictor.EvictionPlan) InvalidWorkerStateException(alluxio.exception.InvalidWorkerStateException)

Example 4 with WorkerOutOfSpaceException

use of alluxio.exception.WorkerOutOfSpaceException in project alluxio by Alluxio.

the class TieredBlockStore method commitBlockInternal.

/**
   * Commits a temp block.
   *
   * @param sessionId the id of session
   * @param blockId the id of block
   * @return destination location to move the block
   * @throws BlockDoesNotExistException if block id can not be found in temporary blocks
   * @throws BlockAlreadyExistsException if block id already exists in committed blocks
   * @throws InvalidWorkerStateException if block id is not owned by session id
   * @throws IOException if I/O errors occur when deleting the block file
   */
private BlockStoreLocation commitBlockInternal(long sessionId, long blockId) throws BlockAlreadyExistsException, InvalidWorkerStateException, BlockDoesNotExistException, IOException {
    long lockId = mLockManager.lockBlock(sessionId, blockId, BlockLockType.WRITE);
    try {
        // When committing TempBlockMeta, the final BlockMeta calculates the block size according to
        // the actual file size of this TempBlockMeta. Therefore, commitTempBlockMeta must happen
        // after moving actual block file to its committed path.
        BlockStoreLocation loc;
        String srcPath;
        String dstPath;
        TempBlockMeta tempBlockMeta;
        try (LockResource r = new LockResource(mMetadataReadLock)) {
            checkTempBlockOwnedBySession(sessionId, blockId);
            tempBlockMeta = mMetaManager.getTempBlockMeta(blockId);
            srcPath = tempBlockMeta.getPath();
            dstPath = tempBlockMeta.getCommitPath();
            loc = tempBlockMeta.getBlockLocation();
        }
        // Heavy IO is guarded by block lock but not metadata lock. This may throw IOException.
        FileUtils.move(srcPath, dstPath);
        try (LockResource r = new LockResource(mMetadataWriteLock)) {
            mMetaManager.commitTempBlockMeta(tempBlockMeta);
        } catch (BlockAlreadyExistsException | BlockDoesNotExistException | WorkerOutOfSpaceException e) {
            // we shall never reach here
            throw Throwables.propagate(e);
        }
        return loc;
    } finally {
        mLockManager.unlockBlock(lockId);
    }
}
Also used : BlockAlreadyExistsException(alluxio.exception.BlockAlreadyExistsException) LockResource(alluxio.resource.LockResource) TempBlockMeta(alluxio.worker.block.meta.TempBlockMeta) BlockDoesNotExistException(alluxio.exception.BlockDoesNotExistException) WorkerOutOfSpaceException(alluxio.exception.WorkerOutOfSpaceException)

Example 5 with WorkerOutOfSpaceException

use of alluxio.exception.WorkerOutOfSpaceException in project alluxio by Alluxio.

the class TieredBlockStore method moveBlockInternal.

/**
   * Moves a block to new location only if allocator finds available space in newLocation. This
   * method will not trigger any eviction. Returns {@link MoveBlockResult}.
   *
   * @param sessionId session Id
   * @param blockId block Id
   * @param oldLocation the source location of the block
   * @param newLocation new location to move this block
   * @return the resulting information about the move operation
   * @throws BlockDoesNotExistException if block is not found
   * @throws BlockAlreadyExistsException if a block with same Id already exists in new location
   * @throws InvalidWorkerStateException if the block to move is a temp block
   * @throws IOException if I/O errors occur when moving block file
   */
private MoveBlockResult moveBlockInternal(long sessionId, long blockId, BlockStoreLocation oldLocation, BlockStoreLocation newLocation) throws BlockDoesNotExistException, BlockAlreadyExistsException, InvalidWorkerStateException, IOException {
    long lockId = mLockManager.lockBlock(sessionId, blockId, BlockLockType.WRITE);
    try {
        long blockSize;
        String srcFilePath;
        String dstFilePath;
        BlockMeta srcBlockMeta;
        BlockStoreLocation srcLocation;
        BlockStoreLocation dstLocation;
        try (LockResource r = new LockResource(mMetadataReadLock)) {
            if (mMetaManager.hasTempBlockMeta(blockId)) {
                throw new InvalidWorkerStateException(ExceptionMessage.MOVE_UNCOMMITTED_BLOCK, blockId);
            }
            srcBlockMeta = mMetaManager.getBlockMeta(blockId);
            srcLocation = srcBlockMeta.getBlockLocation();
            srcFilePath = srcBlockMeta.getPath();
            blockSize = srcBlockMeta.getBlockSize();
        }
        if (!srcLocation.belongsTo(oldLocation)) {
            throw new BlockDoesNotExistException(ExceptionMessage.BLOCK_NOT_FOUND_AT_LOCATION, blockId, oldLocation);
        }
        TempBlockMeta dstTempBlock = createBlockMetaInternal(sessionId, blockId, newLocation, blockSize, false);
        if (dstTempBlock == null) {
            return new MoveBlockResult(false, blockSize, null, null);
        }
        // When `newLocation` is some specific location, the `newLocation` and the `dstLocation` are
        // just the same; while for `newLocation` with a wildcard significance, the `dstLocation`
        // is a specific one with specific tier and dir which belongs to newLocation.
        dstLocation = dstTempBlock.getBlockLocation();
        // internally from the newLocation and return success with specific block location.
        if (dstLocation.belongsTo(srcLocation)) {
            mMetaManager.abortTempBlockMeta(dstTempBlock);
            return new MoveBlockResult(true, blockSize, srcLocation, dstLocation);
        }
        dstFilePath = dstTempBlock.getCommitPath();
        // Heavy IO is guarded by block lock but not metadata lock. This may throw IOException.
        FileUtils.move(srcFilePath, dstFilePath);
        try (LockResource r = new LockResource(mMetadataWriteLock)) {
            // If this metadata update fails, we panic for now.
            // TODO(bin): Implement rollback scheme to recover from IO failures.
            mMetaManager.moveBlockMeta(srcBlockMeta, dstTempBlock);
        } catch (BlockAlreadyExistsException | BlockDoesNotExistException | WorkerOutOfSpaceException e) {
            // we shall never reach here
            throw Throwables.propagate(e);
        }
        return new MoveBlockResult(true, blockSize, srcLocation, dstLocation);
    } finally {
        mLockManager.unlockBlock(lockId);
    }
}
Also used : BlockAlreadyExistsException(alluxio.exception.BlockAlreadyExistsException) LockResource(alluxio.resource.LockResource) TempBlockMeta(alluxio.worker.block.meta.TempBlockMeta) BlockMeta(alluxio.worker.block.meta.BlockMeta) TempBlockMeta(alluxio.worker.block.meta.TempBlockMeta) BlockDoesNotExistException(alluxio.exception.BlockDoesNotExistException) WorkerOutOfSpaceException(alluxio.exception.WorkerOutOfSpaceException) InvalidWorkerStateException(alluxio.exception.InvalidWorkerStateException)

Aggregations

WorkerOutOfSpaceException (alluxio.exception.WorkerOutOfSpaceException)6 BlockAlreadyExistsException (alluxio.exception.BlockAlreadyExistsException)5 BlockDoesNotExistException (alluxio.exception.BlockDoesNotExistException)4 LockResource (alluxio.resource.LockResource)4 TempBlockMeta (alluxio.worker.block.meta.TempBlockMeta)4 InvalidWorkerStateException (alluxio.exception.InvalidWorkerStateException)3 BlockMeta (alluxio.worker.block.meta.BlockMeta)2 BlockTransferInfo (alluxio.worker.block.evictor.BlockTransferInfo)1 EvictionPlan (alluxio.worker.block.evictor.EvictionPlan)1 LocalFileBlockWriter (alluxio.worker.block.io.LocalFileBlockWriter)1 AbstractBlockMeta (alluxio.worker.block.meta.AbstractBlockMeta)1 StorageDir (alluxio.worker.block.meta.StorageDir)1 StorageDirView (alluxio.worker.block.meta.StorageDirView)1 StorageTier (alluxio.worker.block.meta.StorageTier)1 IOException (java.io.IOException)1 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Set (java.util.Set)1