Search in sources :

Example 11 with BlockMeta

use of alluxio.worker.block.meta.BlockMeta in project alluxio by Alluxio.

the class TieredBlockStore method removeBlockInternal.

/**
   * Removes a block.
   *
   * @param sessionId session Id
   * @param blockId block Id
   * @param location the source location of the block
   * @throws InvalidWorkerStateException if the block to remove is a temp block
   * @throws BlockDoesNotExistException if this block can not be found
   * @throws IOException if I/O errors occur when removing this block file
   */
private void removeBlockInternal(long sessionId, long blockId, BlockStoreLocation location) throws InvalidWorkerStateException, BlockDoesNotExistException, IOException {
    long lockId = mLockManager.lockBlock(sessionId, blockId, BlockLockType.WRITE);
    try {
        String filePath;
        BlockMeta blockMeta;
        try (LockResource r = new LockResource(mMetadataReadLock)) {
            if (mMetaManager.hasTempBlockMeta(blockId)) {
                throw new InvalidWorkerStateException(ExceptionMessage.REMOVE_UNCOMMITTED_BLOCK, blockId);
            }
            blockMeta = mMetaManager.getBlockMeta(blockId);
            filePath = blockMeta.getPath();
        }
        if (!blockMeta.getBlockLocation().belongsTo(location)) {
            throw new BlockDoesNotExistException(ExceptionMessage.BLOCK_NOT_FOUND_AT_LOCATION, blockId, location);
        }
        // Heavy IO is guarded by block lock but not metadata lock. This may throw IOException.
        Files.delete(Paths.get(filePath));
        try (LockResource r = new LockResource(mMetadataWriteLock)) {
            mMetaManager.removeBlockMeta(blockMeta);
        } catch (BlockDoesNotExistException e) {
            // we shall never reach here
            throw Throwables.propagate(e);
        }
    } finally {
        mLockManager.unlockBlock(lockId);
    }
}
Also used : LockResource(alluxio.resource.LockResource) BlockMeta(alluxio.worker.block.meta.BlockMeta) TempBlockMeta(alluxio.worker.block.meta.TempBlockMeta) BlockDoesNotExistException(alluxio.exception.BlockDoesNotExistException) InvalidWorkerStateException(alluxio.exception.InvalidWorkerStateException)

Example 12 with BlockMeta

use of alluxio.worker.block.meta.BlockMeta 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)

Example 13 with BlockMeta

use of alluxio.worker.block.meta.BlockMeta in project alluxio by Alluxio.

the class BlockMetadataManager method commitTempBlockMeta.

/**
   * Commits a temp block.
   *
   * @param tempBlockMeta the metadata of the temp block to commit
   * @throws WorkerOutOfSpaceException when no more space left to hold the block
   * @throws BlockAlreadyExistsException when the block already exists in committed blocks
   * @throws BlockDoesNotExistException when temp block can not be found
   */
public void commitTempBlockMeta(TempBlockMeta tempBlockMeta) throws WorkerOutOfSpaceException, BlockAlreadyExistsException, BlockDoesNotExistException {
    long blockId = tempBlockMeta.getBlockId();
    if (hasBlockMeta(blockId)) {
        BlockMeta blockMeta = getBlockMeta(blockId);
        throw new BlockAlreadyExistsException(ExceptionMessage.ADD_EXISTING_BLOCK.getMessage(blockId, blockMeta.getBlockLocation().tierAlias()));
    }
    BlockMeta block = new BlockMeta(Preconditions.checkNotNull(tempBlockMeta));
    StorageDir dir = tempBlockMeta.getParentDir();
    dir.removeTempBlockMeta(tempBlockMeta);
    dir.addBlockMeta(block);
}
Also used : BlockAlreadyExistsException(alluxio.exception.BlockAlreadyExistsException) StorageDir(alluxio.worker.block.meta.StorageDir) AbstractBlockMeta(alluxio.worker.block.meta.AbstractBlockMeta) BlockMeta(alluxio.worker.block.meta.BlockMeta) TempBlockMeta(alluxio.worker.block.meta.TempBlockMeta)

Example 14 with BlockMeta

