集群的理解
ES的集群和Redis 的集群在概念上都大差不离,都是主从分离机制他们都有一个容错机制
这个容错机制都是差不多的,当某个主分片宕机时这个主分片的备分片就会通过选举成为主分片,然后当这个新的主分片完成以后整个集群的状态就会变成黄色,因为少了一个备分片,然后当重启宕机的主机后,这个前主机就会变成备分片,然后新的主分片会自动去这个备分片中拷数据,这样做的好处是避免前主机宕机时同步延迟造成的一部分数据还没有同步过去的数据丢失问题
集群的搭建
不同的主机使用同样的端口不同的ip地址,同一台主机使用同一个ip不同的端口
配置说明:
- cluster.name
集群名,自定义集群名,默认为elasticsearch,建议修改,因为低版本多播模式下同一网段下相同集群名会自动加入同一集群,如生产环境这样易造成数据运维紊乱。
- node.name
节点名,同一集群下要求每个节点的节点名不一致,起到区分节点和辨认节点作用
- node.master
是否为主节点,选项为true或false,当为true时在集群启动时该节点为主节点,在宕机或任务挂掉之后会选举新的主节点,恢复后该节点依然为主节点
- node.data
是否处理数据,选项为true或false。负责数据的相关操作
- path.data
默认数据路径,可用逗号分隔多个路径
- path.logs
默认日志路径
- bootstrap.mlockall
内存锁,选项为true或false,用来确保用户在es-jvm中设置的ES_HEAP_SIZE参数内存可以使用一半以上而又不溢出
- network.host
对外暴露的host,0.0.0.0时暴露给外网
- http.port
对外访问的端口号,默认为9200,所以外界访问该节点一般为http://ip:9200/
- transport.tcp.port
集群间通信的端口号,默认为9300
- discovery.zen.ping.unicast.hosts
集群的ip集合,可指定端口,默认为9300,如 ["192.168.1.101","192.168.1.102"]
- discovery.zen.minimum_master_nodes
最少的主节点个数,为了防止脑裂,最好设置为(总结点数/2 + 1)个
- discovery.zen.ping_timeout
主节点选举超时时间设置
- gateway.recover_after_nodes
值为n,网关控制在n个节点启动之后才恢复整个集群
- node.max_local_storage_nodes
值为n,一个系统中最多启用节点个数为n
- action.destructive_requires_name
选项为true或false,删除indices是否需要现实名字
修改es配置
- Node1-配置
# 统一的集群名
cluster.name: my-ealsticsearch
# 当前节点名
node.name: node-1
# 对外暴露端口使外网访问
network.host: 127.0.0.1
# 对外暴露端口
http.port: 9201
#集群间通讯端口号
transport.tcp.port: 9301
#集群的ip集合,可指定端口,默认为9300
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
- Node2-配置
# 统一的集群名
cluster.name: my-ealsticsearch
# 当前节点名
node.name: node-2
# 对外暴露端口使外网访问
network.host: 127.0.0.1
# 对外暴露端口
http.port: 9202
#集群间通讯端口号
transport.tcp.port: 9302
#集群的ip集合,可指定端口,默认为9300
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
- Node3-配置
# 统一的集群名
cluster.name: my-ealsticsearch
# 当前节点名
node.name: node-3
# 对外暴露端口使外网访问
network.host: 127.0.0.1
# 对外暴露端口
http.port: 9203
#集群间通讯端口号
transport.tcp.port: 9303
#集群的ip集合,可指定端口,默认为9300
discovery.zen.ping.unicast.hosts: ["127.0.0.1:9301","127.0.0.1:9302","127.0.0.1:9303"]
分别启动三个ES节点 , 访问:http://127.0.0.1:9201/
连接集群
修改kibana配置
elasticsearch.url: "http://localhost:9201"
jpa操作ES
导入依赖
<dependency>
<groupId>org.elasticsearch.client</groupId>
<artifactId>transport</artifactId>
<version>5.2.2</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-api</artifactId>
<version>2.7</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>2.7</version>
</dependency>
编写工具
public class ESClientUtil {
public static TransportClient getClient(){
Settings settings = Settings.builder()
.put("cluster.name","my-ealsticsearch")
.put("client.transport.sniff", true).build();
TransportClient client = null;
try {
client = new PreBuiltTransportClient(settings)
.addTransportAddress(
new InetSocketTransportAddress(InetAddress.getByName("127.0.0.1"), 9303));
} catch (UnknownHostException e) {
e.printStackTrace();
}
return client;
}
}
添加文档
@Test
public void testAdd() {
//获取客户端对象
TransportClient client = ESClientUtil.getClient();
//创建索引
IndexRequestBuilder indexRequestBuilder = client.prepareIndex("shopping", "user", "1");
Map<String,Object> data = new HashMap<>();
data.put("id",1);
data.put("username","zs");
data.put("age",11);
//获取结果
IndexResponse indexResponse = indexRequestBuilder.setSource(data).get();
System.out.println(indexResponse);
client.close();
}
查询
@Test
public void testSearch() throws Exception{
//获取客户端对象
TransportClient client = ESClientUtil.getClient();
//设置需要查询的索引库
SearchRequestBuilder searchRequestBuilder = client.prepareSearch("shopping");
//设置类型表
searchRequestBuilder.setTypes("user");
//设置分页条件
searchRequestBuilder.setFrom(0);
searchRequestBuilder.setSize(10);
//设置排序条件
searchRequestBuilder.addSort("age", SortOrder.ASC);
//拼接组合
BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
//设置必须匹配的条件
List<QueryBuilder> must = boolQueryBuilder.must();
must.add(QueryBuilders.matchQuery("sex", "1"));
//设置过滤条件
List<QueryBuilder> filter = boolQueryBuilder.filter();
//设置范围
filter.add(QueryBuilders.rangeQuery("age").lte(20).gte(10));
//设置过滤的id
//filter.add(QueryBuilders.termQuery("id",11));
searchRequestBuilder.setQuery(boolQueryBuilder);
SearchResponse searchResponse = searchRequestBuilder.get();
SearchHits hits = searchResponse.getHits();
System.out.println("条数:"+hits.getTotalHits());
for (SearchHit hit : hits.getHits()) {
System.out.println(hit.getSource());
}
client.close();
}