8.3 JavaAPI操作集群
-
java API想操作集群只需要更改配置,建立连接,增删改查均不变。
-
springboot项目
application.yml
#standonlne 单机192.168.149.135
elasticsearch:
host: 127.0.0.1
port: 9200
#cluster 集群配置
#elasticsearch:
# host1: 127.0.0.1
# port1: 9201
# host2: 127.0.0.1
# port2: 9202
# host3: 127.0.0.1
# port3: 9203
# datasource
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/elasticsearch?serverTimezone=UTC
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
# mybatis
mybatis:
mapper-locations: classpath:mapper/*Mapper.xml # mapper映射文件路径
type-aliases-package: com.itheima.elasticsearch2.domain
# config-location: # 指定mybatis的核心配置文件
ElasticSearchClusterConfig.java
package com.itheima.elasticsearch2.config;
import org.apache.http.HttpHost;
import org.elasticsearch.client.RestClient;
import org.elasticsearch.client.RestHighLevelClient;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
@ConfigurationProperties(prefix = "elasticsearch")
public class ElasticSearchClusterConfig {
private String host1;
private int port1;
private String host2;
private int port2;
private String host3;
private int port3;
public String getHost1() {
return host1;
}
public void setHost1(String host1) {
this.host1 = host1;
}
public int getPort1() {
return port1;
}
public void setPort1(int port1) {
this.port1 = port1;
}
public String getHost2() {
return host2;
}
public void setHost2(String host2) {
this.host2 = host2;
}
public int getPort2() {
return port2;
}
public void setPort2(int port2) {
this.port2 = port2;
}
public String getHost3() {
return host3;
}
public void setHost3(String host3) {
this.host3 = host3;
}
public int getPort3() {
return port3;
}
public void setPort3(int port3) {
this.port3 = port3;
}
@Bean
public RestHighLevelClient client(){
return new RestHighLevelClient(RestClient.builder(
new HttpHost(
host1,
port1,
"http"
),
new HttpHost(
host2,
port2,
"http"
),
new HttpHost(
host3,
port3,
"http"
)
));
}
}
8.4 ES集群介绍
-
集群和分布式
-
• 集群:多个人做一样的事。
-
• 分布式:多个人做不一样的事。
-
-
集群解决的问题:
-
• 让系统高可用
-
• 分担请求压力 分布式解决的问题:
-
• 分担存储和计算的压力,提速
-
• 解耦
-
-
ElasticSearch 集群分布式架构相关概念
-
• 集群(cluster):一组拥有共同的cluster name 的 节点。
-
• 节点(node) :集群中的一个Elasticearch 实例
-
• 索引(index) :es存储数据的地方。相当于关系数据库中的database概念
-
• 分片(shard):索引可以被拆分为不同的部分进行存储,称为分片。在集群环境下,一个索引的不同分片可以拆分到不同的节点中,相当于mysql分库。
-
• 主分片(Primary shard):相对于副本分片的定义。
-
• 副本分片(Replica shard)每个主分片可以有一个或者多个副本,数据和主分片一样。
-
-
集群原理-分片配置
-
• 在创建索引时,如果不指定分片配置,则默认主分片1,副本分片1。
-
• 在创建索引时,可以通过settings设置分片
-
• 分片与自平衡:当节点挂掉后,挂掉的节点分片会自平衡到其他节点中
-
• 在Elasticsearch 中,每个查询在每个分片的单个线程中执行,但是,可以并行处理多个分片。
-
• 分片数量一旦确定好,不能修改。
-
• 索引分片推荐配置方案: 1. 每个分片推荐大小10-30GB 2. 分片数量推荐 = 节点数量 * 1~3倍
-
思考:比如有1000GB数据,应该有多少个分片?多少个节点 ?
答: 40个分片 20个节点
-
###kibana 脚本 #创建索引时设置分片 PUT test_index { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "properties": { "name": {"type": "text"} } } }
#创建索引时设置分片 PUT test_index { "settings": { "number_of_shards": 3, "number_of_replicas": 1 }, "mappings": { "properties": { "name": {"type": "text"} } } }
-
-
集群原理-路由原理
-
• 文档存入对应的分片,ES计算分片编号的过程,称为路由。
-
• Elasticsearch是怎么知道一个文档应该存放到哪个分片中呢?
-
• 查询时,根据文档id查询文档,Elasticsearch 又该去哪个分片中查询数据呢?
-
• 路由算法 :shard_index = hash(id) % number_of_primary_shards
-
8.5 脑裂
-
• 一个正常es集群中只有一个主节点(Master),主节点负责管理整个集群。如创建或删除索引,跟踪哪些节点是群 集的一部分,并决定哪些分片分配给相关的节点。
-
• 集群的所有节点都会选择同一个节点作为主节点。
-
• 脑裂问题的出现就是因为从节点在选择主节点上出现分歧导致一个集群出现多个主节点从而使集群分裂,使得集群 处于异常状态。
脑裂原因
-
网络原因:网络延迟 • 一般es集群会在内网部署,也可能在外网部署,比如阿里云。 • 内网一般不会出现此问题,外网的网络出现问题的可能性大些。
-
节点负载 • 主节点的角色既为master又为data。数据访问量较大时,可能会导致Master节点停止响应(假死状态)。
##elasticsearch.yml 配置
#是否有资格选举为主节点
node.master=true
#是否存储数据
node.data=true
-
JVM内存回收 • 当Master节点设置的JVM内存较小时,引发JVM的大规模内存回收,造成ES进程失去响应。
避免脑裂
-
网络原因:discovery.zen.ping.timeout超时时间配置大一点。默认是3S
-
节点负载:角色分离策略
• 候选主节点配置为 • node.master: true • node.data: false
• 数据节点配置为 • node.master: false • node.data: true
-
JVM内存回收:修改 config/jvm.options 文件的 -Xms 和 -Xmx 为服务器的内存一半。
8.6 集群扩容
-
修改节点名称itcast-1...4
-
node.max_local_storage_nodes = 4
-
discovery.seed_hosts: ["localhost:9700","localhost:9800","localhost:9900","localhost:9600"]
-
cluster.initial_master_nodes: ["itcast-1", "itcast-2","itcast-3","itcast-4"]
-
9204, 9600
-
注意:其他三个节点ES,discovery.seed_hosts 和 cluster.initial_master_nodes 和 node.max_local_storage_nodes 也要做出调整。
-
配置修改好后,四台ES重启即可。
#集群名称
cluster.name: itcast-es
#节点名称
node.name: itcast-4
#是不是有资格主节点
node.master: true
#是否存储数据
node.data: true
#最大集群节点数
node.max_local_storage_nodes: 4
#ip地址
network.host: 0.0.0.0
#端口
http.port: 9204
#内部节点之间沟通端口
transport.tcp.port: 9600
#es7.x 之后新增的配置,节点发现
discovery.seed_hosts: ["localhost:9700","localhost:9800","localhost:9900","localhost:9600"]
#es7.x 之后新增的配置,初始化一个新的集群时需要此配置来选举master
cluster.initial_master_nodes: ["itcast-1", "itcast-2","itcast-3","itcast-4"]
#数据和存储路径
path.data: /opt/data
path.logs: /opt/logs