use of alluxio.worker.block.meta.BlockMeta in project alluxio by Alluxio.

the class BlockMetadataManager method moveBlockMeta.

/**
   * Moves the metadata of an existing block to another location or throws IOExceptions. Throws an
   * {@link IllegalArgumentException} if the newLocation is not in the tiered storage.
   *
   * @param blockMeta the metadata of the block to move
   * @param newLocation new location of the block
   * @return the new block metadata if success, absent otherwise
   * @throws BlockDoesNotExistException when the block to move is not found
   * @throws BlockAlreadyExistsException when the block to move already exists in the destination
   * @throws WorkerOutOfSpaceException when destination have no extra space to hold the block to
   *         move
   * @deprecated As of version 0.8. Use {@link #moveBlockMeta(BlockMeta, TempBlockMeta)} instead.
   */
@Deprecated
public BlockMeta moveBlockMeta(BlockMeta blockMeta, BlockStoreLocation newLocation) throws BlockDoesNotExistException, BlockAlreadyExistsException, WorkerOutOfSpaceException {
    // If existing location belongs to the target location, simply return the current block meta.
    BlockStoreLocation oldLocation = blockMeta.getBlockLocation();
    if (oldLocation.belongsTo(newLocation)) {
        LOG.info("moveBlockMeta: moving {} to {} is a noop", oldLocation, newLocation);
        return blockMeta;
    }
    long blockSize = blockMeta.getBlockSize();
    String newTierAlias = newLocation.tierAlias();
    StorageTier newTier = getTier(newTierAlias);
    StorageDir newDir = null;
    if (newLocation.equals(BlockStoreLocation.anyDirInTier(newTierAlias))) {
        for (StorageDir dir : newTier.getStorageDirs()) {
            if (dir.getAvailableBytes() >= blockSize) {
                newDir = dir;
                break;
            }
        }
    } else {
        StorageDir dir = newTier.getDir(newLocation.dir());
        if (dir.getAvailableBytes() >= blockSize) {
            newDir = dir;
        }
    }
    if (newDir == null) {
        throw new WorkerOutOfSpaceException("Failed to move BlockMeta: newLocation " + newLocation + " does not have enough space for " + blockSize + " bytes");
    }
    StorageDir oldDir = blockMeta.getParentDir();
    oldDir.removeBlockMeta(blockMeta);
    BlockMeta newBlockMeta = new BlockMeta(blockMeta.getBlockId(), blockSize, newDir);
    newDir.addBlockMeta(newBlockMeta);
    return newBlockMeta;
}
Also used : StorageTier(alluxio.worker.block.meta.StorageTier) StorageDir(alluxio.worker.block.meta.StorageDir) WorkerOutOfSpaceException(alluxio.exception.WorkerOutOfSpaceException) AbstractBlockMeta(alluxio.worker.block.meta.AbstractBlockMeta) BlockMeta(alluxio.worker.block.meta.BlockMeta) TempBlockMeta(alluxio.worker.block.meta.TempBlockMeta)

Example 15 with BlockMeta

use of alluxio.worker.block.meta.BlockMeta in project alluxio by Alluxio.

the class GreedyEvictor method freeSpaceWithView.

