一、建立一個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