Search in sources :

Example 1 with PhysicalNode

use of io.datarouter.storage.node.type.physical.PhysicalNode in project datarouter by hotpads.

the class LatencyMonitoringService method getClientChecks.

public List<LatencyCheck> getClientChecks() {
    List<LatencyCheck> checks = new ArrayList<>();
    if (MAKE_GET_CHECK) {
        for (ClientId clientId : clientInitializationTracker.getInitializedClients()) {
            Collection<PhysicalNode<?, ?, ?>> nodesForClient = nodes.getPhysicalNodesForClient(clientId.getName());
            Optional<PhysicalNode<?, ?, ?>> findFirst = nodesForClient.stream().findFirst();
            if (findFirst.isPresent()) {
                PhysicalNode<?, ?, ?> node = findFirst.get();
                if (node instanceof PhysicalMapStorageNode) {
                    PhysicalMapStorageNode<?, ?, ?> ms = (PhysicalMapStorageNode<?, ?, ?>) node;
                    checks.add(new DatarouterClientLatencyCheck(LatencyMonitoringService.DR_CLIENT_PREFIX + clientId + LatencyMonitoringService.MS_CHECK_SUFIX, makeGet(ms), clientId));
                }
            }
        }
    }
    Function<ClientId, Stream<Pair<ClientId, SortedStorage<?, ?>>>> mapClientIdToFirstSortedStorageNode = clientId -> nodes.getPhysicalNodesForClient(clientId.getName()).stream().filter(node -> node instanceof SortedStorage).limit(1).map(SortedStorage.class::cast).peek(sortedStorage -> logger.info("selected SortedStorage {}", sortedStorage)).map(sortedStorage -> new Pair<>(clientId, sortedStorage));
    checks.addAll(clientInitializationTracker.getInitializedClients().stream().filter(clientId -> clients.getClientManager(clientId).monitorLatency()).flatMap(mapClientIdToFirstSortedStorageNode).map(pair -> new DatarouterClientLatencyCheck(getCheckNameForDatarouterClient(pair.getLeft()), () -> pair.getRight().scanKeys(ONLY_FIRST).findFirst(), pair.getLeft())).collect(Collectors.toList()));
    return checks;
}
Also used : SortedStorage(io.datarouter.storage.node.op.raw.SortedStorage) OptionalDouble(java.util.OptionalDouble) LoggerFactory(org.slf4j.LoggerFactory) PhysicalNode(io.datarouter.storage.node.type.physical.PhysicalNode) PhysicalDatabeanFieldInfo(io.datarouter.storage.serialize.fieldcache.PhysicalDatabeanFieldInfo) PhysicalMapStorageNode(io.datarouter.storage.node.op.raw.MapStorage.PhysicalMapStorageNode) Deque(java.util.Deque) Singleton(javax.inject.Singleton) ServerName(io.datarouter.storage.config.properties.ServerName) Function(java.util.function.Function) ServiceName(io.datarouter.web.config.service.ServiceName) ArrayList(java.util.ArrayList) Inject(javax.inject.Inject) Map(java.util.Map) ClientId(io.datarouter.storage.client.ClientId) StreamTool(io.datarouter.util.StreamTool) Config(io.datarouter.storage.config.Config) DatarouterNodes(io.datarouter.storage.node.DatarouterNodes) DatarouterClients(io.datarouter.storage.client.DatarouterClients) DatarouterWebSettingRoot(io.datarouter.web.config.DatarouterWebSettingRoot) Logger(org.slf4j.Logger) DatarouterClientAvailabilitySwitchThresholdSettingsProvider(io.datarouter.storage.config.setting.impl.DatarouterClientAvailabilitySwitchThresholdSettingsProvider) Gauges(io.datarouter.storage.metric.Gauges) Collection(java.util.Collection) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) Counters(io.datarouter.instrumentation.count.Counters) SortedStorage(io.datarouter.storage.node.op.raw.SortedStorage) DatarouterDuration(io.datarouter.util.duration.DatarouterDuration) Collectors(java.util.stream.Collectors) ConcurrentLinkedDeque(java.util.concurrent.ConcurrentLinkedDeque) PrimaryKey(io.datarouter.model.key.primary.PrimaryKey) TimeUnit(java.util.concurrent.TimeUnit) List(java.util.List) ClientInitializationTracker(io.datarouter.storage.client.ClientInitializationTracker) Stream(java.util.stream.Stream) TreeMap(java.util.TreeMap) Entry(java.util.Map.Entry) Optional(java.util.Optional) Pair(io.datarouter.util.tuple.Pair) Collections(java.util.Collections) PhysicalMapStorageNode(io.datarouter.storage.node.op.raw.MapStorage.PhysicalMapStorageNode) ArrayList(java.util.ArrayList) ClientId(io.datarouter.storage.client.ClientId) Stream(java.util.stream.Stream) PhysicalNode(io.datarouter.storage.node.type.physical.PhysicalNode)

Example 2 with PhysicalNode

use of io.datarouter.storage.node.type.physical.PhysicalNode in project datarouter by hotpads.

the class SpannerSingleTableSchemaUpdateService method performSchemaUpdate.

public Optional<SchemaUpdateResult> performSchemaUpdate(ClientId clientId, Supplier<List<String>> existingTableNames, PhysicalNode<?, ?, ?> physicalNode) {
    String tableName = physicalNode.getFieldInfo().getTableName();
    List<Field<?>> primaryKeyFields = physicalNode.getFieldInfo().getSamplePrimaryKey().getFields();
    List<? extends SpannerBaseFieldCodec<?, ?>> primaryKeyCodecs = fieldCodecRegistry.createCodecs(primaryKeyFields);
    for (SpannerBaseFieldCodec<?, ?> codec : primaryKeyCodecs) {
        if (codec.getSpannerColumnType().isArray()) {
            throw new RuntimeException("Invalid field type used for primary key: " + codec.getField().getKey().getName());
        }
    }
    List<SpannerIndex> indexes = new ArrayList<>();
    List<SpannerIndex> uniqueIndexes = Scanner.of(physicalNode.getFieldInfo().getUniqueIndexes().entrySet()).map(entry -> new SpannerIndex(tableName, entry.getKey(), entry.getValue(), Collections.emptyList(), true)).list();
    var statements = new SpannerUpdateStatements();
    String entityTableName = null;
    if (physicalNode instanceof IndexedStorage) {
        IndexedStorage<?, ?> indexedStorage = (IndexedStorage<?, ?>) physicalNode;
        indexes = Scanner.of(indexedStorage.getManagedNodes()).map(node -> new SpannerIndex(tableName, node.getName(), node.getIndexEntryFieldInfo().getPrimaryKeyFields(), node.getIndexEntryFieldInfo().getFields(), false)).list();
    }
    List<SpannerColumn> primaryKeyColumns = Scanner.of(primaryKeyCodecs).map(codec -> codec.getSpannerColumn(false)).list();
    List<SpannerColumn> nonKeyColumns = Scanner.of(fieldCodecRegistry.createCodecs(physicalNode.getFieldInfo().getNonKeyFields())).map(codec -> codec.getSpannerColumn(true)).list();
    if (!existingTableNames.get().contains(tableName)) {
        statements.updateFunction(tableOperationsGenerator.createTable(tableName, primaryKeyColumns, nonKeyColumns, entityTableName), updateOptions::getCreateTables, true);
        Scanner.of(indexes, uniqueIndexes).concat(Scanner::of).map(index -> createIndex(index, primaryKeyColumns)).forEach(statement -> statements.updateFunction(statement, updateOptions::getCreateTables, true));
    } else {
        DatabaseClient databaseClient = clientsHolder.getDatabaseClient(clientId);
        List<SpannerColumn> allColumns = Scanner.of(primaryKeyColumns, nonKeyColumns).concat(Scanner::of).list();
        ResultSet columnRs = databaseClient.singleUse().executeQuery(Statement.of(tableOperationsGenerator.getTableSchema(tableName)));
        ResultSet primaryKeyRs = databaseClient.singleUse().executeQuery(Statement.of(tableOperationsGenerator.getTableIndexColumnsSchema(tableName, "PRIMARY_KEY")));
        tableAlterSchemaService.generateUpdateStatementColumns(tableName, allColumns, primaryKeyColumns, columnRs, primaryKeyRs, statements);
        ResultSet indexesRs = databaseClient.singleUse().executeQuery(Statement.of(tableOperationsGenerator.getTableIndexSchema(tableName)));
        Set<String> currentIndexes = tableAlterSchemaService.getIndexes(indexesRs);
        Scanner.of(indexes, uniqueIndexes).concat(Scanner::of).forEach(index -> {
            Statement tableIndexColumnsSchema = Statement.of(tableOperationsGenerator.getTableIndexColumnsSchema(tableName, index.getIndexName()));
            ResultSet indexRs = databaseClient.singleUse().executeQuery(tableIndexColumnsSchema);
            if (!tableAlterSchemaService.indexEqual(index, indexRs)) {
                if (currentIndexes.contains(index.getIndexName())) {
                    statements.updateFunction(tableOperationsGenerator.dropIndex(index.getIndexName()), updateOptions::getDropIndexes, false);
                }
                statements.updateFunction(createIndex(index, primaryKeyColumns), updateOptions::getAddIndexes, true);
            }
            currentIndexes.remove(index.getIndexName());
        });
        currentIndexes.forEach(name -> statements.updateFunction(tableOperationsGenerator.dropIndex(name), updateOptions::getDropIndexes, false));
    }
    String errorMessage = null;
    if (!statements.getExecuteStatements().isEmpty()) {
        logger.info(SchemaUpdateTool.generateFullWidthMessage("Executing Spanner " + getClass().getSimpleName() + " SchemaUpdate"));
        logger.info(String.join("\n\n", statements.getExecuteStatements()));
        Database database = clientsHolder.getDatabase(clientId);
        OperationFuture<Void, UpdateDatabaseDdlMetadata> future = database.updateDdl(statements.getExecuteStatements(), null);
        errorMessage = FutureTool.get(future.getPollingFuture().getAttemptResult()).getErrorMessage();
        if (StringTool.notNullNorEmptyNorWhitespace(errorMessage)) {
            logger.error(errorMessage);
        }
    }
    if (statements.getPreventStartUp()) {
        errorMessage = "an alter on Spanner table " + tableName + " is required";
    }
    if (statements.getPrintStatements().isEmpty()) {
        return Optional.empty();
    }
    String printStatement = statements.getPrintStatements().stream().map(statement -> statement + ";").collect(Collectors.joining("\n"));
    SchemaUpdateTool.printSchemaUpdate(logger, printStatement);
    return Optional.of(new SchemaUpdateResult(printStatement, errorMessage, clientId));
}
Also used : Scanner(io.datarouter.scanner.Scanner) SchemaUpdateTool(io.datarouter.storage.config.schema.SchemaUpdateTool) OperationFuture(com.google.api.gax.longrunning.OperationFuture) SpannerDatabaseClientsHolder(io.datarouter.gcp.spanner.connection.SpannerDatabaseClientsHolder) LoggerFactory(org.slf4j.LoggerFactory) PhysicalNode(io.datarouter.storage.node.type.physical.PhysicalNode) DatabaseClient(com.google.cloud.spanner.DatabaseClient) Singleton(javax.inject.Singleton) Supplier(java.util.function.Supplier) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Inject(javax.inject.Inject) ResultSet(com.google.cloud.spanner.ResultSet) ClientId(io.datarouter.storage.client.ClientId) Logger(org.slf4j.Logger) Database(com.google.cloud.spanner.Database) Set(java.util.Set) StringTool(io.datarouter.util.string.StringTool) Collectors(java.util.stream.Collectors) SchemaUpdateOptions(io.datarouter.storage.config.schema.SchemaUpdateOptions) UpdateDatabaseDdlMetadata(com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata) Statement(com.google.cloud.spanner.Statement) List(java.util.List) Field(io.datarouter.model.field.Field) SpannerFieldCodecRegistry(io.datarouter.gcp.spanner.field.SpannerFieldCodecRegistry) Optional(java.util.Optional) IndexedStorage(io.datarouter.storage.node.op.raw.IndexedStorage) Collections(java.util.Collections) SpannerBaseFieldCodec(io.datarouter.gcp.spanner.field.SpannerBaseFieldCodec) SchemaUpdateResult(io.datarouter.storage.config.schema.SchemaUpdateResult) FutureTool(io.datarouter.util.concurrent.FutureTool) Scanner(io.datarouter.scanner.Scanner) ArrayList(java.util.ArrayList) Field(io.datarouter.model.field.Field) UpdateDatabaseDdlMetadata(com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata) ResultSet(com.google.cloud.spanner.ResultSet) Database(com.google.cloud.spanner.Database) IndexedStorage(io.datarouter.storage.node.op.raw.IndexedStorage) Statement(com.google.cloud.spanner.Statement) DatabaseClient(com.google.cloud.spanner.DatabaseClient) SchemaUpdateResult(io.datarouter.storage.config.schema.SchemaUpdateResult)

