Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 37 additions & 13 deletions _api-reference/grpc-apis/bulk.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ The gRPC Bulk API provides an efficient, binary-encoded alternative to the [HTTP

## Prerequisite

To submit gRPC requests, you must have a set of protobufs on the client side. For ways to obtain the protobufs, see [Using gRPC APIs]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#using-grpc-apis).
To submit gRPC requests, you must have a set of protobufs on the client side. For ways to obtain the protobufs, see [Using gRPC APIs]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#how-to-use-grpc-apis).

## gRPC service and method

gRPC Document APIs reside in the [DocumentService](https://github.com/opensearch-project/opensearch-protobufs/blob/0.19.0/protos/services/document_service.proto#L22).

You can submit bulk requests by invoking the [`Bulk`](https://github.com/opensearch-project/opensearch-protobufs/blob/0.19.0/protos/services/document_service.proto#L24) gRPC method within the `DocumentService`. The method takes a [`BulkRequest`](#bulkrequest-fields) and returns a [`BulkResponse`](#bulkresponsebody-fields).
You can submit bulk requests by invoking the [`Bulk`](https://github.com/opensearch-project/opensearch-protobufs/blob/0.19.0/protos/services/document_service.proto#L24) gRPC method within the `DocumentService`. The method takes a [`BulkRequest`](#bulkrequest-fields) and returns a [`BulkResponse`](#bulkresponse-fields).

## Document format

Expand Down Expand Up @@ -318,9 +318,9 @@ The following example shows a bulk request with a `script` operation. It increme

The gRPC Bulk API provides the following response fields.

### BulkResponseBody fields
### BulkResponse fields

The [`BulkResponse`](https://github.com/opensearch-project/opensearch-protobufs/blob/0.19.0/protos/schemas/document.proto#L188) message wraps either a `BulkResponseBody` for successful requests or a `BulkErrorResponse` for failed requests. The `BulkResponseBody` provides a summary and per-item result of a bulk operation and contains the following fields.
The [`BulkResponse`](https://github.com/opensearch-project/opensearch-protobufs/blob/0.19.0/protos/schemas/document.proto#L186) message is returned directly from the Bulk gRPC method and provides a summary and per-item result of a bulk operation. It contains the following fields.

| Field | Protobuf type | Description |
| :---- | :---- | :---- |
Expand Down Expand Up @@ -475,23 +475,23 @@ public class BulkClient {

// Create an index operation
IndexOperation indexOp = IndexOperation.newBuilder()
.setIndex("my-index")
.setId("1")
.setXIndex("my-index")
.setXId("1")
.build();

BulkRequestBody indexBody = BulkRequestBody.newBuilder()
.setIndex(indexOp)
.setDoc(ByteString.copyFromUtf8("{\"field\": \"value\"}"))
.setOperationContainer(OperationContainer.newBuilder().setIndex(indexOp).build())
.setObject(ByteString.copyFromUtf8("{\"field\": \"value\"}"))
.build();

// Create a delete operation
DeleteOperation deleteOp = DeleteOperation.newBuilder()
.setIndex("my-index")
.setId("2")
.setXIndex("my-index")
.setXId("2")
.build();

BulkRequestBody deleteBody = BulkRequestBody.newBuilder()
.setDelete(deleteOp)
.setOperationContainer(OperationContainer.newBuilder().setDelete(deleteOp).build())
.build();

// Build the bulk request
Expand All @@ -502,8 +502,32 @@ public class BulkClient {
.build();

// Execute the bulk request
BulkResponse response = stub.bulk(request);
System.out.println("Bulk errors: " + response.getBulkResponseBody().getErrors());
try {
BulkResponse response = stub.bulk(request);

// Handle the response
System.out.println("Bulk errors: " + response.getErrors());
System.out.println("Bulk took: " + response.getTook() + " ms");
if (response.hasIngestTook()) {
System.out.println("Ingest took: " + response.getIngestTook() + " ms");
}

// Process individual items
for (Item item : response.getItemsList()) {
if (item.hasIndex()) {
System.out.println("Index operation: " + item.getIndex().getStatus());
} else if (item.hasDelete()) {
System.out.println("Delete operation: " + item.getDelete().getStatus());
} else if (item.hasCreate()) {
System.out.println("Create operation: " + item.getCreate().getStatus());
} else if (item.hasUpdate()) {
System.out.println("Update operation: " + item.getUpdate().getStatus());
}
}
} catch (io.grpc.StatusRuntimeException e) {
System.err.println("gRPC request failed with status: " + e.getStatus());
System.err.println("Error message: " + e.getMessage());
}

channel.shutdown();
}
Expand Down
50 changes: 25 additions & 25 deletions _api-reference/grpc-apis/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,25 +18,27 @@
Starting with OpenSearch version 3.2, the gRPC [Bulk API]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/bulk/) and [k-NN search queries]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/knn/) are generally available. These use [protobuf version 0.19.0](https://github.com/opensearch-project/opensearch-protobufs/releases/tag/0.19.0). However, expect updates to the protobuf structure as the feature matures in upcoming versions. Other gRPC search functionality remains experimental and not recommended for production use. For updates on the progress of these features or to leave feedback, see the associated [GitHub issue](https://github.com/opensearch-project/OpenSearch/issues/16787).
{: .note}

The OpenSearch gRPC functionality provides an alternative, high-performance transport layer using [gRPC](https://grpc.io/) for communication with OpenSearch. It uses protocol buffers over gRPC for lower overhead and faster serialization. This reduces overhead, speeds up serialization, and improves request-side latency, based on initial benchmarking results.
The OpenSearch gRPC functionality provides an alternative, high-performance transport layer using [gRPC](https://grpc.io/) for communication with OpenSearch. It uses protocol buffers over gRPC for lower overhead and faster serialization. This reduces overhead, speeds up serialization, and improves request-side latency, based on initial benchmarking results. See [Performance Benefits](#grpc-performance-benefits) for more info.

The primary goal of gRPC support is to:
## Supported APIs
The following gRPC APIs are currently supported:
- [Bulk]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/bulk/) **Generally available 3.2**
- [k-NN]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/knn/) **Generally available 3.2**
- [Search]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/search/) (for select query types)

* Offer a **binary-encoded** alternative to HTTP/REST-based communication.
* **Improve performance** for bulk workloads and large-scale ingestion scenarios.
* **Enable more efficient client integrations** across languages, like Java, Go, and Python, using native gRPC stubs.
## How to use gRPC APIs
1. First, enable gRPC transport following [gRPC settings](#grpc-settings).

## Performance benefits
2. To submit gRPC requests, you must have a set of protobufs on the client side. You can obtain the protobufs in the following ways:

Using gRPC APIs provides several advantages over HTTP APIs:
| Language | Distribution method | Instructions |
| :------- | :------------------ | :----------- |
| Java | Maven Central repository | Download the `opensearch-protobufs` jar from the [Maven Central repository](https://repo1.maven.org/maven2/org/opensearch/protobufs/0.19.0). |
| Python | PyPI repository | Download the `opensearch-protobufs` package from the [PyPI repository](https://pypi.org/project/opensearch-protobufs/0.19.0). |
| Other languages | GitHub repository (raw protobufs) | Download the raw protobuf schema from the [OpenSearch Protobufs GitHub repository (v0.19.0)](https://github.com/opensearch-project/opensearch-protobufs/releases/tag/0.19.0). You can then generate client-side code using the protocol buffer compilers for the [supported languages](https://grpc.io/docs/languages/). |

- **Reduced latency**: Binary protocol buffers eliminate JSON parsing overhead.
- **Higher throughput**: More efficient network utilization for high-frequency queries.
- **Lower CPU usage**: Reduced serialization and deserialization costs.
- **Type safety**: Protocol buffer schemas provide compile-time validation.
- **Smaller payload sizes**: Binary encoding reduces network traffic.

## Enabling gRPC APIs
## gRPC Settings

Check failure on line 41 in _api-reference/grpc-apis/index.md

View workflow job for this annotation

GitHub Actions / style-job

[vale] reported by reviewdog 🐶 [OpenSearch.HeadingCapitalization] 'gRPC Settings' is a heading and should be in sentence case. Raw Output: {"message": "[OpenSearch.HeadingCapitalization] 'gRPC Settings' is a heading and should be in sentence case.", "location": {"path": "_api-reference/grpc-apis/index.md", "range": {"start": {"line": 41, "column": 4}}}, "severity": "ERROR"}

The `transport-grpc` module is included by default with OpenSearch installations. To enable it, add the following settings to `opensearch.yml`:

Expand All @@ -63,7 +65,7 @@
```
{% include copy.html %}
## Advanced gRPC settings
### Advanced gRPC settings
OpenSearch supports the following advanced settings for gRPC communication. These settings can be configured in `opensearch.yml`.

Expand Down Expand Up @@ -106,18 +108,16 @@

These settings are similar to the [HTTP Network settings]({{site.url}}{{site.baseurl}}/install-and-configure/configuring-opensearch/network-settings/#advanced-http-settings) but specifically apply to gRPC communication.

## Using gRPC APIs

To submit gRPC requests, you must have a set of protobufs on the client side. You can obtain the protobufs in the following ways:

- **Raw protobufs**: Download the raw protobuf schema from the [OpenSearch Protobufs GitHub repository (v0.19.0)](https://github.com/opensearch-project/opensearch-protobufs/releases/tag/0.19.0). You can then generate client-side code using the protocol buffer compilers for the [supported languages](https://grpc.io/docs/languages/).
- **Java client-side programs only**: Download the `opensearch-protobufs` jar from the [Maven Central repository](https://repo1.maven.org/maven2/org/opensearch/protobufs/0.19.0).
- **Python client-side programs only**: Download the `opensearch-protobufs` package from the [PyPI repository](https://pypi.org/project/opensearch-protobufs/0.19.0/).
## gRPC performance benefits

## Supported APIs
Using gRPC APIs provides several advantages over HTTP APIs:

The following gRPC APIs are supported:
- **Reduced latency**: Binary protocol buffers eliminate JSON parsing overhead.
- **Higher throughput**: More efficient network utilization for high-frequency queries.
- **Lower CPU usage**: Reduced serialization and deserialization costs.
- **Type safety**: Protocol buffer schemas provide compile-time validation.
- **Smaller payload sizes**: Binary encoding reduces network traffic.

- [Bulk]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/bulk/) **Generally available 3.2**
- [k-NN]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/knn/) **Generally available 3.2**
- [Search]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/search/) (for select query types)
### Additional performance tip
Indexing documents as supported binary formats, such as SMILE, will usually incur lower latency than indexing/searching for them as JSON. Both indexing and searching latency should be reduced.
29 changes: 24 additions & 5 deletions _api-reference/grpc-apis/knn.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ For information about HTTP-based k-NN queries, see [k-NN query]({{site.url}}{{si

## Prerequisite

To submit gRPC requests, you must have a set of protobufs on the client side. For ways to obtain the protobufs, see [Using gRPC APIs]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#using-grpc-apis).
To submit gRPC requests, you must have a set of protobufs on the client side. For ways to obtain the protobufs, see [Using gRPC APIs]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#how-to-use-grpc-apis).

## gRPC service and method

Expand Down Expand Up @@ -105,9 +105,28 @@ public class KnnGrpcClient {
.build();

// Execute the search
SearchResponse response = searchStub.search(request);

System.out.println("Found " + response.getResponseBody().getHits().getHitsCount() + " results");
try {
SearchResponse response = searchStub.search(request);

// Handle the response
System.out.println("Search took: " + response.getTook() + " ms");

HitsMetadata hits = response.getHits();
if (hits.hasTotal()) {
System.out.println("Found " + hits.getTotal().getTotalHits().getValue() + " results");
}

// Process k-NN results with similarity scores
for (HitsMetadataHitsInner hit : hits.getHitsList()) {
System.out.println("Document ID: " + hit.getXId());
if (hit.hasXScore()) {
System.out.println("Similarity score: " + hit.getXScore().getDouble());
}
}
} catch (io.grpc.StatusRuntimeException e) {
System.err.println("gRPC k-NN search request failed with status: " + e.getStatus());
System.err.println("Error message: " + e.getMessage());
}

channel.shutdown();
}
Expand Down Expand Up @@ -140,4 +159,4 @@ For complex filtering requirements, consider using the HTTP k-NN API, simplifyin
- Learn more about [vector search in OpenSearch]({{site.url}}{{site.baseurl}}/search-plugins/knn/index/).
- Explore [k-NN index settings]({{site.url}}{{site.baseurl}}/search-plugins/knn/knn-index/).
- Review [performance tuning for k-NN]({{site.url}}{{site.baseurl}}/search-plugins/knn/performance-tuning/).
- Read about [gRPC configuration]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#enabling-grpc-apis).
- Read about [gRPC configuration]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#grpc-settings).
36 changes: 24 additions & 12 deletions _api-reference/grpc-apis/search.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The gRPC Search API provides a performant, binary interface for running [queries

## Prerequisite

To submit gRPC requests, you must have a set of protobufs on the client side. For ways to obtain the protobufs, see [Using gRPC APIs]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#using-grpc-apis).
To submit gRPC requests, you must have a set of protobufs on the client side. For ways to obtain the protobufs, see [Using gRPC APIs]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#how-to-use-grpc-apis).

## gRPC service and method

Expand Down Expand Up @@ -443,17 +443,29 @@ public class SearchClient {
.setRequestBody(requestBody)
.build();

SearchResponse response = stub.search(request);

// Handle the response
if (response.hasResponseBody()) {
ResponseBody responseBody = response.getResponseBody();
HitsMetadata hits = responseBody.getHits();
System.out.println("Found hits: " + hits.getTotal().getTotalHits().getValue());
} else if (response.hasError4XxResponse()) {
System.out.println("4xx Error: " + response.getError4XxResponse().getError());
} else if (response.hasError5XxResponse()) {
System.out.println("5xx Error: " + response.getError5XxResponse().getMessage());
try {
SearchResponse response = stub.search(request);

// Handle the response
System.out.println("Search took: " + response.getTook() + " ms");
System.out.println("Timed out: " + response.getTimedOut());

HitsMetadata hits = response.getHits();
if (hits.hasTotal()) {
System.out.println("Total hits: " + hits.getTotal().getTotalHits().getValue());
}

// Process individual hits
for (HitsMetadataHitsInner hit : hits.getHitsList()) {
System.out.println("Hit ID: " + hit.getXId());
System.out.println("Hit Index: " + hit.getXIndex());
if (hit.hasXScore()) {
System.out.println("Score: " + hit.getXScore().getDouble());
}
}
} catch (io.grpc.StatusRuntimeException e) {
System.err.println("gRPC search request failed with status: " + e.getStatus());
System.err.println("Error message: " + e.getMessage());
}

channel.shutdown();
Expand Down
2 changes: 1 addition & 1 deletion _security/configuration/tls.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ You should receive the following response:
gRPC supports encryption in transit only. Trust stores and certificates configured as root CAs in PEM format are used only for the purpose of TLS client authorization. Role-based access is not available for gRPC endpoints.
{: .warning}

You can configure TLS on the optional gRPC transport in `opensearch.yml`. For more information about using the gRPC plugin, see [Enabling gRPC APIs]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#enabling-grpc-apis).
You can configure TLS on the optional gRPC transport in `opensearch.yml`. For more information about using the gRPC plugin, see [Enabling gRPC APIs]({{site.url}}{{site.baseurl}}/api-reference/grpc-apis/index/#grpc-settings).

### PEM key settings (X.509 PEM certificates and PKCS #8 keys)

Expand Down
Loading