com.yahoo.vespa.model.content.DistributorCluster Maven / Gradle / Ivy
// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.
package com.yahoo.vespa.model.content;
import ai.vespa.metrics.DistributorMetrics;
import com.yahoo.config.model.deploy.DeployState;
import com.yahoo.vespa.config.content.core.StorDistributormanagerConfig;
import com.yahoo.vespa.config.content.core.StorServerConfig;
import com.yahoo.document.select.DocumentSelector;
import com.yahoo.document.select.parser.ParseException;
import com.yahoo.config.model.producer.AnyConfigProducer;
import com.yahoo.config.model.producer.TreeConfigProducer;
import com.yahoo.metrics.MetricsmanagerConfig;
import com.yahoo.vespa.model.builder.xml.dom.ModelElement;
import com.yahoo.vespa.model.builder.xml.dom.VespaDomBuilder;
import com.yahoo.vespa.model.content.cluster.ContentCluster;
import org.w3c.dom.Element;
import java.util.logging.Logger;
/**
* Generates distributor-specific configuration.
*/
public class DistributorCluster extends TreeConfigProducer implements
StorDistributormanagerConfig.Producer,
StorServerConfig.Producer,
MetricsmanagerConfig.Producer {
public static final Logger log = Logger.getLogger(DistributorCluster.class.getPackage().toString());
private record GcOptions(int interval, String selection) { }
private final ContentCluster parent;
private final BucketSplitting bucketSplitting;
private final GcOptions gc;
private final boolean hasIndexedDocumentType;
private final int maxActivationInhibitedOutOfSyncGroups;
private final int contentLayerMetadataFeatureLevel;
private final boolean symmetricPutAndActivateReplicaSelection;
private final boolean enforceStrictlyIncreasingClusterStateVersions;
public static class Builder extends VespaDomBuilder.DomConfigProducerBuilderBase {
ContentCluster parent;
public Builder(ContentCluster parent) {
this.parent = parent;
}
private String prepareGCSelection(ModelElement documentNode, String selectionString) throws ParseException {
DocumentSelector s = new DocumentSelector(selectionString);
boolean enableGC = false;
if (documentNode != null) {
enableGC = documentNode.booleanAttribute("garbage-collection", false);
}
if (!enableGC) {
return null;
}
return s.toString();
}
private int getGCInterval(ModelElement documentNode) {
int gcInterval = 3600;
if (documentNode != null) {
gcInterval = documentNode.integerAttribute("garbage-collection-interval", gcInterval);
}
return gcInterval;
}
private GcOptions parseGcOptions(ModelElement documentNode) {
String gcSelection = parent.getRoutingSelector();
int gcInterval;
try {
if (gcSelection != null) {
gcSelection = prepareGCSelection(documentNode, gcSelection);
}
gcInterval = getGCInterval(documentNode);
} catch (ParseException e) {
throw new IllegalArgumentException("Failed to parse garbage collection selection", e);
}
return new GcOptions(gcInterval, gcSelection);
}
private boolean documentModeImpliesIndexing(String mode) {
return "index".equals(mode);
}
private boolean clusterContainsIndexedDocumentType(ModelElement documentsNode) {
return documentsNode != null
&& documentsNode.subElements("document").stream()
.anyMatch(node -> documentModeImpliesIndexing(node.stringAttribute("mode")));
}
@Override
protected DistributorCluster doBuild(DeployState deployState, TreeConfigProducer ancestor, Element producerSpec) {
final ModelElement clusterElement = new ModelElement(producerSpec);
final ModelElement documentsNode = clusterElement.child("documents");
final GcOptions gc = parseGcOptions(documentsNode);
final boolean hasIndexedDocumentType = clusterContainsIndexedDocumentType(documentsNode);
var featureFlags = deployState.getProperties().featureFlags();
int maxInhibitedGroups = featureFlags.maxActivationInhibitedOutOfSyncGroups();
int contentLayerMetadataFeatureLevel = featureFlags.contentLayerMetadataFeatureLevel();
boolean symmetricPutAndActivateReplicaSelection = featureFlags.symmetricPutAndActivateReplicaSelection();
boolean enforceStrictlyIncreasingClusterStateVersions = featureFlags.enforceStrictlyIncreasingClusterStateVersions();
return new DistributorCluster(parent,
new BucketSplitting.Builder().build(new ModelElement(producerSpec)), gc,
hasIndexedDocumentType,
maxInhibitedGroups,
contentLayerMetadataFeatureLevel,
symmetricPutAndActivateReplicaSelection,
enforceStrictlyIncreasingClusterStateVersions);
}
}
private DistributorCluster(ContentCluster parent, BucketSplitting bucketSplitting,
GcOptions gc, boolean hasIndexedDocumentType,
int maxActivationInhibitedOutOfSyncGroups,
int contentLayerMetadataFeatureLevel,
boolean symmetricPutAndActivateReplicaSelection,
boolean enforceStrictlyIncreasingClusterStateVersions)
{
super(parent, "distributor");
this.parent = parent;
this.bucketSplitting = bucketSplitting;
this.gc = gc;
this.hasIndexedDocumentType = hasIndexedDocumentType;
this.maxActivationInhibitedOutOfSyncGroups = maxActivationInhibitedOutOfSyncGroups;
this.contentLayerMetadataFeatureLevel = contentLayerMetadataFeatureLevel;
this.symmetricPutAndActivateReplicaSelection = symmetricPutAndActivateReplicaSelection;
this.enforceStrictlyIncreasingClusterStateVersions = enforceStrictlyIncreasingClusterStateVersions;
}
@Override
public void getConfig(StorDistributormanagerConfig.Builder builder) {
if (gc.selection != null) {
builder.garbagecollection(new StorDistributormanagerConfig.Garbagecollection.Builder()
.selectiontoremove("not (" + gc.selection + ")")
.interval(gc.interval));
}
builder.disable_bucket_activation(!hasIndexedDocumentType);
builder.max_activation_inhibited_out_of_sync_groups(maxActivationInhibitedOutOfSyncGroups);
if (contentLayerMetadataFeatureLevel > 0) {
builder.enable_operation_cancellation(true);
}
builder.symmetric_put_and_activate_replica_selection(symmetricPutAndActivateReplicaSelection);
bucketSplitting.getConfig(builder);
}
@Override
public void getConfig(MetricsmanagerConfig.Builder builder) {
ContentCluster.getMetricBuilder("log", builder).
addedmetrics(DistributorMetrics.VDS_DISTRIBUTOR_DOCSSTORED.baseName()).
addedmetrics(DistributorMetrics.VDS_DISTRIBUTOR_BYTESSTORED.baseName()).
addedmetrics(DistributorMetrics.VDS_IDEALSTATE_DELETE_BUCKET_DONE_OK.baseName()).
addedmetrics(DistributorMetrics.VDS_IDEALSTATE_MERGE_BUCKET_DONE_OK.baseName()).
addedmetrics(DistributorMetrics.VDS_IDEALSTATE_SPLIT_BUCKET_DONE_OK.baseName()).
addedmetrics(DistributorMetrics.VDS_IDEALSTATE_JOIN_BUCKET_DONE_OK.baseName()).
addedmetrics(DistributorMetrics.VDS_IDEALSTATE_BUCKETS_RECHECKING.baseName());
}
@Override
public void getConfig(StorServerConfig.Builder builder) {
builder.root_folder("");
builder.cluster_name(parent.getName());
builder.is_distributor(true);
builder.require_strictly_increasing_cluster_state_versions(enforceStrictlyIncreasingClusterStateVersions);
}
public String getClusterName() {
return parent.getName();
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy