Skip to content

Commit 9bb2d92

Browse files
committed
Introduce RemoteIndexClient
Add RemoteIndexClient initial implementation, its accompanying dependencies, and Build Request, Retry Strategy, and test files Signed-off-by: owenhalpert <ohalpert@gmail.com>
1 parent edcbe31 commit 9bb2d92

File tree

7 files changed

+559
-4
lines changed

7 files changed

+559
-4
lines changed

build.gradle

+5-1
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,11 @@ dependencies {
321321
api "net.java.dev.jna:jna-platform:5.13.0"
322322
// OpenSearch core is using slf4j 1.7.36. Therefore, we cannot change the version here.
323323
implementation 'org.slf4j:slf4j-api:1.7.36'
324-
324+
api 'org.apache.httpcomponents.client5:httpclient5:5.4.1'
325+
api 'org.apache.httpcomponents.core5:httpcore5:5.3.2'
326+
api 'org.apache.httpcomponents.core5:httpcore5-h2:5.3.2'
327+
api "com.fasterxml.jackson.core:jackson-databind:${versions.jackson_databind}"
328+
api "com.fasterxml.jackson.core:jackson-annotations:${versions.jackson}"
325329
zipArchive group: 'org.opensearch.plugin', name:'opensearch-security', version: "${opensearch_build}"
326330
}
327331

src/main/java/org/opensearch/knn/index/KNNSettings.java

+80-1
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,12 @@
1515
import org.opensearch.cluster.metadata.IndexMetadata;
1616
import org.opensearch.cluster.service.ClusterService;
1717
import org.opensearch.common.Booleans;
18+
import org.opensearch.common.settings.SecureSetting;
1819
import org.opensearch.common.settings.Setting;
1920
import org.opensearch.common.settings.Settings;
2021
import org.opensearch.common.unit.TimeValue;
2122
import org.opensearch.core.action.ActionListener;
23+
import org.opensearch.core.common.settings.SecureString;
2224
import org.opensearch.core.common.unit.ByteSizeUnit;
2325
import org.opensearch.core.common.unit.ByteSizeValue;
2426
import org.opensearch.index.IndexModule;
@@ -31,6 +33,7 @@
3133

