Class AstyanaxStorageProvider

  • All Implemented Interfaces:
    MetadataProvider, StorageProvider, com.bazaarvoice.emodb.table.db.astyanax.DataCopyDAO, com.bazaarvoice.emodb.table.db.astyanax.DataPurgeDAO

    public class AstyanaxStorageProvider
    extends java.lang.Object
    implements StorageProvider, MetadataProvider, com.bazaarvoice.emodb.table.db.astyanax.DataCopyDAO, com.bazaarvoice.emodb.table.db.astyanax.DataPurgeDAO
    A single row Cassandra implementation of StorageProvider.

    Storing blobs in a single row means blobs can't be bigger than what a single Cassandra server can handle. This is unlikely to be a problem as long as it's not used to store large videos. It also means that reads of a single large blob can't be distributed across all servers in the ring but instead just N servers, where N is the replication factor.

    The storage strategy is to chunk up the blob into smallish columns where each chunk can fit easily in memory. To do this, there it uses 3 classes of columns: - A single metadata column with a StorageSummary object encoded as JSON. - N "presence" columns, one per chunk. These have no data, but are written at the same time as each chunk. A reader can quickly read the presence columns and verify that, if all presence columns exist, all the chunk columns must also exist and be available (unless a concurrent writer re-writes the blob before the chunks can be retrieved). - N chunk columns, sized so that each chunk can be transferred in a single thrift call without consuming too much memory.

    The Astyanax com.netflix.astyanax.recipes.storage.CassandraChunkedStorageProvider implementation has a few deficiencies that this avoids: - The Astyanax v1.0.1 ChunkedStorage recipe has minor bugs: it ignores its configured ConsistencyLevel, it doesn't have a way to set some ObjectMetadata attributes. - The consistency story seems weak. There's no way to test whether all chunks are available before starting to stream back the results, and as a result the algorithm relies heavily on retry to wait for replication. If the retry algorithm waits too long (seconds) it impacts the client, and if too many threads get stuck in retry loops it will DOS the BlobStore service. - If two different blobs are stored using the same IDs, we may end up with orphaned chunks that never get cleaned up. We'd have to write a M/R job that looks for them. - If a blob is overwritten with new data, there is a period of time when readers could see mixed results where part of the returned data is from the old blob and part is from the new blob.

    On the other hand, the Astyanax recipes com.netflix.astyanax.recipes.storage.ObjectReader and com.netflix.astyanax.recipes.storage.ObjectWriter are much more aggressive about retries and concurrency, so they likely have better performance than this does.

    • Constructor Summary

      Constructors 
      Constructor Description
      AstyanaxStorageProvider​(com.netflix.astyanax.model.ConsistencyLevel readConsistency, com.codahale.metrics.MetricRegistry metricRegistry)  
    • Method Summary

      All Methods Instance Methods Concrete Methods 
      Modifier and Type Method Description
      void copy​(com.bazaarvoice.emodb.table.db.astyanax.AstyanaxStorage source, com.bazaarvoice.emodb.table.db.astyanax.AstyanaxStorage dest, java.lang.Runnable progress)  
      long countMetadata​(com.bazaarvoice.emodb.table.db.Table tbl)
      Count metadata.
      void deleteMetadata​(com.bazaarvoice.emodb.table.db.Table tbl, java.lang.String blobId)
      Delete metadata.
      void deleteObject​(com.bazaarvoice.emodb.table.db.Table tbl, java.lang.String blobId)  
      long getCurrentTimestamp​(com.bazaarvoice.emodb.table.db.Table tbl)  
      int getDefaultChunkSize()  
      void purge​(com.bazaarvoice.emodb.table.db.astyanax.AstyanaxStorage storage, java.lang.Runnable progress)  
      java.nio.ByteBuffer readChunk​(com.bazaarvoice.emodb.table.db.Table tbl, java.lang.String blobId, int chunkId, long timestamp)  
      StorageSummary readMetadata​(com.bazaarvoice.emodb.table.db.Table tbl, java.lang.String blobId)
      Read metadata storage summary.
      java.util.Iterator<java.util.Map.Entry<java.lang.String,​StorageSummary>> scanMetadata​(com.bazaarvoice.emodb.table.db.Table tbl, java.lang.String fromBlobIdExclusive, com.bazaarvoice.emodb.common.api.impl.LimitCounter limit)
      Scan metadata iterator.
      void writeChunk​(com.bazaarvoice.emodb.table.db.Table tbl, java.lang.String blobId, int chunkId, java.nio.ByteBuffer data, long timestamp)  
      void writeMetadata​(com.bazaarvoice.emodb.table.db.Table tbl, java.lang.String blobId, StorageSummary summary)
      Write metadata.
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Constructor Detail

      • AstyanaxStorageProvider

        @Inject
        public AstyanaxStorageProvider​(com.netflix.astyanax.model.ConsistencyLevel readConsistency,
                                       com.codahale.metrics.MetricRegistry metricRegistry)
    • Method Detail

      • writeChunk

        public void writeChunk​(com.bazaarvoice.emodb.table.db.Table tbl,
                               java.lang.String blobId,
                               int chunkId,
                               java.nio.ByteBuffer data,
                               long timestamp)
        Specified by:
        writeChunk in interface StorageProvider
      • readChunk

        public java.nio.ByteBuffer readChunk​(com.bazaarvoice.emodb.table.db.Table tbl,
                                             java.lang.String blobId,
                                             int chunkId,
                                             long timestamp)
        Specified by:
        readChunk in interface StorageProvider
      • deleteObject

        public void deleteObject​(com.bazaarvoice.emodb.table.db.Table tbl,
                                 java.lang.String blobId)
        Specified by:
        deleteObject in interface StorageProvider
      • writeMetadata

        public void writeMetadata​(com.bazaarvoice.emodb.table.db.Table tbl,
                                  java.lang.String blobId,
                                  StorageSummary summary)
        Description copied from interface: MetadataProvider
        Write metadata.
        Specified by:
        writeMetadata in interface MetadataProvider
        Parameters:
        tbl - the table
        blobId - the blob id
        summary - the summary
      • readMetadata

        public StorageSummary readMetadata​(com.bazaarvoice.emodb.table.db.Table tbl,
                                           java.lang.String blobId)
        Description copied from interface: MetadataProvider
        Read metadata storage summary.
        Specified by:
        readMetadata in interface MetadataProvider
        Parameters:
        tbl - the table
        blobId - the blob id
        Returns:
        the storage summary
      • deleteMetadata

        public void deleteMetadata​(com.bazaarvoice.emodb.table.db.Table tbl,
                                   java.lang.String blobId)
        Description copied from interface: MetadataProvider
        Delete metadata.
        Specified by:
        deleteMetadata in interface MetadataProvider
        Parameters:
        tbl - the table
        blobId - the blob id
      • countMetadata

        public long countMetadata​(com.bazaarvoice.emodb.table.db.Table tbl)
        Description copied from interface: MetadataProvider
        Count metadata.
        Specified by:
        countMetadata in interface MetadataProvider
        Parameters:
        tbl - the table
      • scanMetadata

        public java.util.Iterator<java.util.Map.Entry<java.lang.String,​StorageSummary>> scanMetadata​(com.bazaarvoice.emodb.table.db.Table tbl,
                                                                                                           @Nullable
                                                                                                           java.lang.String fromBlobIdExclusive,
                                                                                                           com.bazaarvoice.emodb.common.api.impl.LimitCounter limit)
        Description copied from interface: MetadataProvider
        Scan metadata iterator.
        Specified by:
        scanMetadata in interface MetadataProvider
        Parameters:
        tbl - the table
        fromBlobIdExclusive - the from blob id exclusive
        limit - the limit
        Returns:
        the iterator
      • copy

        public void copy​(com.bazaarvoice.emodb.table.db.astyanax.AstyanaxStorage source,
                         com.bazaarvoice.emodb.table.db.astyanax.AstyanaxStorage dest,
                         java.lang.Runnable progress)
        Specified by:
        copy in interface com.bazaarvoice.emodb.table.db.astyanax.DataCopyDAO
      • purge

        public void purge​(com.bazaarvoice.emodb.table.db.astyanax.AstyanaxStorage storage,
                          java.lang.Runnable progress)
        Specified by:
        purge in interface com.bazaarvoice.emodb.table.db.astyanax.DataPurgeDAO