ES-部署

https://www.elastic.co/guide/cn/elasticsearch/guide/current/deploy.html

部署

硬件

按照正常的流程,你可能已经在自己的笔记本电脑或集群上使用了 Elasticsearch。
但是当要部署 Elasticsearch 到生产环境时,有一些建议是你需要考虑的。

内存

如果有一种资源是最先被耗尽的,它可能是内存
排序和聚合都很耗内存,所以有足够的堆空间来应付它们是很重要的。
即使使用的堆空间是比较小, 也能为操作系统文件缓存提供额外的内存。因为 Lucene 使用的许多数据结构是基于磁盘的格式,Elasticsearch 利用操作系统缓存能产生很大效果。

  • 64 GB 内存的机器是非常理想的,
    • 大于64 GB 的机器也会有问题(不均衡)
  • 但是32 GB 和16 GB 机器也是很常见的。
  • 少于8 GB 会适得其反
CPUs

大多数 Elasticsearch 部署往往对 CPU 要求不高。因此,相对其它资源,具体配置多少个(CPU)不是那么关键。你应该选择具有多个内核的现代处理器,常见的集群使用两到八个核的机器

如果你要在更快的 CPUs 和更多的核心之间选择,选择更多的核心更好

硬盘

硬盘对所有的集群都很重要,对大量写入的集群更是加倍重要(例如那些存储日志数据的)。
硬盘是服务器上最慢的子系统,这意味着那些写入量很大的集群很容易让硬盘饱和,使得它成为集群的瓶颈。

  • 如果你负担得起,SSD 是一个好的选择。
  • 使用 RAID 0 是提高硬盘速度的有效途径,对机械硬盘和 SSD 来说都是如此。没有必要使用镜像或其它 RAID 变体,因为高可用已经通过 replicas 内建于 Elasticsearch 之中。

RAID 0提高存储性能的原理是把连续的数据分散到多个磁盘上存取,这样,系统有数据请求就可以被多个磁盘并行的执行,每个磁盘执行属于它自己的那部分数据请求。
在这里插入图片描述- 避免使用网络附加存储(NAS)。

网络

快速可靠的网络显然对分布式系统的性能是很重要的。
低延时能帮助确保节点间能容易的通讯,大带宽能帮助分片移动和恢复。
现代数据中心网络(1 GbE, 10 GbE)对绝大多数集群都是足够的。
即使数据中心们近在咫尺,也要避免集群跨越多个数据中心。绝对要避免集群跨越大的地理距离。

总则

成百 GB 的 RAM 和几十个 CPU 核心 vs在云平台上串联起成千的小虚拟机

  • 通常,选择中配或者高配机器更好
  • 避免使用低配机器, 因为你不会希望去管理拥有上千个节点的集群,而且在这些低配机器上运行Elasticsearch 的开销也是显著的。
  • 避免使用真正的高配机器。它们通常会导致资源使用不均衡(例如,所有的内存都被使用,但 CPU 却没有)而且在单机上运行多个节点时,会增加逻辑复杂度。

配置

Elasticsearch 已经有了 很好 的默认值特别是涉及到性能相关的配置或者选项。 如果你有疑问,最好就不要动它。
其它数据库可能需要调优,但总得来说,Elasticsearch 不需要
如果你遇到了性能问题,解决方法通常是更好的数据布局或者更多的节点。 在 Elasticsearch 中很少有“神奇的配置项”, 如果存在,我们也已经帮你优化了!

指定名字

Elasticsearch 默认启动的集群名字叫 elasticsearch 。
你最好给你的生产环境的集群改个名字,改名字的目的很简单, 就是防止某人的笔记本电脑加入了集群这种意外。你可以在你的elasticsearch.yml文件中修改:cluster.name: elasticsearch_production

同样,最好也修改你的节点名字。就像你现在可能发现的那样, Elasticsearch 会在你的节点启动的时候随机给它指定一个名字。否则会带来日志混乱等一些问题。node.name: elasticsearch_005_data