3234
import java.security.InvalidParameterException;
3335
import java.util.Arrays;
36+
import java.util.Collections;
3437
import java.util.HashMap;
3538
import java.util.List;
3639
import java.util.Map;
@@ -96,6 +99,11 @@ public class KNNSettings {
9699
public static final String KNN_DERIVED_SOURCE_ENABLED = "index.knn.derived_source.enabled";
97100
public static final String KNN_INDEX_REMOTE_VECTOR_BUILD = "index.knn.remote_index_build.enabled";
98101
public static final String KNN_REMOTE_VECTOR_REPO = "knn.remote_index_build.vector_repo";
102+
public static final String KNN_REMOTE_BUILD_SERVICE_ENDPOINT = "knn.remote_build_service.endpoint";
103+
public static final String KNN_REMOTE_BUILD_SERVICE_POLL_INTERVAL = "knn.remote_build_service.poll_interval";
104+
public static final String KNN_REMOTE_BUILD_SERVICE_TIMEOUT = "knn.remote_build_service.timeout";
105+
public static final String KNN_REMOTE_BUILD_SERVICE_USERNAME = "knn.remote_build_service.username";
106+
public static final String KNN_REMOTE_BUILD_SERVICE_PASSWORD = "knn.remote_build_service.password";
99107

100108
/**
101109
* Default setting values
@@ -127,6 +135,9 @@ public class KNNSettings {
127135
public static final Integer KNN_DEFAULT_QUANTIZATION_STATE_CACHE_EXPIRY_TIME_MINUTES = 60;
128136
public static final boolean KNN_DISK_VECTOR_SHARD_LEVEL_RESCORING_DISABLED_VALUE = false;
129137

138+
public static final Integer KNN_DEFAULT_REMOTE_BUILD_SERVICE_TIMEOUT_MINUTES = 60;
139+
public static final Integer KNN_DEFAULT_REMOTE_BUILD_SERVICE_POLL_INTERVAL_SECONDS = 30;
140+
130141
/**
131142
* Settings Definition
132143
*/
@@ -388,6 +399,49 @@ public class KNNSettings {
388399
*/
389400
public static final Setting<String> KNN_REMOTE_VECTOR_REPO_SETTING = Setting.simpleString(KNN_REMOTE_VECTOR_REPO, Dynamic, NodeScope);
390401

402+
/**
403+
* List of remote build service endpoints to be used by remote build service. If greater than one, the client uses round-robin task assignment when workers are busy.
404+
*/
405+
public static final Setting<List<String>> KNN_REMOTE_BUILD_SERVICE_ENDPOINT_SETTING = Setting.listSetting(
406+
KNN_REMOTE_BUILD_SERVICE_ENDPOINT,
407+
Collections.emptyList(),
408+
Function.identity(),
409+
NodeScope,
410+
Dynamic
411+
);
412+
413+
/**
414+
* Time the remote build service client will wait before falling back to CPU index build
415+
*/
416+
public static final Setting<TimeValue> KNN_REMOTE_BUILD_SERVICE_TIMEOUT_SETTING = Setting.timeSetting(
417+
KNN_REMOTE_BUILD_SERVICE_TIMEOUT,
418+
TimeValue.timeValueMinutes(KNN_DEFAULT_REMOTE_BUILD_SERVICE_TIMEOUT_MINUTES),
419+
NodeScope,
420+
Dynamic
421+
);
422+
423+
/**
424+
* Setting to control how often the remote build service client polls the build service for the status of the job
425+
*/
426+
public static final Setting<TimeValue> KNN_REMOTE_BUILD_SERVICE_POLL_INTERVAL_SETTING = Setting.timeSetting(
427+
KNN_REMOTE_BUILD_SERVICE_POLL_INTERVAL,
428+
TimeValue.timeValueSeconds(KNN_DEFAULT_REMOTE_BUILD_SERVICE_POLL_INTERVAL_SECONDS),
429+
NodeScope,
430+
Dynamic
431+
);
432+
433+
/**
434+
* Keystore settings for build service HTTP authorization
435+
*/
436+
public static final Setting<SecureString> KNN_REMOTE_BUILD_SERVICE_USERNAME_SETTING = SecureSetting.secureString(
437+
KNN_REMOTE_BUILD_SERVICE_USERNAME,
438+
null
439+
);
440+
public static final Setting<SecureString> KNN_REMOTE_BUILD_SERVICE_PASSWORD_SETTING = SecureSetting.secureString(
441+
KNN_REMOTE_BUILD_SERVICE_PASSWORD,
442+
null
443+
);
444+
391445
/**
392446
* Dynamic settings
393447
*/
@@ -550,6 +604,26 @@ private Setting<?> getSetting(String key) {
550604
return KNN_REMOTE_VECTOR_REPO_SETTING;
551605
}
552606

607+
if (KNN_REMOTE_BUILD_SERVICE_ENDPOINT.equals(key)) {
608+
return KNN_REMOTE_BUILD_SERVICE_ENDPOINT_SETTING;
609+
}
610+
611+
if (KNN_REMOTE_BUILD_SERVICE_TIMEOUT.equals(key)) {
612+
return KNN_REMOTE_BUILD_SERVICE_TIMEOUT_SETTING;
613+
}
614+
615+
if (KNN_REMOTE_BUILD_SERVICE_POLL_INTERVAL.equals(key)) {
616+
return KNN_REMOTE_BUILD_SERVICE_POLL_INTERVAL_SETTING;
617+
}
618+
619+
if (KNN_REMOTE_BUILD_SERVICE_USERNAME.equals(key)) {
620+
return KNN_REMOTE_BUILD_SERVICE_USERNAME_SETTING;
621+
}
622+
623+
if (KNN_REMOTE_BUILD_SERVICE_PASSWORD.equals(key)) {
624+
return KNN_REMOTE_BUILD_SERVICE_PASSWORD_SETTING;
625+
}
626+
553627
throw new IllegalArgumentException("Cannot find setting by key [" + key + "]");
554628
}
555629

@@ -577,7 +651,12 @@ public List<Setting<?>> getSettings() {
577651
KNN_DISK_VECTOR_SHARD_LEVEL_RESCORING_DISABLED_SETTING,
578652
KNN_DERIVED_SOURCE_ENABLED_SETTING,
579653
KNN_INDEX_REMOTE_VECTOR_BUILD_SETTING,
580-
KNN_REMOTE_VECTOR_REPO_SETTING
654+
KNN_REMOTE_VECTOR_REPO_SETTING,
655+
KNN_REMOTE_BUILD_SERVICE_ENDPOINT_SETTING,
656+
KNN_REMOTE_BUILD_SERVICE_TIMEOUT_SETTING,
657+
KNN_REMOTE_BUILD_SERVICE_POLL_INTERVAL_SETTING,
658+
KNN_REMOTE_BUILD_SERVICE_USERNAME_SETTING,
659+
KNN_REMOTE_BUILD_SERVICE_PASSWORD_SETTING
581660
);
582661
return Stream.concat(settings.stream(), Stream.concat(getFeatureFlags().stream(), dynamicCacheSettings.values().stream()))
583662
.collect(Collectors.toList());

src/main/java/org/opensearch/knn/index/codec/nativeindex/remote/RemoteIndexBuildStrategy.java

+3-2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
import org.opensearch.knn.index.KNNSettings;
1616
import org.opensearch.knn.index.codec.nativeindex.NativeIndexBuildStrategy;
1717
import org.opensearch.knn.index.codec.nativeindex.model.BuildIndexParams;
18+
import org.opensearch.knn.index.remote.RemoteIndexClient;
1819
import org.opensearch.knn.index.vectorvalues.KNNVectorValues;
1920
import org.opensearch.repositories.RepositoriesService;
2021
import org.opensearch.repositories.Repository;
@@ -88,12 +89,12 @@ public void buildAndWriteIndex(BuildIndexParams indexInfo) throws IOException {
8889
log.debug("Repository write took {} ms for vector field [{}]", time_in_millis, indexInfo.getFieldName());
8990

9091
stopWatch = new StopWatch().start();
91-
submitVectorBuild();
92+
String jobId = RemoteIndexClient.getInstance().submitVectorBuild();
9293
time_in_millis = stopWatch.stop().totalTime().millis();
9394
log.debug("Submit vector build took {} ms for vector field [{}]", time_in_millis, indexInfo.getFieldName());
9495

9596
stopWatch = new StopWatch().start();
96-
awaitVectorBuild();
97+
String indexPath = RemoteIndexClient.getInstance().awaitVectorBuild(jobId);
9798
time_in_millis = stopWatch.stop().totalTime().millis();
9899
log.debug("Await vector build took {} ms for vector field [{}]", time_in_millis, indexInfo.getFieldName());
99100

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright OpenSearch Contributors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package org.opensearch.knn.index.remote;
7+
8+
import org.opensearch.common.xcontent.json.JsonXContent;
9+
import lombok.Builder;
10+
import lombok.Getter;
11+
import org.opensearch.core.xcontent.XContentBuilder;
12+
13+
import java.io.IOException;
14+
import java.util.HashMap;
15+
import java.util.Map;
16+
17+
@Builder
18+
@Getter
19+
public class RemoteBuildRequest {
20+
private final String repositoryType;
21+
private final String containerName;
22+
private final String objectPath;
23+
private final String tenantId;
24+
private final int dimension;
25+
private final int docCount;
26+
private final String dataType;
27+
private final String engine;
28+
private final String algorithm;
29+
@Builder.Default
30+
private final Map<String, Object> indexParameters = new HashMap<>();
31+
32+
// TODO: Add type checking to all parameters, add individual methods (e.g. setEfConstruction) to check index params
33+
34+
public String toJson() throws IOException {
35+
try (XContentBuilder builder = JsonXContent.contentBuilder()) {
36+
builder.startObject();
37+
builder.field("repository_type", repositoryType);
38+
builder.field("container_name", containerName);
39+
builder.field("object_path", objectPath);
40+
builder.field("tenant_id", tenantId);
41+
builder.field("dimension", dimension);
42+
builder.field("doc_count", docCount);
43+
builder.field("data_type", dataType);
44+
builder.field("engine", engine);
45+
builder.field("index_parameters", indexParameters);
46+
builder.endObject();
47+
return builder.toString();
48+
}
49+
}
50+
51+
}

0 commit comments

Comments
 (0)