Search in sources :

Example 6 with StoreTransaction

use of org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction in project janusgraph by JanusGraph.

the class ConsistentKeyIDAuthority method getIDBlock.

@Override
public synchronized IDBlock getIDBlock(final int partition, final int idNamespace, Duration timeout) throws BackendException {
    Preconditions.checkArgument(partition >= 0 && partition < (1 << partitionBitWidth), "Invalid partition id [%s] for bit width [%s]", partition, partitionBitWidth);
    // can be any non-negative value
    Preconditions.checkArgument(idNamespace >= 0);
    final Timer methodTime = times.getTimer().start();
    final long blockSize = getBlockSize(idNamespace);
    final long idUpperBound = getIdUpperBound(idNamespace);
    final int maxAvailableBits = (VariableLong.unsignedBitLength(idUpperBound) - 1) - uniqueIdBitWidth;
    Preconditions.checkArgument(maxAvailableBits > 0, "Unique id bit width [%s] is too wide for id-namespace [%s] id bound [%s]", uniqueIdBitWidth, idNamespace, idUpperBound);
    final long idBlockUpperBound = (1L << maxAvailableBits);
    final List<Integer> exhaustedUniquePIDs = new ArrayList<>(randomUniqueIDLimit);
    Duration backoffMS = idApplicationWaitMS;
    Preconditions.checkArgument(idBlockUpperBound > blockSize, "Block size [%s] is larger than upper bound [%s] for bit width [%s]", blockSize, idBlockUpperBound, uniqueIdBitWidth);
    while (methodTime.elapsed().compareTo(timeout) < 0) {
        final int uniquePID = getUniquePartitionID();
        final StaticBuffer partitionKey = getPartitionKey(partition, idNamespace, uniquePID);
        try {
            long nextStart = getCurrentID(partitionKey);
            if (idBlockUpperBound - blockSize <= nextStart) {
                log.info("ID overflow detected on partition({})-namespace({}) with uniqueid {}. Current id {}, block size {}, and upper bound {} for bit width {}.", partition, idNamespace, uniquePID, nextStart, blockSize, idBlockUpperBound, uniqueIdBitWidth);
                if (randomizeUniqueId) {
                    exhaustedUniquePIDs.add(uniquePID);
                    if (exhaustedUniquePIDs.size() == randomUniqueIDLimit)
                        throw new IDPoolExhaustedException(String.format("Exhausted %d uniqueid(s) on partition(%d)-namespace(%d): %s", exhaustedUniquePIDs.size(), partition, idNamespace, Joiner.on(",").join(exhaustedUniquePIDs)));
                    else
                        throw new UniqueIDExhaustedException(String.format("Exhausted ID partition(%d)-namespace(%d) with uniqueid %d (uniqueid attempt %d/%d)", partition, idNamespace, uniquePID, exhaustedUniquePIDs.size(), randomUniqueIDLimit));
                }
                throw new IDPoolExhaustedException("Exhausted id block for partition(" + partition + ")-namespace(" + idNamespace + ") with upper bound: " + idBlockUpperBound);
            }
            // calculate the start (inclusive) and end (exclusive) of the allocation we're about to attempt
            assert idBlockUpperBound - blockSize > nextStart;
            long nextEnd = nextStart + blockSize;
            StaticBuffer target = null;
            // attempt to write our claim on the next id block
            boolean success = false;
            try {
                Timer writeTimer = times.getTimer().start();
                target = getBlockApplication(nextEnd, writeTimer.getStartTime());
                // copy for the inner class
                final StaticBuffer finalTarget = target;
                BackendOperation.execute(txh -> {
                    idStore.mutate(partitionKey, Collections.singletonList(StaticArrayEntry.of(finalTarget)), KeyColumnValueStore.NO_DELETIONS, txh);
                    return true;
                }, this, times);
                writeTimer.stop();
                Duration writeElapsed = writeTimer.elapsed();
                if (idApplicationWaitMS.compareTo(writeElapsed) < 0) {
                    throw new TemporaryBackendException("Wrote claim for id block [" + nextStart + ", " + nextEnd + ") in " + (writeElapsed) + " => too slow, threshold is: " + idApplicationWaitMS);
                } else {
                    assert 0 != target.length();
                    final StaticBuffer[] slice = getBlockSlice(nextEnd);
                    /* At this point we've written our claim on [nextStart, nextEnd),
                         * but we haven't yet guaranteed the absence of a contending claim on
                         * the same id block from another machine
                         */
                    sleepAndConvertInterrupts(idApplicationWaitMS.plus(waitGracePeriod));
                    // Read all id allocation claims on this partition, for the counter value we're claiming
                    final List<Entry> blocks = BackendOperation.execute((BackendOperation.Transactional<List<Entry>>) txh -> idStore.getSlice(new KeySliceQuery(partitionKey, slice[0], slice[1]), txh), this, times);
                    if (blocks == null)
                        throw new TemporaryBackendException("Could not read from storage");
                    if (blocks.isEmpty())
                        throw new PermanentBackendException("It seems there is a race-condition in the block application. " + "If you have multiple JanusGraph instances running on one physical machine, ensure that they have unique machine idAuthorities");
                    /* If our claim is the lexicographically first one, then our claim
                         * is the most senior one and we own this id block
                         */
                    if (target.equals(blocks.get(0).getColumnAs(StaticBuffer.STATIC_FACTORY))) {
                        ConsistentKeyIDBlock idBlock = new ConsistentKeyIDBlock(nextStart, blockSize, uniqueIdBitWidth, uniquePID);
                        if (log.isDebugEnabled()) {
                            log.debug("Acquired ID block [{}] on partition({})-namespace({}) (my rid is {})", idBlock, partition, idNamespace, uid);
                        }
                        success = true;
                        return idBlock;
                    } else {
                        // Another claimant beat us to this id block -- try again.
                        log.debug("Failed to acquire ID block [{},{}) (another host claimed it first)", nextStart, nextEnd);
                    }
                }
            } finally {
                if (!success && null != target) {
                    // Delete claim to not pollute id space
                    for (int attempt = 0; attempt < ROLLBACK_ATTEMPTS; attempt++) {
                        try {
                            // copy for the inner class
                            final StaticBuffer finalTarget = target;
                            BackendOperation.execute(txh -> {
                                idStore.mutate(partitionKey, KeyColumnValueStore.NO_ADDITIONS, Collections.singletonList(finalTarget), txh);
                                return true;
                            }, new // Use normal consistency level for these non-critical delete operations
                            BackendOperation.TransactionalProvider() {

                                @Override
                                public StoreTransaction openTx() throws BackendException {
                                    return manager.beginTransaction(storeTxConfigBuilder.build());
                                }

                                @Override
                                public void close() {
                                }
                            }, times);
                            break;
                        } catch (BackendException e) {
                            log.warn("Storage exception while deleting old block application - retrying in {}", rollbackWaitTime, e);
                            if (!rollbackWaitTime.isZero())
                                sleepAndConvertInterrupts(rollbackWaitTime);
                        }
                    }
                }
            }
        } catch (UniqueIDExhaustedException e) {
            // No need to increment the backoff wait time or to sleep
            log.warn(e.getMessage());
        } catch (TemporaryBackendException e) {
            backoffMS = Durations.min(backoffMS.multipliedBy(2), idApplicationWaitMS.multipliedBy(32));
            log.warn("Temporary storage exception while acquiring id block - retrying in {}: {}", backoffMS, e);
            sleepAndConvertInterrupts(backoffMS);
        }
    }
    throw new TemporaryLockingException(String.format("Reached timeout %d (%s elapsed) when attempting to allocate id block on partition(%d)-namespace(%d)", timeout.getNano(), methodTime.toString(), partition, idNamespace));
}
Also used : KeyRange(org.janusgraph.diskstorage.keycolumnvalue.KeyRange) org.janusgraph.diskstorage.util.time(org.janusgraph.diskstorage.util.time) StoreManager(org.janusgraph.diskstorage.keycolumnvalue.StoreManager) LoggerFactory(org.slf4j.LoggerFactory) Random(java.util.Random) Timer(org.janusgraph.diskstorage.util.time.Timer) NumberUtil(org.janusgraph.util.stats.NumberUtil) ArrayList(java.util.ArrayList) org.janusgraph.diskstorage.util(org.janusgraph.diskstorage.util) VariableLong(org.janusgraph.graphdb.database.idhandling.VariableLong) Duration(java.time.Duration) StoreTransaction(org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction) IDPoolExhaustedException(org.janusgraph.graphdb.database.idassigner.IDPoolExhaustedException) Logger(org.slf4j.Logger) Configuration(org.janusgraph.diskstorage.configuration.Configuration) KeySliceQuery(org.janusgraph.diskstorage.keycolumnvalue.KeySliceQuery) Instant(java.time.Instant) KeyColumnValueStore(org.janusgraph.diskstorage.keycolumnvalue.KeyColumnValueStore) List(java.util.List) GraphDatabaseConfiguration(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration) Preconditions(com.google.common.base.Preconditions) Collections(java.util.Collections) org.janusgraph.diskstorage(org.janusgraph.diskstorage) Joiner(com.google.common.base.Joiner) TemporaryLockingException(org.janusgraph.diskstorage.locking.TemporaryLockingException) StoreTransaction(org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction) ArrayList(java.util.ArrayList) ArrayList(java.util.ArrayList) List(java.util.List) KeySliceQuery(org.janusgraph.diskstorage.keycolumnvalue.KeySliceQuery) Duration(java.time.Duration) Timer(org.janusgraph.diskstorage.util.time.Timer) IDPoolExhaustedException(org.janusgraph.graphdb.database.idassigner.IDPoolExhaustedException) TemporaryLockingException(org.janusgraph.diskstorage.locking.TemporaryLockingException)

