ElasticSearch 应用开发(四)Java Client 连接ElasticSearch集群方法的对比与总结

ElasticSearch 应用开发(二)Java Client 连接ElasticSearch集群

ElasticSearch 应用开发(三)基于commons-pool2和TransportClient的ElasticSearch连接池

上述内容,介绍java client连接Elasticsearch的方法,简单做一个对比和总结


1.对比

1.1单线程测试获取连接地址

(a)TransportClient

/**
 * 单线程 创建一个简单的TransportClient连接
 */
@Test
public void testTransportClient() {
	for (int i = 0; i < 10; i++) {
		Client client = TransportClientBuild.getClient();
		System.out.println(("连接对象————地址:" + client));

	}
}

结果如下: 

 (b)Rest Client

@Test
public void testLowLevelClient() {
	for (int i = 0; i < 10; i++) {
		System.out.println(LowLevelClient.getClient().toString());
	}
}

@Test
public void testHighLevelClient() {
	try {
		for (int i = 0; i < 10; i++) {
			System.out.println(HighLevelClient.getClient().toString());
		}
	} catch (Exception e) {
		e.printStackTrace();
	}
}

结果如下: 

(c)分析

简单for循环获取连接地址,经过简单对比,可知:

1.每次获取TransportClient地址是同一个,针对其做池化有一定的意义,高并发环境下,提高系统稳定性;

2.每次获取Rest Low Level Client和Rest High Level Client地址不同,针对其做做池化技术,意义并不是很大; 

1.2多线程条件下 ,测试获取连接地址

(a)TransportClient

public void testTransprotClient() {

	//System.out.println(TransportClientBuild.getClient());
	System.setProperty("es.set.netty.runtime.available.processors", "false");

	ExecutorService executorService = new ThreadPoolExecutor(10, 10,
			0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

	for (int i = 0; i < 10; i++) {
		int index = i;

		if (!executorService.isShutdown()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					Client client = TransportClientBuild.getClient();
					System.out.println(("第" + index + "次获取到了连接对象————地址:" + client));
				}
			});
		}

	}
	executorService.shutdown();

	try {
		while (!executorService.awaitTermination(10000, TimeUnit.MILLISECONDS)) {
			System.out.println("10秒没有执行完,强制关闭线程池");
			executorService.shutdownNow();
		}
	} catch (Exception e) {
		e.printStackTrace();
	}

}

结果:

 (b)Rest Client

@Test
public void testRestClient() {

	//System.out.println(TransportClientBuild.getClient());
	System.setProperty("es.set.netty.runtime.available.processors", "false");

	ExecutorService executorService = new ThreadPoolExecutor(10, 10,
			0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());

	for (int i = 0; i < 10; i++) {
		int index = i;

		if (!executorService.isShutdown()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					System.out.println(("第" + index + "次获取到了连接对象————地址:" + HighLevelClient.getClient().toString()));
				}
			});
		}

	}
	executorService.shutdown();

	try {
		while (!executorService.awaitTermination(10000, TimeUnit.MILLISECONDS)) {
			System.out.println("10秒没有执行完,强制关闭线程池");
			executorService.shutdownNow();
		}
	} catch (Exception e) {
		e.printStackTrace();
	}

}

结果:

(c)分析

使用多线程条件下,获取TransportClient和Rest Client 地址,每次地址都不同。由此,可以判断多线程条件下两个连接方式都能够胜任稍微复杂的业务。

1.3 多线程条件下,测试连接池

针对 ElasticSearch 应用开发(三)基于commons-pool2和TransportClient的ElasticSearch连接池构建的连接池,在多线程环境下进行测试。

代码:

/**
 * 多线程线程池测试TransportClient连接池
 */
