节点客户端(node client):
节点客户端本身也是一个ES节点(一般不保存数据,不能成为主节点),它能以无数据节点身份加入到集群中。因为它是集群环境中的一个节点,所以它知道整个集群状态(所有节点驻留,分片分布在哪些节点等等), 可以把需要执行的操作自动路由到节点上,而少一个网络跃点。
Node node = NodeBuilder.nodeBuilder().local(true).node() ;
Client client = node.client();
GetResponse getResponse = client.prepareGet(index,type,"2").get();
System.out.println(JSONObject.toJSONString(getResponse));
当你启动node时,你可以在你的项目/src/main/resources/elasticsearch.yml文件中定义简单的设置cluster.name或者明确地使用clusterName
方法来加入到指定的集群中。
使用elasticsearch.yml的方式: cluster.name: yourclustername
通过Java的方式:
Node node = NodeBuilder.nodeBuilder().clusterName("elasticsearch").local(true).node() ;
使用节点客户端的好处是,操作可以自动地路由到这些操作被执行的节点,而不需要执行双跳(double hop)。例如,索引操作将会在该操作最终存在的分片上执行。
当你启动了一个节点,最重要的决定是它是否将保有数据。大多数情况下,我们仅仅需要用到clients,而不需要分片分配给它们。这可以通过设置node.data
为false
或者设置node.local
为true
来简单实现。
Node node = NodeBuilder.nodeBuilder().local(true).node() ;
Client client = node.client();
传输客户端(Transport Client)
作为更轻量的传输客户端能够请求到远程集群。它自己不加入集群,只是简单的获得一个或者多个初始化的transport
地址,并以轮询的方式与这些地址进行通信。比较像传统的CS程序的架构,比如数据库连接。
Settings settings = Settings.builder()
.put("cluster.name","my-application") .build();
TransportClient client = TransportClient.builder()
.settings(settings).build()
.addTransportAddress(newInetSocketTransportAddress(InetAddress.getByName("ip"),9300));
传输客户端可以嗅到集群的其他部分,并将它们加入到机器列表。为了开启该功能,可以设置client.transport.sniff
为true
。
其他的transfersport客户端设置有如下几个:
client.transport.ignore_cluster_name
:true
:忽略连接节点的集群名验证
client.transport.ping_timeout
一个节点的响应时间,默认是5s
client.transport.nodes_sampler_intervalsample/ping
节点的时间间隔,默认是5s
节点客户端与传输客户端的区别
- 第一种方式,相当于额外启动了一个ES的
node
节点,这个节点和集群中的其他节点没有任何区别。只是这个node
是由我们编码控制的,可以设置这个node
是不存数据的节点(没有特殊原因你就应该这个设置)。
- 第二种方法,相当于获取了所有
node
节点的client
,发送请求的时候遍历当前可用的client
(这里可用指的是可以连接,但是node
本身不一定可用,比如node
正在恢复中,还没有加入到集群,这就会产生问题。)跟方法一相比,方法二会产生双跳(double hop),即当前遍历到node1,但访问的数据在node2,请求先转发到node1,又由node1转发到node2。
遍历方式:每次请求通过AtomicInteger
进行原子加1(超过最大值后设置为0),按当前可用client
数取模。
获取当前可用client的方法:使用线程池,遍历当前可用client
,如果client
未连接,尝试进行一次连接,连接成功加入可用client
中,如果client
已经连接直接加入可用client
。
可以通过设置client.transport.sniff
是否为true
,来设置是使用SimpleNodeSampler
还是SniffNOdesSampler
,默认是false
,就是使用SimpleNodeSampler
。具体实现在org.elasticsearch.client.transport.TransportClientNodesService
中。
简单的说,SimpleNodeSampler
会限制当前可用client
一定是在配置中设置的节点。而SniffNodesSampler
会使用所有发现的client
,即使这个client
的node
,不在配置中。
当集群中某个node
挂掉之后,重新加入的时候,因为是通过判断client
是否可以连接,而不是node
是否可用,这会导致这个时候使用这个client
发送请求的时候产生异常。而方法一不会,因为还没加入集群的node
,对于自己创建的node
来说是不可见的。
使用情况
如果要将应用程序和Elasticsearch集群进行解耦,传输客户端是一个理想的选择。例如 如果你的应用程序需要快速的创建和销毁到集群的链接,传输客户端比节点客户端更"轻",因为它不是集群的