Example 7 with StoreTransaction

use of org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction in project janusgraph by JanusGraph.

the class BerkeleyJEKeyValueStore method delete.

@Override
public void delete(StaticBuffer key, StoreTransaction txh) throws BackendException {
    log.trace("Deletion");
    Transaction tx = getTransaction(txh);
    try {
        log.trace("db={}, op=delete, tx={}", name, txh);
        OperationStatus status = db.delete(tx, key.as(ENTRY_FACTORY));
        if (status != OperationStatus.SUCCESS) {
            throw new PermanentBackendException("Could not remove: " + status);
        }
    } catch (DatabaseException e) {
        throw new PermanentBackendException(e);
    }
}
Also used : StoreTransaction(org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction) PermanentBackendException(org.janusgraph.diskstorage.PermanentBackendException)

Example 8 with StoreTransaction

use of org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction in project janusgraph by JanusGraph.

the class BerkeleyJEKeyValueStore method get.

@Override
public StaticBuffer get(StaticBuffer key, StoreTransaction txh) throws BackendException {
    Transaction tx = getTransaction(txh);
    try {
        DatabaseEntry databaseKey = key.as(ENTRY_FACTORY);
        DatabaseEntry data = new DatabaseEntry();
        log.trace("db={}, op=get, tx={}", name, txh);
        OperationStatus status = db.get(tx, databaseKey, data, getLockMode(txh));
        if (status == OperationStatus.SUCCESS) {
            return getBuffer(data);
        } else {
            return null;
        }
    } catch (DatabaseException e) {
        throw new PermanentBackendException(e);
    }
}
Also used : StoreTransaction(org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction) PermanentBackendException(org.janusgraph.diskstorage.PermanentBackendException)