@Test
public void testESPoolClient() {

	/*配置节点熟悉*/
	Set<TransportClientNodeConfig> nodeSets = TransportClientPoolConfig.getNodesConfig();

	AtomicReference<Set<TransportClientNodeConfig>> nodesReference = new AtomicReference<Set<TransportClientNodeConfig>>();
	nodesReference.set(nodeSets);

	/*配置线程池熟悉*/
	TransportClientPoolConfig transportClientPoolConfig = new TransportClientPoolConfig();

	final TransportClientPool pool = new TransportClientPool(nodesReference, transportClientPoolConfig);

	System.setProperty("es.set.netty.runtime.available.processors", "false");

	LinkedBlockingQueue<Runnable> linkBlockingQuene = new LinkedBlockingQueue<Runnable>();
	ExecutorService cachedThreadPool = new ThreadPoolExecutor(10, 10, 0L, TimeUnit.MILLISECONDS, linkBlockingQuene);
	for (int i = 0; i < 15; i++) {
		cachedThreadPool.execute(new Runnable() {

			@Override
			public void run() {
				TransportClient client = null;
				try {
					client = pool.getResource();
					System.out.println("当前线获取线程地址:" + client.toString());
				} catch (Exception e) {
					e.printStackTrace();
				} finally {
					pool.returnResource(client);
				}
			}
		});
	}
	cachedThreadPool.shutdown();

	try {
		while (!cachedThreadPool.awaitTermination(10000, TimeUnit.MILLISECONDS)) {
			System.out.println("10秒没有执行完,强制关闭线程池");
			cachedThreadPool.shutdownNow();
		}
	} catch (InterruptedException e) {
		e.printStackTrace();
	}
}

结果:

 分析:

多线程条件下,使用线程池,测试获取连接地址,每次地址都不一样.

2.总结

2.1针对TransportClient

若业务比较简单,连接ElasticSearch集群需求比较少,可以直接连接;

业务复杂,情况下,务必注意线程的使用,尽量在不同的线程中调用client;

当然,业务的增加,也可以使用连接池的形式,可以应对高并发的需求;

2.2针对Rest Client

连接就行了,建议Elasticsearch6.x之后,开始使用,应该能够解决绝大部分业务需求;

 

说明,以上代码都可以在github上找得到:

https://github.com/codersfarm/elasticsearch/tree/master/elasticsearch5.x

https://github.com/codersfarm/elasticsearch/tree/master/elasticsearch6.x

要使用ElasticsearchJava API连接Elasticsearch集群,需要添加以下三个依赖:org.elasticsearch.client.elasticsearch-rest-high-level-client、org.elasticsearch.client:elasticsearch-rest-client、org.elasticsearch:elasticsearch。这些依赖可以通过Maven或Gradle添加到项目中。接下来,可以使用ElasticsearchJava API编写代码来连接Elasticsearch集群。具体步骤如下: 1. 创建RestHighLevelClient对象,该对象是与Elasticsearch集群进行通信的主要入口点。 2. 创建IndexRequest对象,该对象表示要索引的文档。 3. 使用IndexRequest对象设置索引名称、文档类型和文档ID等信息。 4. 使用IndexRequest对象设置要索引的文档内容。 5. 使用RestHighLevelClient对象执行IndexRequest对象,将文档索引到Elasticsearch集群中。 下面是一个示例代码,用于将文档索引到Elasticsearch集群中: ```java import org.elasticsearch.action.index.IndexRequest; import org.elasticsearch.action.index.IndexResponse; import org.elasticsearch.client.RequestOptions; import org.elasticsearch.client.RestHighLevelClient; import org.elasticsearch.common.xcontent.XContentType; import org.elasticsearch.index.IndexNotFoundException; import org.elasticsearch.rest.RestStatus; import java.io.IOException; public class ElasticsearchExample { private RestHighLevelClient client; public ElasticsearchExample(RestHighLevelClient client) { this.client = client; } public void indexDocument(String index, String type, String id, String json) throws IOException { IndexRequest request = new IndexRequest(index, type, id); request.source(json, XContentType.JSON); IndexResponse response = client.index(request, RequestOptions.DEFAULT); if (response.status() == RestStatus.CREATED) { System.out.println("Document indexed successfully"); } else { System.out.println("Failed to index document"); } } public static void main(String[] args) throws IOException { RestHighLevelClient client = new RestHighLevelClient(/* Elasticsearch连接配置 */); ElasticsearchExample example = new ElasticsearchExample(client); example.indexDocument("my_index", "my_type", "1", "{\"name\":\"John Doe\",\"age\":25}"); client.close(); } }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值