路径

默认情况下,Elasticsearch 会把插件、日志以及你最重要的数据放在安装目录下。这会带来不幸的事故, 如果你重新安装 Elasticsearch 的时候不小心把安装目录覆盖了。如果你不小心,你就可能把你的全部数据删掉了。
最好的选择就是把你的数据目录配置到安装目录以外的地方, 同样你也可以选择转移你的插件和日志目录。

# 你可以通过逗号分隔指定多个目录。
# 数据可以保存到多个不同的目录, 如果将每个目录分别挂载不同的硬盘,这可是一个简单且高效实现一个软磁盘阵列( RAID 0 )的办法。
path.data: /path/to/data1,/path/to/data2 

# Path to log files:
path.logs: /path/to/logs

# Path to where plugins are installed:
path.plugins: /path/to/plugins
最小节点数

minimum_master_nodes设定对你的集群的稳定 极其 重要。 配置有助于防止脑裂(集群中有两个masters).
如果你的集群发生了脑裂,那么你的集群就会处在丢失数据的危险中,因为主节点被认为是这个集群的最高统治者,它决定了什么时候新的索引可以创建,分片是如何移动的等等。

这个配置就是告诉 Elasticsearch 当没有足够 master 候选节点的时候,就不要进行 master 节点选举,等 master 候选节点足够了才进行选举。
此设置应该始终被配置为 master 候选节点的法定个数(大多数个)。法定个数就是 ( master 候选节点个数 / 2) + 1
固定配置
你可以在你的elasticsearch.yml文件中这样配置:discovery.zen.minimum_master_nodes: 2

API修改
但是由于 ELasticsearch 是动态的,你可以很容易的添加和删除节点, 但是这会改变这个法定个数。 你不得不修改每一个索引节点的配置并且重启你的整个集群只是为了让配置生效,这将是非常痛苦的一件事情。
基于这个原因,minimum_master_nodes (还有一些其它配置)允许通过 API 调用的方式动态进行配置。 当你的集群在线运行的时候,你可以这样修改配置:

PUT /_cluster/settings
{
    "persistent" : {
        "discovery.zen.minimum_master_nodes" : 2
    }
}

这将成为一个永久的配置,并且无论你配置项里配置的如何,这个将优先生效。
当你添加和删除 master 节点的时候,你需要更改这个配置。

集群恢复方面的配置

当你集群重启时,几个配置项影响你的分片恢复的表现。
首先,我们需要明白如果什么也没配置将会发生什么
想象一下假设你有10 个节点,每个节点只保存一个分片,这个分片是一个主分片或者是一个副本分片,或者说有一个有 5 个主分片/1 个副本分片的索引。
有时你需要为整个集群做离线维护(比如,为了安装一个新的驱动程序), 当你重启你的集群,恰巧出现了 5 个节点已经启动,还有 5 个还没启动的场景
假设其它 5 个节点出问题,或者他们根本没有收到立即重启的命令。不管什么原因,你有 5 个节点在线上,这五个节点会相互通信,选出一个 master,从而形成一个集群。 他们注意到数据不再均匀分布,因为有 5 个节点在集群中丢失了,所以他们之间会立即启动分片复制
最后,你的其它 5 个节点打开加入了集群。这些节点会发现 它们 的数据正在被复制到其他节点,所以他们删除本地数据(因为这份数据要么是多余的,要么是过时的)。 然后整个集群重新进行平衡,因为集群的大小已经从 5 变成了 10。
在整个过程中,你的节点会消耗磁盘和网络带宽,来回移动数据,因为没有更好的办法。
对于有 TB 数据的大集群, 这种无用的数据传输需要 很长时间 。
如果等待所有的节点重启好了,整个集群再上线,所有的本地的数据都不需要移动。

现在我们知道问题的所在了,我们可以修改一些设置来缓解它。 首先我们要给 ELasticsearch 一个严格的限制:

# 阻止 Elasticsearch 在存在至少 8 个节点(数据节点或者 master 节点)之前进行数据恢复
# 这意味着至少要有 8 个节点,该集群才可用。
gateway.recover_after_nodes: 8


## 等待如下两个条件中任意一个满足,再进行数据恢复
# 等待集群至少存在 10 个节点
gateway.expected_nodes: 10
# 等待 5 分钟
gateway.recover_after_time: 5m
使用单播代替组播

Elasticsearch 默认被配置为使用单播发现,以防止节点无意中加入集群。
只有在同一台机器上运行的节点才会自动组成集群。
使用单播,你可以为 Elasticsearch 提供一些它应该去尝试连接的节点列表。 当一个节点联系到单播列表中的成员时,它就会得到整个集群所有节点的状态,然后它会联系 master 节点,并加入集群。

这意味着你的单播列表不需要包含你的集群中的所有节点, 它只是需要足够的节点,当一个新节点联系上其中一个并且说上话就可以了。如果你使用 master 候选节点作为单播列表,你只要列出三个就可以了。 这个配置在 elasticsearch.yml 文件中:

discovery.zen.ping.unicast.hosts: ["host1", "host2:port"]

不要修改如下配置

垃圾回收器

不要更改默认的垃圾回收器!

线程池

多人 喜欢 调整线程池。 无论什么原因,人们都对增加线程数无法抵抗。
索引太多了?增加线程!
搜索太多了?增加线程!
节点空闲率低于 95%?增加线程!

  • 如果你有 8 个核,你可以同时运行的只有 8 个线程,只分配 8 个线程给任何特定的线程池是有道理的。
  • 搜索线程池设置的大一点,配置为int(( 核心数 * 3 )/ 2 )+ 1
  • 最多设置成核心数的两倍,再多了都是浪费。

堆内存:大小和交换

Elasticsearch 默认安装后设置的堆内存是 1 GB。对于任何一个业务部署来说, 这个设置都太小了。如果你正在使用这些默认堆内存配置,您的集群可能会出现问题。
这里有两种方式修改 Elasticsearch 的堆内存。最简单的一个方法就是指定 ES_HEAP_SIZE 环境变量。服务进程在启动时候会读取这个变量,并相应的设置堆的大小。
export ES_HEAP_SIZE=10g

你也可以通过命令行参数的形式,在程序启动的时候把内存大小传递给它,如果你觉得这样更简单的话:
./bin/elasticsearch -Xmx10g -Xms10g

确保堆内存最小值( Xms )与最大值( Xmx )的大小是相同的,防止程序在运行时堆内存大小伸缩, 这是一个很耗系统资源的过程。

把你的内存的(少于)一半给Lucene

一个常见的问题是给 Elasticsearch 分配的内存 太 大了。假设你有一个 64 GB 内存的机器, 天啊,我要把 64 GB 内存全都给 Elasticsearch。因为越多越好啊!
当然,内存对于 Elasticsearch 来说绝对是重要的,它可以被许多内存数据结构使用来提供更快的操作。但是说到这里, 还有另外一个内存消耗大户 非堆内存 (off-heap):Lucene。

Lucene 被设计为可以利用操作系统底层机制来缓存内存数据结构。 Lucene 的段是分别存储到单个文件中的。因为段是不可变的,这些文件也都不会变化,这是对缓存友好的,同时操作系统也会把这些段文件缓存起来,以便更快的访问。

Lucene 的性能取决于和操作系统的相互作用。如果你把所有的内存都分配给 Elasticsearch 的堆内存,那将不会有剩余的内存交给 Lucene。 这将严重地影响全文检索的性能。
标准的建议是把 50% 的可用内存作为 Elasticsearch 的堆内存,保留剩下的 50%。当然它也不会被浪费,Lucene 会很乐意利用起余下的内存。

如果你不需要对分词字符串做聚合计算(例如,不需要 fielddata )可以考虑降低堆内存
堆内存越小,Elasticsearch(更快的 GC)和 Lucene(更多的内存用于缓存)的性能越好。