Example 9 with StoreTransaction

use of org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction in project janusgraph by JanusGraph.

the class CQLStoreManager method mutateManyLogged.

// Use a single logged batch
private void mutateManyLogged(final Map<String, Map<StaticBuffer, KCVMutation>> mutations, final StoreTransaction txh) throws BackendException {
    final MaskedTimestamp commitTime = new MaskedTimestamp(txh);
    final BatchStatement batchStatement = new BatchStatement(Type.LOGGED);
    batchStatement.setConsistencyLevel(getTransaction(txh).getWriteConsistencyLevel());
    batchStatement.addAll(Iterator.ofAll(mutations.entrySet()).flatMap(tableNameAndMutations -> {
        final String tableName = tableNameAndMutations.getKey();
        final Map<StaticBuffer, KCVMutation> tableMutations = tableNameAndMutations.getValue();
        final CQLKeyColumnValueStore columnValueStore = Option.of(this.openStores.get(tableName)).getOrElseThrow(() -> new IllegalStateException("Store cannot be found: " + tableName));
        return Iterator.ofAll(tableMutations.entrySet()).flatMap(keyAndMutations -> {
            final StaticBuffer key = keyAndMutations.getKey();
            final KCVMutation keyMutations = keyAndMutations.getValue();
            final Iterator<Statement> deletions = Iterator.of(commitTime.getDeletionTime(this.times)).flatMap(deleteTime -> Iterator.ofAll(keyMutations.getDeletions()).map(deletion -> columnValueStore.deleteColumn(key, deletion, deleteTime)));
            final Iterator<Statement> additions = Iterator.of(commitTime.getAdditionTime(this.times)).flatMap(addTime -> Iterator.ofAll(keyMutations.getAdditions()).map(addition -> columnValueStore.insertColumn(key, addition, addTime)));
            return Iterator.concat(deletions, additions);
        });
    }));
    final Future<ResultSet> result = Future.fromJavaFuture(this.executorService, this.session.executeAsync(batchStatement));
    result.await();
    if (result.isFailure()) {
        throw EXCEPTION_MAPPER.apply(result.getCause().get());
    }
    sleepAfterWrite(txh, commitTime);
}
Also used : Match(io.vavr.API.Match) PoolingOptions(com.datastax.driver.core.PoolingOptions) GRAPH_NAME(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.GRAPH_NAME) SSLContext(javax.net.ssl.SSLContext) REMOTE_MAX_REQUESTS_PER_CONNECTION(org.janusgraph.diskstorage.cql.CQLConfigOptions.REMOTE_MAX_REQUESTS_PER_CONNECTION) TrustManager(javax.net.ssl.TrustManager) KeyStoreException(java.security.KeyStoreException) REMOTE_CORE_CONNECTIONS_PER_HOST(org.janusgraph.diskstorage.cql.CQLConfigOptions.REMOTE_CORE_CONNECTIONS_PER_HOST) StandardStoreFeatures(org.janusgraph.diskstorage.keycolumnvalue.StandardStoreFeatures) REMOTE_MAX_CONNECTIONS_PER_HOST(org.janusgraph.diskstorage.cql.CQLConfigOptions.REMOTE_MAX_CONNECTIONS_PER_HOST) Option(io.vavr.control.Option) Map(java.util.Map) Session(com.datastax.driver.core.Session) TokenAwarePolicy(com.datastax.driver.core.policies.TokenAwarePolicy) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) SSL_TRUSTSTORE_LOCATION(org.janusgraph.diskstorage.cql.CQLConfigOptions.SSL_TRUSTSTORE_LOCATION) Iterator(io.vavr.collection.Iterator) SchemaBuilder.dropKeyspace(com.datastax.driver.core.schemabuilder.SchemaBuilder.dropKeyspace) BatchStatement(com.datastax.driver.core.BatchStatement) LOCAL_MAX_CONNECTIONS_PER_HOST(org.janusgraph.diskstorage.cql.CQLConfigOptions.LOCAL_MAX_CONNECTIONS_PER_HOST) KEYSPACE(org.janusgraph.diskstorage.cql.CQLConfigOptions.KEYSPACE) KCVMutation(org.janusgraph.diskstorage.keycolumnvalue.KCVMutation) NetworkUtil(org.janusgraph.util.system.NetworkUtil) Tuple(io.vavr.Tuple) TrustManagerFactory(javax.net.ssl.TrustManagerFactory) READ_CONSISTENCY(org.janusgraph.diskstorage.cql.CQLConfigOptions.READ_CONSISTENCY) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Array(io.vavr.collection.Array) Case(io.vavr.API.Case) KeyStore(java.security.KeyStore) KeyManagementException(java.security.KeyManagementException) InetSocketAddress(java.net.InetSocketAddress) LinkedBlockingQueue(java.util.concurrent.LinkedBlockingQueue) StoreFeatures(org.janusgraph.diskstorage.keycolumnvalue.StoreFeatures) GraphDatabaseConfiguration.buildGraphConfiguration(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.buildGraphConfiguration) REPLICATION_FACTOR(org.janusgraph.diskstorage.cql.CQLConfigOptions.REPLICATION_FACTOR) KeyColumnValueStore(org.janusgraph.diskstorage.keycolumnvalue.KeyColumnValueStore) Builder(com.datastax.driver.core.Cluster.Builder) ProtocolVersion(com.datastax.driver.core.ProtocolVersion) List(java.util.List) METRICS_SYSTEM_PREFIX_DEFAULT(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.METRICS_SYSTEM_PREFIX_DEFAULT) DROP_ON_CLEAR(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.DROP_ON_CLEAR) Cluster(com.datastax.driver.core.Cluster) ATOMIC_BATCH_MUTATE(org.janusgraph.diskstorage.cql.CQLConfigOptions.ATOMIC_BATCH_MUTATE) NoSuchAlgorithmException(java.security.NoSuchAlgorithmException) HostDistance(com.datastax.driver.core.HostDistance) SSL_TRUSTSTORE_PASSWORD(org.janusgraph.diskstorage.cql.CQLConfigOptions.SSL_TRUSTSTORE_PASSWORD) AUTH_PASSWORD(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.AUTH_PASSWORD) Statement(com.datastax.driver.core.Statement) EXCEPTION_MAPPER(org.janusgraph.diskstorage.cql.CQLKeyColumnValueStore.EXCEPTION_MAPPER) KeyRange(org.janusgraph.diskstorage.keycolumnvalue.KeyRange) ThreadFactoryBuilder(com.google.common.util.concurrent.ThreadFactoryBuilder) CLUSTER_NAME(org.janusgraph.diskstorage.cql.CQLConfigOptions.CLUSTER_NAME) DistributedStoreManager(org.janusgraph.diskstorage.common.DistributedStoreManager) ThreadPoolExecutor(java.util.concurrent.ThreadPoolExecutor) BATCH_STATEMENT_SIZE(org.janusgraph.diskstorage.cql.CQLConfigOptions.BATCH_STATEMENT_SIZE) METRICS_PREFIX(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.METRICS_PREFIX) LOCAL_CORE_CONNECTIONS_PER_HOST(org.janusgraph.diskstorage.cql.CQLConfigOptions.LOCAL_CORE_CONNECTIONS_PER_HOST) REPLICATION_OPTIONS(org.janusgraph.diskstorage.cql.CQLConfigOptions.REPLICATION_OPTIONS) ONLY_USE_LOCAL_CONSISTENCY_FOR_SYSTEM_OPERATIONS(org.janusgraph.diskstorage.cql.CQLConfigOptions.ONLY_USE_LOCAL_CONSISTENCY_FOR_SYSTEM_OPERATIONS) ResultSet(com.datastax.driver.core.ResultSet) CQLTransaction.getTransaction(org.janusgraph.diskstorage.cql.CQLTransaction.getTransaction) Type(com.datastax.driver.core.BatchStatement.Type) WRITE_CONSISTENCY(org.janusgraph.diskstorage.cql.CQLConfigOptions.WRITE_CONSISTENCY) Future(io.vavr.concurrent.Future) SchemaBuilder.createKeyspace(com.datastax.driver.core.schemabuilder.SchemaBuilder.createKeyspace) AUTH_USERNAME(org.janusgraph.graphdb.configuration.GraphDatabaseConfiguration.AUTH_USERNAME) Container(org.janusgraph.diskstorage.StoreMetaData.Container) LOCAL_MAX_REQUESTS_PER_CONNECTION(org.janusgraph.diskstorage.cql.CQLConfigOptions.LOCAL_MAX_REQUESTS_PER_CONNECTION) KeyColumnValueStoreManager(org.janusgraph.diskstorage.keycolumnvalue.KeyColumnValueStoreManager) StoreTransaction(org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction) ExecutorService(java.util.concurrent.ExecutorService) API.$(io.vavr.API.$) SSL_ENABLED(org.janusgraph.diskstorage.cql.CQLConfigOptions.SSL_ENABLED) BackendException(org.janusgraph.diskstorage.BackendException) Configuration(org.janusgraph.diskstorage.configuration.Configuration) HashMap(io.vavr.collection.HashMap) LOCAL_DATACENTER(org.janusgraph.diskstorage.cql.CQLConfigOptions.LOCAL_DATACENTER) IOException(java.io.IOException) FileInputStream(java.io.FileInputStream) CertificateException(java.security.cert.CertificateException) REPLICATION_STRATEGY(org.janusgraph.diskstorage.cql.CQLConfigOptions.REPLICATION_STRATEGY) PROTOCOL_VERSION(org.janusgraph.diskstorage.cql.CQLConfigOptions.PROTOCOL_VERSION) TimeUnit(java.util.concurrent.TimeUnit) JdkSSLOptions(com.datastax.driver.core.JdkSSLOptions) KeyspaceMetadata(com.datastax.driver.core.KeyspaceMetadata) BaseTransactionConfig(org.janusgraph.diskstorage.BaseTransactionConfig) QueryBuilder.truncate(com.datastax.driver.core.querybuilder.QueryBuilder.truncate) Seq(io.vavr.collection.Seq) PermanentBackendException(org.janusgraph.diskstorage.PermanentBackendException) DCAwareRoundRobinPolicy(com.datastax.driver.core.policies.DCAwareRoundRobinPolicy) BatchStatement(com.datastax.driver.core.BatchStatement) Iterator(io.vavr.collection.Iterator) ResultSet(com.datastax.driver.core.ResultSet) StaticBuffer(org.janusgraph.diskstorage.StaticBuffer) Map(java.util.Map) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) HashMap(io.vavr.collection.HashMap) KCVMutation(org.janusgraph.diskstorage.keycolumnvalue.KCVMutation)