Aggregations

ClientId (io.datarouter.storage.client.ClientId)2 PhysicalNode (io.datarouter.storage.node.type.physical.PhysicalNode)2 ArrayList (java.util.ArrayList)2 Collections (java.util.Collections)2 List (java.util.List)2 Optional (java.util.Optional)2 Collectors (java.util.stream.Collectors)2 Inject (javax.inject.Inject)2 Singleton (javax.inject.Singleton)2 Logger (org.slf4j.Logger)2 LoggerFactory (org.slf4j.LoggerFactory)2 OperationFuture (com.google.api.gax.longrunning.OperationFuture)1 Database (com.google.cloud.spanner.Database)1 DatabaseClient (com.google.cloud.spanner.DatabaseClient)1 ResultSet (com.google.cloud.spanner.ResultSet)1 Statement (com.google.cloud.spanner.Statement)1 UpdateDatabaseDdlMetadata (com.google.spanner.admin.database.v1.UpdateDatabaseDdlMetadata)1 SpannerDatabaseClientsHolder (io.datarouter.gcp.spanner.connection.SpannerDatabaseClientsHolder)1 SpannerBaseFieldCodec (io.datarouter.gcp.spanner.field.SpannerBaseFieldCodec)1 SpannerFieldCodecRegistry (io.datarouter.gcp.spanner.field.SpannerFieldCodecRegistry)1