欢迎大家关注公众号「JAVA前线」查看更多精彩分享文章,主要包括源码分析、实际应用、架构思维、职场分享、产品思考等等,同时欢迎大家加我微信「java_front」一起交流学习
类比关系型数据库概念:数据库(database)
类比关系型数据库概念:表(table),类型这个概念已经逐步被官方弱化,7.X不再支持自定义类型,默认类型是_doc,在类型弱化之后也可以把索引(Index)类比为表
类比关系型数据库概念:行(row)
类比于关系型数据库分库后数据分片,当一个索引数据量过大时,可以将一个索引拆分为多个数据集合,每一个数据集合只有一部分数据,这种数据集合称为分片
主分片可以有一个或多个副分片,副本有两个作用:第一可以承担读流量,提高系统吞吐量。第二可以提高可用性,如果主分片出现问题,副分片可以晋升为主分片
一个节点资源是有限的,当数据量和流量达到超过单节点负载时,可以将多个节点组成一个集群,共同承担流量
根据上述概念提出两个问题:
为了回答上述两个问题,我们首先搭建实验环境,本次实验使用windows环境,ES使用7.11版本。
ES官网下载64位版本并分别解压到三个文件夹:
编辑文件es-node1/config/elasticsearch.yml
# 集群信息
cluster.name: java-front-cluster
# 节点信息
node.name: es-node-1
node.master: true
node.data: true
network.host: localhost
http.port: 8001
# 通信端口
transport.tcp.port: 9001
discovery.zen.ping.unicast.hosts: ["localhost:9001", "localhost:9002", "localhost:9003"]
# 跨域配置
http.cors.enabled: true
http.cors.allow-origin: "*"
编辑文件es-node2/config/elasticsearch.yml
# 集群信息
cluster.name: java-front-cluster
# 节点信息
node.name: es-node-2
node.master: true
node.data: true
network.host: localhost
http.port: 8002
# 通信端口
transport.tcp.port: 9002
discovery.zen.ping.unicast.hosts: ["localhost:9001", "localhost:9002", "localhost:9003"]
# 跨域配置
http.cors.enabled: true
http.cors.allow-origin: "*"
编辑文件es-node3/config/elasticsearch.yml
# 集群信息
cluster.name: java-front-cluster
# 节点信息
node.name: es-node-3
node.master: true
node.data: true
network.host: localhost
http.port: 8003
# 通信端口
transport.tcp.port: 9003
discovery.zen.ping.unicast.hosts: ["localhost:9001", "localhost:9002", "localhost:9003"]
# 跨域配置
http.cors.enabled: true
http.cors.allow-origin: "*"
连续双击下列脚本启动三个节点:
es-node-1/bin/elasticsearch.bat
es-node-2/bin/elasticsearch.bat
es-node-3/bin/elasticsearch.bat
如果只启动一个节点会出现错误:master节点无法发现或者选举,选举需要至少两个节点
[es-node-1] master not discovered or elected yet, an election requires at least 2 nodes
此时依次启动节点二和三就可以解决这个问题。
节点一选举为主节点
GET http://localhost:8001/_cat/nodes
127.0.0.1 34 84 30 dilmrt * es-node-1
127.0.0.1 25 84 31 dilmrt - es-node-2
127.0.0.1 26 84 19 dilmrt - es-node-3
创建订单索引,包含三个分片和两个副本
PUT http://localhost:8001/order
{
"settings": {
"number_of_shards": 3,
"number_of_replicas": 2
}
}
// 响应结果
{
"acknowledged": true,
"shards_acknowledged": true,
"index": "order"
}
一个集群有三个节点,订单索引有三个分片,每个分片有两个副本,这些分片如何分布在集群?
通过扩展程序商店安装Chrome浏览器插件ElasticSearch Head,运行插件并输入节点一地址:

es-node-1
order索引有三个主分片,分别对应加粗0、1、2三个分片
P0、P1在节点一,P2在节点二
P0有两个副分片R0,分配在节点二和节点三
P1有两个副分片R1,分配在节点二和节点三
P2有两个副分片R1,分配在节点一和节点三
集群健康值有三种颜色:绿色、黄色、红色
关闭节点es-node-3并通过插件查看:

集群信息发生变化:
再关闭节点es-node-2并通过插件查看:

集群信息发生变化:
当请求访问ES集群,怎么确定数据在哪一个分片?
order索引有三个分片,现在新增orderId=100订单数据,这条数据应该保存在哪个分片?
路由规则公式:
shard_number = hash(routing) % number_of_primary_shards
本实例路由公式:
shard_num = hash(100) % 3
路由公式参数说明:
本实例集群中有三个节点,当客户端发送请求至集群,应该发送请求到哪一个节点呢?
客户端也不知道应该发送给哪一个节点,所以会发送至任意一个节点,由这个节点决定处理还是转发,这个节点就是协调节点。
本章节沿用第二章节集群信息:

orderId=100写请求流程:
orderId=100读请求流程:
这个问题可以类比关系型数据库分库分表,读取是不指定shardingKey会怎么样?答案是会扫描全库全表。ES搜索过程可以分为Query和Fetch两个阶段:
第一本文介绍了ES基本概念并提出了两个问题,第二本文为了回答这两个问题搭建了ES集群,第三本文通过六个维度回答了第一个问题,第四本文通过五个维度回答了第二个问题,希望本文对大家有所帮助。
欢迎大家关注公众号「JAVA前线」查看更多精彩分享文章,主要包括源码分析、实际应用、架构思维、职场分享、产品思考等等,同时欢迎大家加我微信「java_front」一起交流学习