@Override
public EvictionPlan freeSpaceWithView(long availableBytes, BlockStoreLocation location, BlockMetadataManagerView view) {
    Preconditions.checkNotNull(location);
    Preconditions.checkNotNull(view);
    // 1. Select a StorageDirView that has enough capacity for required bytes.
    StorageDirView selectedDirView = null;
    if (location.equals(BlockStoreLocation.anyTier())) {
        selectedDirView = selectEvictableDirFromAnyTier(view, availableBytes);
    } else {
        String tierAlias = location.tierAlias();
        StorageTierView tierView = view.getTierView(tierAlias);
        if (location.equals(BlockStoreLocation.anyDirInTier(tierAlias))) {
            selectedDirView = selectEvictableDirFromTier(tierView, availableBytes);
        } else {
            int dirIndex = location.dir();
            StorageDirView dir = tierView.getDirView(dirIndex);
            if (canEvictBlocksFromDir(dir, availableBytes)) {
                selectedDirView = dir;
            }
        }
    }
    if (selectedDirView == null) {
        LOG.error("Failed to freeSpace: No StorageDirView has enough capacity of {} bytes", availableBytes);
        return null;
    }
    // 2. Check if the selected StorageDirView already has enough space.
    List<BlockTransferInfo> toTransfer = new ArrayList<>();
    List<Pair<Long, BlockStoreLocation>> toEvict = new ArrayList<>();
    long bytesAvailableInDir = selectedDirView.getAvailableBytes();
    if (bytesAvailableInDir >= availableBytes) {
        // No need to evict anything, return an eviction plan with empty instructions.
        return new EvictionPlan(toTransfer, toEvict);
    }
    // 3. Collect victim blocks from the selected StorageDirView. They could either be evicted or
    // moved.
    List<BlockMeta> victimBlocks = new ArrayList<>();
    for (BlockMeta block : selectedDirView.getEvictableBlocks()) {
        victimBlocks.add(block);
        bytesAvailableInDir += block.getBlockSize();
        if (bytesAvailableInDir >= availableBytes) {
            break;
        }
    }
    // 4. Make best effort to transfer victim blocks to lower tiers rather than evict them.
    Map<StorageDirView, Long> pendingBytesInDir = new HashMap<>();
    for (BlockMeta block : victimBlocks) {
        // TODO(qifan): Should avoid calling getParentDir.
        String fromTierAlias = block.getParentDir().getParentTier().getTierAlias();
        List<StorageTierView> candidateTiers = view.getTierViewsBelow(fromTierAlias);
        StorageDirView dstDir = selectAvailableDir(block, candidateTiers, pendingBytesInDir);
        if (dstDir == null) {
            // Not possible to transfer
            toEvict.add(new Pair<>(block.getBlockId(), block.getBlockLocation()));
        } else {
            StorageTierView dstTier = dstDir.getParentTierView();
            toTransfer.add(new BlockTransferInfo(block.getBlockId(), block.getBlockLocation(), new BlockStoreLocation(dstTier.getTierViewAlias(), dstDir.getDirViewIndex())));
            if (pendingBytesInDir.containsKey(dstDir)) {
                pendingBytesInDir.put(dstDir, pendingBytesInDir.get(dstDir) + block.getBlockSize());
            } else {
                pendingBytesInDir.put(dstDir, block.getBlockSize());
            }
        }
    }
    return new EvictionPlan(toTransfer, toEvict);
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) StorageDirView(alluxio.worker.block.meta.StorageDirView) StorageTierView(alluxio.worker.block.meta.StorageTierView) BlockMeta(alluxio.worker.block.meta.BlockMeta) BlockStoreLocation(alluxio.worker.block.BlockStoreLocation) Pair(alluxio.collections.Pair)

Aggregations

BlockMeta (alluxio.worker.block.meta.BlockMeta)29 TempBlockMeta (alluxio.worker.block.meta.TempBlockMeta)20 StorageDir (alluxio.worker.block.meta.StorageDir)16 Test (org.junit.Test)16 BlockDoesNotExistException (alluxio.exception.BlockDoesNotExistException)6 PrepareForTest (org.powermock.core.classloader.annotations.PrepareForTest)6 BlockAlreadyExistsException (alluxio.exception.BlockAlreadyExistsException)4 StorageTierView (alluxio.worker.block.meta.StorageTierView)4 HashMap (java.util.HashMap)4 InvalidWorkerStateException (alluxio.exception.InvalidWorkerStateException)3 AbstractBlockMeta (alluxio.worker.block.meta.AbstractBlockMeta)3 StorageDirView (alluxio.worker.block.meta.StorageDirView)3 StorageTier (alluxio.worker.block.meta.StorageTier)3 ArrayList (java.util.ArrayList)3 Pair (alluxio.collections.Pair)2 WorkerOutOfSpaceException (alluxio.exception.WorkerOutOfSpaceException)2 LockResource (alluxio.resource.LockResource)2 FileInfo (alluxio.wire.FileInfo)2 BlockStoreLocation (alluxio.worker.block.BlockStoreLocation)2 BlockReader (alluxio.worker.block.io.BlockReader)2