Elasticsearch教程 — 集群/分片/副本/水平扩容/优化

集群安装与配置

单台节点往往性能有限、磁盘有限、并发有限。

修改集群文件目录中每个节点的 config/elasticsearch.yml 配置文件

#节点 1 的配置信息:
#集群名称,节点之间要保持一致
cluster.name: my-elasticsearch
#节点名称,集群内要唯一
node.name: node-1001
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"]
#discovery.zen.fd.ping_timeout: 1m
#discovery.zen.fd.ping_retries: 5
#集群内的可以被选为主节点的节点列表
#cluster.initial_master_nodes: ["node-1", "node-2","node-3"]
#跨域配置
#action.destructive_requires_name: true
http.cors.enabled: true
http.cors.allow-origin: "*"

分片与副本

一个分片就是一个Lucene的索引,也就是一个包含倒排索引的文件目录。
Elasticsearch索引被分解为多块:分片。所以一个Elasticsearch的索引由多个Lucene的索引组成。

分片很重要,主要有两方面的原因:

  • 允许你水平分割 / 扩展你的内容容量。
  • 允许你在分片之上进行分布式的、并行的操作,进而提高性能/吞吐量。

当某个分片/节点故障时,需有一个故障转移机制,所以允许你创建分片的一份或多份拷贝,这些拷贝叫做复制分片(副本)。
复制分片之所以重要,有两个主要原因:

  • 在分片/节点失败的情况下,提供了高可用性。因为这个原因,注意到复制分片从不与原/主要(original/primary)分片置于同一节点上是非常重要的。
  • 扩展你的搜索量/吞吐量,因为搜索可以在所有的副本上并行运行。

总之,每个索引可以被分成多个分片。一个索引也可以被复制 0 次(意思是没有复制)或多次。一旦复制了,每个索引就有了主分片(作为复制源的原来的分片)和复制分片(主分片的拷贝)之别。

分片副本数可以在索引创建时指定。在索引创建之后,你可以在任何时候动态地改变复制的数量,但是你事后不能改变分片的数量。索引库的分片数量是在索引库创建的时候通过settings去设置的,如果不设置,分片数默认是5,分片数一旦确定就不能改变

如果需要修改分片数量,需使用重建索引来完成,步骤如下:

  • 首先创建一个新索引,结构一致,可以设置新索引分片数
  • 数据迁移,使用_reindex api完成
  • 删除老索引
  • 给新索引加别名
    注意,这里建议大家在做项目时,都将每个索引设置一个别名,都使用别名访问。这样在修改索引时,直接将别名转给新索引就完成了更新。
# 设置索引参数
PUT http://127.0.0.1:1001/users[索引]/_settings
{
    "number_of_replicas": "1",
}

水平扩容

随着业务的增长,两台服务器不能满足业务的需求,现在需要加一台服务器节点。加入新节点后,现有的分片将在所有的节点中自动进行负载均衡。扩展节点时,需要注意分片和副本数量。

Elasticsearch优化

硬件/系统优化

Elasticsearch 的基础是 Lucene,所有的索引和文档数据是存储在本地的磁盘中,具体的路径可在 ES 的配置文件。

Elasticsearch 重度使用磁盘,你的磁盘能处理的吞吐量越大,你的节点就越稳定。

  • 使用SSD硬盘优于普通机械硬盘
  • 数据专门储存到一块硬盘中
  • 关闭交换分区,防止内存置换降低性能

分片策略

  • 合理设置分片数
  • 推迟分片分配

索引分片数建议设置为集群节点的整数倍, 大量数据写入时副本设置为0。生产环境副本数建议设置为1(多的副本会占更多存储空间,操作系统缓存会下降,搜索性能不一定提升)。单结点分片数量不超过3个,每个索引分片大小10~30G左右。

路由选择

当我们查询文档的时候, Elasticsearch 如何知道一个文档应该存放到哪个分片中呢?它其实是通过下面这个公式来计算出来:

shard = hash(routing) % number_of_primary_shards

routing 默认值是文档的 id,也可以采用自定义值,比如用户 id。当然,写入文档时,也是通过该参数查找要存入的分片的。通过这个公式我们就可以发现索引的分片数量不能修改,不然文档就找不到了。

我们可以发送请求到集群中的任一节点。每个节点都有能力处理任意请求。每个节点都知道集群中任一文档位置,所以该节点可以直接将请求转发到需要的节点上。

读写优化

  • 大量数据写入时可以把number_of_replicas改为0,每次写入1万条。
  • 如果对数据实时性要求不高可以把 index.refresh_interval 改为 30或者60秒,但如果对实时性不高,增大其值可以提高性能。
  • 多索引与索引别名

内存设置

在 ES 安装文件中包含一个 jvm.option 文件,添加如下命令来设置 ES 的堆大小, Xms 表示堆的初始大小, Xmx 表示可分配的最大内存。例如:-Xms10g -Xmx10g

  • 不超过物理机器的50%
  • 最大内存不超过32G

重要配置

参数名 参数值 说明
cluster.name name 配置 ES 的集群名称,默认值是 ES,建议改成与所存数据相关的名称, ES 会自动发现在同一网段下的 集群名称相同的节点。
node.name node-1 集群中的节点名,在同一个集群中不能重复。节点 的名称一旦设置,就不能再改变了。当然,也可以 设 置 成 服 务 器 的 主 机 名 称 , 例 如 node.name:${HOSTNAME}。
node.master true 指定该节点是否有资格被选举成为 Master 节点,默 认是 True,如果被设置为 True,则只是有资格成为 Master 节点,具体能否成为 Master 节点,需要通 过选举产生。
node.data true 指定该节点是否存储索引数据,默认为 True。数据 的增、删、改、查都是在 Data 节点完成的。
index.number_of_shards 1 设置都索引分片个数,默认是 1 片。也可以在创建 索引时设置该值,具体设置为多大都值要根据数据 量的大小来定。如果数据量不大,则设置成 1 时效 率最高
index.number_of_replicas 1 设置默认的索引副本个数,默认为 1 个。副本数越 多,集群的可用性越好,但是写索引时需要同步的 数据越多。
transport.tcp.compress true 设置在节点间传输数据时是否压缩,默认为 False, 不压缩
discovery.zen.minimum_master_nodes 1 设置在选举 Master 节点时需要参与的最少的候选 主节点数,默认为 1。如果使用默认值,则当网络 不稳定时有可能会出现脑裂。 合 理 的 数 值 为 (master_eligible_nodes/2)+1 , 其 中 master_eligible_nodes 表示集群中的候选主节点数
discovery.zen.ping.timeout 3s 设置在集群中自动发现其他节点时 Ping 连接的超 时时间,默认为 3 秒。 在较差的网络环境下需要设置得大一点,防止因误 判该节点的存活状态而导致分片的转移

此处评论已关闭