不要超过32GB

这里有另外一个原因不分配大内存给 Elasticsearch。
事实上, JVM 在内存小于 32 GB 的时候会采用一个内存对象指针压缩技术。

在 Java 中,所有的对象都分配在堆上,并通过一个指针进行引用。
普通对象指针(OOP)指向这些对象,通常为 CPU 字长 的大小:32 位或 64 位,取决于你的处理器。
指针引用的就是这个 OOP 值的字节位置。

对于 32 位的系统,意味着堆内存大小最大为 4 GB。对于 64 位的系统, 可以使用更大的内存,但是 64 位的指针意味着更大的浪费,因为你的指针本身大了。

Java 使用一个叫作 内存指针压缩(compressed oops)的技术来解决这个问题。 它的指针不再表示对象在内存中的精确位置,而是表示 偏移量 。这意味着 32 位的指针可以引用 40 亿个 对象 , 而不是 40 亿个字节。最终, 也就是说堆内存增长到 32 GB 的物理内存,也可以用 32 位的指针表示

假设你有个机器有 128 GB 的内存,你可以创建两个节点,每个节点内存分配不超过 32 GB。 也就是说不超过 64 GB 内存给 ES 的堆内存,剩下的超过 64 GB 的内存给 Lucene。
如果你选择这一种,你需要配置cluster.routing.allocation.same_shard.host: true 。 这会防止同一个分片(shard)的主副本存在同一个物理机上。

Swapping是性能的坟墓
  • 最好的办法就是在你的操作系统中完全禁用 swap。这样可以暂时禁用sudo swapoff -a.
  • 如果需要永久禁用,你可能需要修改/etc/fstab文件,
  • 如果你并不打算完全禁用 swap,也可以选择降低 swappiness 的值。 这个值决定操作系统交换内存的频率。 这可以预防正常情况下发生交换,但仍允许操作系统在紧急情况下发生交换。vm.swappiness = 1
  • 如果上面的方法都不合适,在你的elasticsearch.yml 文件中,设置如下:bootstrap.mlockall: true,它的作用就是允许 JVM 锁住内存,禁止操作系统交换出去。

文件描述符合MMap

Lucene 使用了 大量的 文件。 同时,Elasticsearch 在节点和 HTTP 客户端之间进行通信也使用了大量的套接字(注:sockets)。 所有这一切都需要足够的文件描述符。

可悲的是,许多现代的 Linux 发行版本,每个进程默认允许一个微不足道的 1024 文件描述符。这对一个小的 Elasticsearch 节点来说实在是太 低 了,更不用说一个处理数以百计索引的节点。

你应该增加你的文件描述符,设置一个很大的值,如 64,000。这个过程困难得让人恼火,它高度依赖于你的特定操作系统和分布。
一旦你认为已经改变了它,检查 Elasticsearch,以确保它的真的起作用并且有足够的文件描述符:

GET /_nodes/process

{
   "cluster_name": "elasticsearch__zach",
   "nodes": {
      "TGn9iO2_QQKb0kavcLbnDw": {
         "name": "Zach",
         "transport_address": "inet[/192.168.1.131:9300]",
         "host": "zacharys-air",
         "ip": "192.168.1.131",
         "version": "2.0.0-SNAPSHOT",
         "build": "612f461",
         "http_address": "inet[/192.168.1.131:9200]",
         "process": {
            "refresh_interval_in_millis": 1000,
            "id": 19808,
            "max_file_descriptors": 64000,  //显示 Elasticsearch 进程可以访问的可用文件描述符数量。
            "mlockall": true
         }
      }
   }
}

Elasticsearch 对各种文件混合使用了 NioFs( 注:非阻塞文件系统)和 MMapFs ( 注:内存映射文件系统.请确保你配置的最大映射数量,以便有足够的虚拟内存可用于 mmapped 文件。
这可以暂时设置sysctl -w vm.max_map_count=262144
或者在/etc/sysctl.conf通过修改vm.max_map_count永久设置它

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值