-
Notifications
You must be signed in to change notification settings - Fork 591
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(sink): refator es sink to support opensearch (#16330)
- Loading branch information
Showing
16 changed files
with
579 additions
and
252 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
...nector-node/risingwave-sink-es-7/src/main/java/com/risingwave/connector/BulkListener.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
/* | ||
* Copyright 2024 RisingWave Labs | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.risingwave.connector; | ||
|
||
import com.risingwave.connector.EsSink.RequestTracker; | ||
import org.elasticsearch.action.bulk.BulkRequest; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class BulkListener | ||
implements org.elasticsearch.action.bulk.BulkProcessor.Listener, | ||
org.opensearch.action.bulk.BulkProcessor.Listener { | ||
private static final Logger LOG = LoggerFactory.getLogger(EsSink.class); | ||
private final RequestTracker requestTracker; | ||
|
||
public BulkListener(RequestTracker requestTracker) { | ||
this.requestTracker = requestTracker; | ||
} | ||
|
||
@Override | ||
public void beforeBulk(long executionId, org.elasticsearch.action.bulk.BulkRequest request) { | ||
LOG.debug("Sending bulk of {} actions to Elasticsearch.", request.numberOfActions()); | ||
} | ||
|
||
@Override | ||
public void afterBulk( | ||
long executionId, | ||
org.elasticsearch.action.bulk.BulkRequest request, | ||
org.elasticsearch.action.bulk.BulkResponse response) { | ||
if (response.hasFailures()) { | ||
String errMessage = | ||
String.format( | ||
"Bulk of %d actions failed. Failure: %s", | ||
request.numberOfActions(), response.buildFailureMessage()); | ||
this.requestTracker.addErrResult(errMessage); | ||
} else { | ||
this.requestTracker.addOkResult(request.numberOfActions()); | ||
LOG.debug("Sent bulk of {} actions to Elasticsearch.", request.numberOfActions()); | ||
} | ||
} | ||
|
||
/** This method is called when the bulk failed and raised a Throwable */ | ||
@Override | ||
public void afterBulk(long executionId, BulkRequest request, Throwable failure) { | ||
String errMessage = | ||
String.format( | ||
"Bulk of %d actions failed. Failure: %s", | ||
request.numberOfActions(), failure.getMessage()); | ||
this.requestTracker.addErrResult(errMessage); | ||
} | ||
|
||
@Override | ||
public void beforeBulk(long executionId, org.opensearch.action.bulk.BulkRequest request) { | ||
LOG.debug("Sending bulk of {} actions to Opensearch.", request.numberOfActions()); | ||
} | ||
|
||
@Override | ||
public void afterBulk( | ||
long executionId, | ||
org.opensearch.action.bulk.BulkRequest request, | ||
org.opensearch.action.bulk.BulkResponse response) { | ||
if (response.hasFailures()) { | ||
String errMessage = | ||
String.format( | ||
"Bulk of %d actions failed. Failure: %s", | ||
request.numberOfActions(), response.buildFailureMessage()); | ||
this.requestTracker.addErrResult(errMessage); | ||
} else { | ||
this.requestTracker.addOkResult(request.numberOfActions()); | ||
LOG.debug("Sent bulk of {} actions to Opensearch.", request.numberOfActions()); | ||
} | ||
} | ||
|
||
@Override | ||
public void afterBulk( | ||
long executionId, org.opensearch.action.bulk.BulkRequest request, Throwable failure) { | ||
String errMessage = | ||
String.format( | ||
"Bulk of %d actions failed. Failure: %s", | ||
request.numberOfActions(), failure.getMessage()); | ||
this.requestTracker.addErrResult(errMessage); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
91 changes: 91 additions & 0 deletions
91
...ingwave-sink-es-7/src/main/java/com/risingwave/connector/ElasticBulkProcessorAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
/* | ||
* Copyright 2024 RisingWave Labs | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.risingwave.connector; | ||
|
||
import com.risingwave.connector.EsSink.RequestTracker; | ||
import java.util.concurrent.TimeUnit; | ||
import org.elasticsearch.action.bulk.BackoffPolicy; | ||
import org.elasticsearch.action.bulk.BulkProcessor; | ||
import org.elasticsearch.action.delete.DeleteRequest; | ||
import org.elasticsearch.action.update.UpdateRequest; | ||
import org.elasticsearch.client.RequestOptions; | ||
import org.elasticsearch.common.unit.ByteSizeUnit; | ||
import org.elasticsearch.common.unit.ByteSizeValue; | ||
import org.elasticsearch.core.TimeValue; | ||
import org.elasticsearch.xcontent.XContentType; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
public class ElasticBulkProcessorAdapter implements BulkProcessorAdapter { | ||
private static final Logger LOG = LoggerFactory.getLogger(EsSink.class); | ||
BulkProcessor esBulkProcessor; | ||
private final RequestTracker requestTracker; | ||
|
||
public ElasticBulkProcessorAdapter( | ||
RequestTracker requestTracker, ElasticRestHighLevelClientAdapter client) { | ||
BulkProcessor.Builder builder = | ||
BulkProcessor.builder( | ||
(bulkRequest, bulkResponseActionListener) -> | ||
client.bulkAsync( | ||
bulkRequest, | ||
RequestOptions.DEFAULT, | ||
bulkResponseActionListener), | ||
new BulkListener(requestTracker)); | ||
// Possible feature: move these to config | ||
// execute the bulk every 10 000 requests | ||
builder.setBulkActions(1000); | ||
// flush the bulk every 5mb | ||
builder.setBulkSize(new ByteSizeValue(5, ByteSizeUnit.MB)); | ||
// flush the bulk every 5 seconds whatever the number of requests | ||
builder.setFlushInterval(TimeValue.timeValueSeconds(5)); | ||
// Set the number of concurrent requests | ||
builder.setConcurrentRequests(1); | ||
// Set a custom backoff policy which will initially wait for 100ms, increase exponentially | ||
// and retries up to three times. | ||
builder.setBackoffPolicy( | ||
BackoffPolicy.exponentialBackoff(TimeValue.timeValueMillis(100), 3)); | ||
this.esBulkProcessor = builder.build(); | ||
this.requestTracker = requestTracker; | ||
} | ||
|
||
@Override | ||
public void flush() { | ||
esBulkProcessor.flush(); | ||
} | ||
|
||
@Override | ||
public void awaitClose(long timeout, TimeUnit unit) throws InterruptedException { | ||
esBulkProcessor.awaitClose(timeout, unit); | ||
} | ||
|
||
@Override | ||
public void addRow(String index, String key, String doc) { | ||
UpdateRequest updateRequest; | ||
updateRequest = new UpdateRequest(index, "_doc", key).doc(doc, XContentType.JSON); | ||
updateRequest.docAsUpsert(true); | ||
this.requestTracker.addWriteTask(); | ||
this.esBulkProcessor.add(updateRequest); | ||
} | ||
|
||
@Override | ||
public void deleteRow(String index, String key) { | ||
DeleteRequest deleteRequest; | ||
deleteRequest = new DeleteRequest(index, "_doc", key); | ||
this.requestTracker.addWriteTask(); | ||
this.esBulkProcessor.add(deleteRequest); | ||
} | ||
} |
89 changes: 89 additions & 0 deletions
89
...e-sink-es-7/src/main/java/com/risingwave/connector/ElasticRestHighLevelClientAdapter.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
/* | ||
* Copyright 2024 RisingWave Labs | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
*/ | ||
|
||
package com.risingwave.connector; | ||
|
||
import java.io.IOException; | ||
import org.apache.http.HttpHost; | ||
import org.apache.http.auth.AuthScope; | ||
import org.apache.http.auth.UsernamePasswordCredentials; | ||
import org.apache.http.client.CredentialsProvider; | ||
import org.apache.http.impl.client.BasicCredentialsProvider; | ||
import org.elasticsearch.action.ActionListener; | ||
import org.elasticsearch.action.bulk.BulkRequest; | ||
import org.elasticsearch.action.bulk.BulkResponse; | ||
import org.elasticsearch.action.search.SearchRequest; | ||
import org.elasticsearch.action.search.SearchResponse; | ||
import org.elasticsearch.client.Cancellable; | ||
import org.elasticsearch.client.RequestOptions; | ||
import org.elasticsearch.client.RestClient; | ||
import org.elasticsearch.client.RestClientBuilder; | ||
import org.elasticsearch.client.RestHighLevelClient; | ||
import org.elasticsearch.client.RestHighLevelClientBuilder; | ||
|
||
public class ElasticRestHighLevelClientAdapter implements AutoCloseable { | ||
RestHighLevelClient esClient; | ||
|
||
private static RestClientBuilder configureRestClientBuilder( | ||
RestClientBuilder builder, EsSinkConfig config) { | ||
// Possible config: | ||
// 1. Connection path prefix | ||
// 2. Username and password | ||
if (config.getPassword() != null && config.getUsername() != null) { | ||
final CredentialsProvider credentialsProvider = new BasicCredentialsProvider(); | ||
credentialsProvider.setCredentials( | ||
AuthScope.ANY, | ||
new UsernamePasswordCredentials(config.getUsername(), config.getPassword())); | ||
builder.setHttpClientConfigCallback( | ||
httpClientBuilder -> | ||
httpClientBuilder.setDefaultCredentialsProvider(credentialsProvider)); | ||
} | ||
// 3. Timeout | ||
return builder; | ||
} | ||
|
||
public ElasticRestHighLevelClientAdapter(HttpHost host, EsSinkConfig config) { | ||
this.esClient = | ||
new RestHighLevelClientBuilder( | ||
configureRestClientBuilder(RestClient.builder(host), config) | ||
.build()) | ||
.setApiCompatibilityMode(true) | ||
.build(); | ||
} | ||
|
||
@Override | ||
public void close() throws IOException { | ||
esClient.close(); | ||
} | ||
|
||
public boolean ping(RequestOptions options) throws IOException { | ||
boolean flag = esClient.ping(options); | ||
return flag; | ||
} | ||
|
||
public Cancellable bulkAsync( | ||
BulkRequest bulkRequest, | ||
RequestOptions options, | ||
ActionListener<BulkResponse> listener) { | ||
Cancellable cancellable = esClient.bulkAsync(bulkRequest, options, listener); | ||
return cancellable; | ||
} | ||
|
||
public SearchResponse search(SearchRequest searchRequest, RequestOptions options) | ||
throws IOException { | ||
return this.esClient.search(searchRequest, options); | ||
} | ||
} |
Oops, something went wrong.