Aggregations

StoreTransaction (org.janusgraph.diskstorage.keycolumnvalue.StoreTransaction)9 PermanentBackendException (org.janusgraph.diskstorage.PermanentBackendException)5 KeyColumnValueStore (org.janusgraph.diskstorage.keycolumnvalue.KeyColumnValueStore)3 ArrayList (java.util.ArrayList)2 List (java.util.List)2 BackendException (org.janusgraph.diskstorage.BackendException)2 StaticBuffer (org.janusgraph.diskstorage.StaticBuffer)2 Configuration (org.janusgraph.diskstorage.configuration.Configuration)2 KeyColumnValueStoreManager (org.janusgraph.diskstorage.keycolumnvalue.KeyColumnValueStoreManager)2 KeyRange (org.janusgraph.diskstorage.keycolumnvalue.KeyRange)2 BatchStatement (com.datastax.driver.core.BatchStatement)1 Type (com.datastax.driver.core.BatchStatement.Type)1 Cluster (com.datastax.driver.core.Cluster)1 Builder (com.datastax.driver.core.Cluster.Builder)1 HostDistance (com.datastax.driver.core.HostDistance)1 JdkSSLOptions (com.datastax.driver.core.JdkSSLOptions)1 KeyspaceMetadata (com.datastax.driver.core.KeyspaceMetadata)1 PoolingOptions (com.datastax.driver.core.PoolingOptions)1 ProtocolVersion (com.datastax.driver.core.ProtocolVersion)1 ResultSet (com.datastax.driver.core.ResultSet)1