本文主要参考尚硅谷的资料,少部分自己原创,有错误之处请指出。
单节点集群
node-1001配置如下:
# 集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
# 节点名称,集群内要唯一
node.name: node-1001
# 表示节点是否具有成为主节点的资格(此属性的值为true,并不意味着这个节点就是主节点)
node.master: true
# 表示节点是否存储数据
node.data: true
# IP地址
network.host: localhost
# http端口
http.port: 1001
# tcp监听端口(节点间通信端口)
transport.tcp.port: 9301
# 该节点会与哪些候选地址进行通信
#discovery.seed_hosts: ["localhost:9301", "localhost:9302", "localhost:9303"]
# 集群内可以被选为主节点的节点列表
#cluster.initial_master_nodes: ["node-1001", "node-1002", "node-1003"]
# 是否支持跨域,默认为false(因为我们接下来要使用elasticsearch-head插件连接es服务)
http.cors.enabled: true
# 当设置允许跨域,默认为*,表示支持所有域名,如果我们只是允许某些网站能访问,那么可以使用正则表达式。比如只允许本地地址。 /https?:\/\/localhost(:[0-9]+)?/
http.cors.allow-origin: "*"
坑1:如果之前启动过此 ES 服务,需要删除 data文件夹以及logs里面的所有日志,否则可能配置失效
坑2:discovery.seed_hosts以及cluster.initial_master_nodes不需要配置,否则访问此 ES 服务会报错找不到主节点,其实和坑3的出现是一个原因。
我们创建名为 user 的索引,为了演示目的,我们将分配3个主分片和一份副本(每个主分片拥有一个副本份片)
{
"settings" : {
"number_of_shards" : 3,
"number_of_replicas" : 1
}
}
我们的集群现在是拥有一个索引的单节点集群。所有 3 个主分片都被分配在 node-1。
通过 elasticsearch-head 插件查看集群情况
可以看到,三个副本分片都没有被分配到任何节点。在同一个节点上即保存原始数据又保存副本是没有意义的,因为一旦失去了那个节点,我们也将丢失该节点上的所有副本数据。
故障转移
当集群中只有一个节点在运行时,意味着会有一个单点故障问题——没有冗余。幸运的是,我们只需要再启动一个节点即可防止数据丢失。当你在同一台机器上启动了第二个节点时,只要它和第一个节点有同样的 cluster.name 配置,它就会自动发现集群并加入其中。但是在不同机器上启动节点的时候,为了加入到统一集群,你需要配置一个可连接到的单播主机列表。之所以配置为使用单播发现,以防止节点无意中加入集群。
如果启动了两个节点,我们的集群将会拥有两个节点的集群:所有主分片和副本分片都被分配。
node-1002配置如下:
# 集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
# 节点名称,集群内要唯一
node.name: node-1002
# 表示节点是否具有成为主节点的资格(此属性的值为true,并不意味着这个节点就是主节点)
node.master: true
# 表示节点是否存储数据
node.data: true
# IP地址
network.host: localhost
# http端口
http.port: 1002
# tcp监听端口(节点间通信端口)
transport.tcp.port: 9302
# 该节点会与哪些候选地址进行通信
discovery.seed_hosts: ["localhost:9301"]
# 集群内可以被选为主节点的节点列表
#cluster.initial_master_nodes: ["node-1001", "node-1002", "node-1003"]
# 是否支持跨域,默认为false(因为我们接下来要使用elasticsearch-head插件连接es服务)
http.cors.enabled: true
# 当设置允许跨域,默认为*,表示支持所有域名,如果我们只是允许某些网站能访问,那么可以使用正则表达式。比如只允许本地地址。 /https?:\/\/localhost(:[0-9]+)?/
http.cors.allow-origin: "*"
通过 elasticsearch-head 插件查看集群情况
水平扩容
怎样为我们的正在增长中的应用程序按需扩容呢?当启动了第三个节点,我们的集群会拥有三个节点的集群:为了分散负载而对分片进行重新分配。
node-1003配置如下:
# 集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
# 节点名称,集群内要唯一
node.name: node-1003
# 表示节点是否具有成为主节点的资格(此属性的值为true,并不意味着这个节点就是主节点)
node.master: true
# 表示节点是否存储数据
node.data: true
# IP地址
network.host: localhost
# http端口
http.port: 1003
# tcp监听端口(节点间通信端口)
transport.tcp.port: 9303
# 该节点会与哪些候选地址进行通信
discovery.seed_hosts: ["localhost:9301", "localhost:9302"]
# 集群内可以被选为主节点的节点列表
# cluster.initial_master_nodes: ["node-1001", "node-1002", "node-1003"]
# 是否支持跨域,默认为false(因为我们接下来要使用elasticsearch-head插件连接es服务)
http.cors.enabled: true
# 当设置允许跨域,默认为*,表示支持所有域名,如果我们只是允许某些网站能访问,那么可以使用正则表达式。比如只允许本地地址。 /https?:\/\/localhost(:[0-9]+)?/
http.cors.allow-origin: "*"
通过 elasticsearch-head 插件查看集群情况:
Node1 和 Node2 上各有一个分片被迁移到了新的 Node3 节点,现在每个结点上都拥有2个分片,而不是之前的3个。这表示每个节点的硬件资源(CPU,RAM,I/O)将被更少的分片所共享,每个分片的性能将会得到提升。
分片是一个功能完善的搜索引擎,它拥有使用一个节点上所有资源的能力。我们这个拥有6个分片(3主3副)的索引可以扩容到6个节点,每个节点上存在一个分片,并且每个分片拥有所在节点的全部资源。
但是如果我们想要扩容超过6个节点怎么办?
主分片的数目在索引创建时就已经确定了下来。实际上,这个数目定义了这个索引能够存储的最大数据量。(实际大小取决于你的数据、硬件和使用场景。)但是,读操作和返回数据可以同时被主分片或副本分片所处理,所以当你拥有越多的副本分片时,也将拥有越高的吞吐量。
在运行中的集群上是可以动态调整副本分片数目的,我们可以按需伸缩群。让我们把副本数从默认的 1 增加到 2
{
"number_of_replicas": 2
}
user索引现在拥有9个分片:3主6副。这意味着我们可以将集群扩容到9个节点每个节点上一个分片。相比原来 3 个节点时,集群搜索性能可以提升 3 倍
通过 elasticsearch-head 插件查看集群情况:
当然,如果只是在相同节点数据的集群上增加更多的副本并不能提高性能,因为每个分片从节点上获得的资源会变少。你需要增加更多的硬件资源来提升吞吐量。
但是更多的副本分片数提高了数据冗余量:按照上面节点配置,我们可以在失去 2 个节点的情况下不丢失任何数据。
应对故障
我们关闭第一个节点,这时集群的状态为:关闭了一个节点后的集群。
我们关闭的节点是一个主节点。而集群必须拥有一个主节点来保证正常工作,所以发生的第一件事情就是选举集群的主节点:node-1002。在我们关闭 Node-1001 的同时也失去了主分片2,并且在缺失主分片的时候索引也不能正常工作。如果此时来检查集群的状况,我们看到的状态将会为red:不是所有主分片都在正常工作。
幸运的是,在其他节点上存在着这个主分片的完整副本,所以新的主节点立即将这些分片在node-1002和node-1003上对应的副本分片提升为主分片,此时集群的状态将会为yellow。这个提升主分片的过程是瞬间发生的,如同按下一个开关一般。
为什么我们集群状态是 yellow 而不是 green 呢?
虽然我们拥有所有的三个主分片,但是同时设置了每个主分片需要对应 2 份副本分片,而此时只存在一份副本分片。所以集群不能为 green 的状态。
坑3:当你关闭了两个节点的时候,第三个节点是无法操作访问的,这里涉及到另外一个知识点:discovery.zen.minimum_master_nodes,感兴趣的朋友可以再研究一下。
如果我们重新启动node-1001,集群可以将缺失的副本分片再次进行分配,那么集群的状态也将恢复成之前的状态。如果node-1001依然拥有着之前的分片,它将尝试去重用它们,同时仅从主分片复制发生了修改的数据文件。和之前的集群相比,只是 master 节点切换了。
注意:重启node-1001的之前添加配置:discovery.seed_hosts: [“localhost:9302”, “localhost:9303”],用来发现node-1002和node-1003节点
路由计算
当索引一个文档的时候,文档会被存储到一个主分片中。Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?当我们创建文档时,它如何决定这个文档应该被存放在分片 1 还是分片 2 中呢?首先这肯定不是随机的,否则将来要获取文档的时候我们就不知道从何处寻找了。实际上,这个过程是根据下面这个公式决定的:
分片 = hash(routing) % 主分片数量
routing 是一个可变值,默认是文档的 _id,也可以设置成一个自定义值。routing 通过 hash 函数生成一个数字,然后这个数字再除以主分片的数量后得到余数。这个分布在 0 到 主分片数量 -1 之间的余数,就是我们所寻求的文档所在分片的位置。
这就解释了为什么我们在创建索引的时候就确定好主分片的数量,并且永远不会改变这个数量:因为数量变化了,那么之前路由的值会无效,文档也再也找不到了。文章来源:https://www.toymoban.com/news/detail-494415.html
所有的文档API(get、index、delete、bulk、update以及mget)都接受一个叫做 routing 的路由参数,通过这个参数我们可以自定义文档到分片的映射。一个自定义的路由参数可以用来确保所有相关的文档(例如:所有属于同一个用户的文档)一一都被存储到同一个分片中。文章来源地址https://www.toymoban.com/news/detail-494415.html
到了这里,关于【ES】分布式集群的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!