Java鏈接ElasticSearch詳解

Java鏈接ES有兩種鏈接方式(即得到ES的Client)

一、建立一個node,加入集羣中,經過這個node得到client。node

二、經過TransportClient來鏈接集羣。git

區別

第一種方式,至關於額外啓動了一個es的node節點,只是這個node是由咱們編碼控制的,能夠設置成這個node是不存數據的節點(沒有特殊緣由你就應該這麼設置),這個節點的配置和其餘的節點沒有什麼區別,也是經過elasticsearch.yml文件來配置,配置文件放在classpath目錄下面,固然你也能夠經過編程的方式,在構建node的時候,設置settings參數。github

Settings settings = ImmutableSettings.settingsBuilder().put("client.transport.ping_timeout", 1000)
                .put("discovery.zen.ping.multicast.enabled", "false").put("timeout", 1)
                .putArray("discovery.zen.ping.unicast.hosts", "l-flightdev18.f.dev.cn0.qunar.com:9300", "l-flightdev17.f.dev.cn0.qunar.com:9300")
                .build();
        Node node = NodeBuilder.nodeBuilder().clusterName("flight_fuwu_order_index").client(true).settings(settings).node();
        Client client = node.client();

注意:client(true)很重要,這標示當前節點不存儲數據編程

方法一有個問題,若是服務和ES集羣不在一個機房,網絡延遲會致使做爲node節點接入ES集羣的服務成爲ES集羣的短板網絡

 

第二種方法,至關於獲取了全部node節點的client,發送請求的時候遍歷當前可用的client(這裏可用指的是能夠鏈接,可是node自己不必定可用,好比node正在恢復中,尚未加入集羣,這會產生問題,見下面)。跟方法一相比,方法二會產生雙跳(double hop),即當前遍歷到node1,但訪問的數據在node2,請求先發到node1,又由node1轉發到node2。elasticsearch

遍歷方式:每次請求經過AtomicInteger進行原子加1(超出最大值後設置成0),按當前可用client數取模。ui

獲取當前可用client的方法:使用線程池,遍歷全部client,若是client未鏈接,嘗試一次鏈接,鏈接成功加入可用client中,若是client已鏈接直接加入可用client。編碼

能夠經過設置參數client.transport.sniff是否爲true,來設置是使用SimpleNodeSampler仍是SniffNodesSampler,默認值爲false,即便用SimpleNodeSampler。spa

具體實如今org.elasticsearch.client.transport.TransportClientNodesService類中。線程

簡單的說,SimpleNodeSampler會限制當前可用client必定是在配置中設置的節點中的,而SniffNodesSampler會使用全部發現的client,即便這個client的node,不在配置中。

Settings settings = ImmutableSettings.settingsBuilder().put("cluster.name", clustersName).put(				"client.transport.ping_timeout", 1000).put("discovery.zen.ping.multicast.enabled", "false").put(				"timeout", 1)//				.put("client.transport.sniff", true)				.build();

		TransportClient transportClient = new TransportClient(settings);		for (String cluster : StringUtils.split(clusters,",")) {
			transportClient.addTransportAddress(new InetSocketTransportAddress("host1", 9300))
        .addTransportAddress(new InetSocketTransportAddress("host2", 9300));
		}

方法二有個問題,就是當集羣中某個node掛掉以後,從新加入的時候,由於是經過判斷client是否能夠鏈接,而不是node是否可用,這會致使這個時候使用這個client發送請求的時候產生異常。而方法一不會,由於還沒加入集羣的node,對於本身建立的node來講是不可見的。gitbub上有對這個問題的討論:https://github.com/elastic/elasticsearch/issues/11202

相關文章
相關標籤/搜索