介绍
Elasticsearch 是一种流行的开源搜索服务器,用于实时分布式搜索和分析数据。 当用于开发以外的任何事情时,Elasticsearch 应该作为一个集群部署在多台服务器上,以获得最佳性能、稳定性和可扩展性。
本教程将向您展示如何在云服务器环境中的 Ubuntu 14.04 上安装和配置生产 Elasticsearch 集群。
尽管手动设置 Elasticsearch 集群对于学习很有用,但强烈建议在任何集群设置中使用配置管理工具。 如果您想使用 Ansible 部署 Elasticsearch 集群,请遵循本教程:如何使用 Ansible 设置生产 Elasticsearch 集群。
先决条件
您必须至少拥有三台 Ubuntu 14.04 服务器才能完成本教程,因为 Elasticsearch 集群应该至少有 3 个符合主节点资格的节点。 如果您想拥有专用的主节点和数据节点,则您的主节点至少需要 3 台服务器,另外还需要额外的服务器用于数据节点。
如果您更喜欢使用 CentOS,请查看本教程:如何在 CentOS 7 上设置生产 Elasticsearch 集群
假设
本教程假设您的服务器正在使用类似于此处描述的 VPN:如何使用 Ansible 和 Tinc VPN 保护您的服务器基础架构。 无论您的服务器使用什么物理网络,这都将提供专用网络功能。
如果您使用共享专用网络,则必须使用 VPN 来保护 Elasticsearch 免受未经授权的访问。 每台服务器都必须在同一个专用网络上,因为 Elasticsearch 的 HTTP 接口中没有内置安全性。 不得与您不信任的任何计算机共享专用网络。
我们将您服务器的 VPN IP 地址称为 vpn_ip
。 我们还将假设它们都有一个名为“tun0”的 VPN 接口,如上面链接的教程中所述。
安装 Java 8
Elasticsearch 需要 Java,所以我们现在就安装它。 我们将安装最新版本的 Oracle Java 8,因为这是 Elasticsearch 推荐的。 但是,如果您决定走那条路,它应该可以与 OpenJDK 一起正常工作。
在您的所有 Elasticsearch 服务器上完成此步骤。
将 Oracle Java PPA 添加到 apt:
sudo add-apt-repository -y ppa:webupd8team/java
更新您的 apt 软件包数据库:
sudo apt-get update
使用此命令安装最新的稳定版 Oracle Java 8(并接受弹出的许可协议):
sudo apt-get -y install oracle-java8-installer
请务必在所有 Elasticsearch 服务器上重复此步骤。
现在已经安装了 Java 8,让我们安装 ElasticSearch。
安装 Elasticsearch
通过添加 Elastic 的包源列表,可以使用包管理器安装 Elasticsearch。 在您的所有 Elasticsearch 服务器上完成此步骤。
运行以下命令将 Elasticsearch 公共 GPG 密钥导入 apt:
wget -qO - https://packages.elastic.co/GPG-KEY-elasticsearch | sudo apt-key add -
如果您的提示只是挂在那里,它可能正在等待您的用户密码(授权 sudo
命令)。 如果是这种情况,请输入您的密码。
创建 Elasticsearch 源列表:
echo "deb http://packages.elastic.co/elasticsearch/2.x/debian stable main" | sudo tee -a /etc/apt/sources.list.d/elasticsearch-2.x.list
更新您的 apt 软件包数据库:
sudo apt-get update
使用以下命令安装 Elasticsearch:
sudo apt-get -y install elasticsearch
请务必在所有 Elasticsearch 服务器上重复这些步骤。
Elasticsearch 现在已安装,但需要先配置才能使用。
配置 Elasticsearch 集群
现在是时候编辑 Elasticsearch 配置了。 在您的所有 Elasticsearch 服务器上完成这些步骤。
打开 Elasticsearch 配置文件进行编辑:
sudo vi /etc/elasticsearch/elasticsearch.yml
后续部分将解释必须如何修改配置。
绑定到 VPN IP 地址或接口
您将希望限制外部访问您的 Elasticsearch 实例,因此外部人员无法访问您的数据或通过 HTTP API 关闭您的 Elasticsearch 集群。 换句话说,您必须配置 Elasticsearch,使其仅允许访问您的专用网络 (VPN) 上的服务器。 为此,我们需要将每个节点配置为绑定到 VPN IP 地址 vpn_ip
或接口“tun0”。
找到指定 network.host
的行,取消注释,并将其值替换为相应服务器的 VPN IP 地址(例如 10.0.0.1
用于 node01) 或接口名称。 因为我们的 VPN 接口在我们所有的服务器上都被命名为“tun0”,所以我们可以用同一行配置我们所有的服务器:
elasticsearch.yml — network.host
network.host: [_tun0_, _local_]
请注意添加了“_local_”,它将 Elasticsearch 配置为也侦听所有环回设备。 这将允许您通过向 localhost
发送请求,从每台服务器本地使用 Elasticsearch HTTP API。 如果您不包含此项,Elasticsearch 将仅响应对 VPN IP 地址的请求。
警告: 因为 Elasticsearch 没有任何内置的安全性,所以不要将其设置为任何不受您控制或信任的服务器可访问的 IP 地址,这一点非常重要。 不要将 Elasticsearch 绑定到公共或 共享专用网络 IP 地址!
设置集群名称
接下来,设置集群的名称,这将允许您的 Elasticsearch 节点加入并形成集群。 您将需要使用唯一的描述性名称(在您的网络中)。
找到指定 cluster.name
的行,取消注释,并将其值替换为所需的集群名称。 在本教程中,我们将集群命名为“production”:
elasticsearch.yml — cluster.name
cluster.name: production
设置节点名称
接下来,我们将设置每个节点的名称。 这应该是集群中唯一的描述性名称。
找到指定 node.name
的行,取消注释,并将其值替换为所需的节点名称。 在本教程中,我们将使用 ${HOSTNAME}
环境变量将每个节点名称设置为服务器的主机名:
elasticsearch.yml — 节点名称
node.name: ${HOSTNAME}
如果您愿意,可以手动命名节点,但请确保指定唯一名称。 如果您不介意随机命名节点,您也可以将 node.name
注释掉。
设置发现主机
接下来,您将需要配置将被联系以发现和形成集群的节点的初始列表。 这在单播网络中是必要的。
找到指定 discovery.zen.ping.unicast.hosts
的行并取消注释。 将其值替换为所有其他节点的 VPN IP 地址或主机名(解析为 VPN IP 地址)的字符串数组。
例如,如果您有三个服务器 node01
、node02
和 node03
,其 VPN IP 地址分别为 10.0.0.1
、10.0.0.2
和10.0.0.3
,你可以使用这一行:
elasticsearch.yml — 按 IP 地址的主机
discovery.zen.ping.unicast.hosts: ["10.0.0.1", "10.0.0.2", "10.0.0.3"]
或者,如果您的所有服务器都配置了基于名称的 VPN IP 地址解析(通过 DNS 或 /etc/hosts
),您可以使用以下行:
elasticsearch.yml — 主机名
discovery.zen.ping.unicast.hosts: ["node01", "node02", "node03"]
注意: 先决条件VPN教程中的Ansible Playbook自动在每个服务器上创建/etc/hosts
条目来解析每个VPN服务器的库存主机名(在Ansible hosts
文件)到它的 VPN IP 地址。
保存并退出
您的服务器现在已配置为形成一个基本的 Elasticsearch 集群。 您还需要更新更多设置,但我们会在验证集群是否正常工作后进行更新。
保存并退出elasticsearch.yml
。
启动弹性搜索
现在启动 Elasticsearch:
sudo service elasticsearch restart
然后运行以下命令在启动时启动 Elasticsearch:
sudo update-rc.d elasticsearch defaults 95 10
请务必在所有 Elasticsearch 服务器上重复这些步骤(配置 Elasticsearch 集群 )。
检查集群状态
如果一切配置正确,您的 Elasticsearch 集群应该已启动并运行。 在继续之前,让我们验证它是否正常工作。 您可以通过从任何 Elasticsearch 节点查询 Elasticsearch 来做到这一点。
在您的任何 Elasticsearch 服务器上,运行以下命令来打印集群的状态:
curl -XGET 'http://localhost:9200/_cluster/state?pretty'
您应该看到指示名为“生产”的集群正在运行的输出。 它还应该表明您配置的所有节点都是成员:
Cluster State:{ "cluster_name" : "production", "version" : 36, "state_uuid" : "MIkS5sk7TQCl31beb45kfQ", "master_node" : "k6k2UObVQ0S-IFoRLmDcvA", "blocks" : { }, "nodes" : { "Jx_YC2sTQY6ayACU43_i3Q" : { "name" : "node02", "transport_address" : "10.0.0.2:9300", "attributes" : { } }, "k6k2UObVQ0S-IFoRLmDcvA" : { "name" : "node01", "transport_address" : "10.0.0.1:9300", "attributes" : { } }, "kQgZZUXATkSpduZxNwHfYQ" : { "name" : "node03", "transport_address" : "10.0.0.3:9300", "attributes" : { } } }, ...
如果您看到与此类似的输出,则您的 Elasticsearch 集群正在运行! 如果您的任何节点丢失,请在继续之前检查相关节点的配置。
接下来,我们将介绍一些您应该为 Elasticsearch 集群考虑的配置设置。
启用内存锁定
Elastic 建议不惜一切代价避免更换 Elasticsearch 进程,因为它会对性能和稳定性产生负面影响。 避免过度交换的一种方法是配置 Elasticsearch 以锁定它需要的内存。
在您的所有 Elasticsearch 服务器上完成此步骤。
编辑 Elasticsearch 配置:
sudo vi /etc/elasticsearch/elasticsearch.yml
找到指定 bootstrap.mlockall
的行并取消注释:
elasticsearch.yml — bootstrap.mlockall
bootstrap.mlockall: true
保存并退出。
接下来,打开/etc/default/elasticsearch
文件进行编辑:
sudo vi /etc/default/elasticsearch
首先,找到 ES_HEAP_SIZE
,取消注释,并将其设置为大约 50% of 可用内存。 例如,如果您有大约 4 GB 可用空间,则应将其设置为 2 GB (2g
):
/etc/default/elasticsearch — ES_HEAP_SIZE
ES_HEAP_SIZE=2g
接下来,找到并取消注释 MAX_LOCKED_MEMORY=unlimited
。 完成后应该是这样的:
/etc/default/elasticsearch — MAX_LOCKED_MEMORY
MAX_LOCKED_MEMORY=unlimited
保存并退出。
现在重新启动 Elasticsearch 以使更改到位:
sudo service elasticsearch restart
请务必在所有 Elasticsearch 服务器上重复此步骤。
验证 Mlockall 状态
要验证 mlockall
是否在您的所有 Elasticsearch 节点上运行,请从任何节点运行此命令:
curl http://localhost:9200/_nodes/process?pretty
每个节点应该有一行写着 "mlockall" : true
,这表明内存锁定已启用并且正在工作:
Nodes process output:... "nodes" : { "kQgZZUXATkSpduZxNwHfYQ" : { "name" : "es03", "transport_address" : "10.0.0.3:9300", "host" : "10.0.0.3", "ip" : "10.0.0.3", "version" : "2.2.0", "build" : "8ff36d1", "http_address" : "10.0.0.3:9200", "process" : { "refresh_interval_in_millis" : 1000, "id" : 1650, "mlockall" : true } ...
如果您的任何节点的 mlockall
为 false,请查看节点的设置并重新启动 Elasticsearch。 Elasticsearch 无法启动的一个常见原因是 ES_HEAP_SIZE
设置得太高。
配置打开文件描述符限制(可选)
默认情况下,您的 Elasticsearch 节点的“打开文件描述符限制”应为 64k。 本节将向您展示如何验证这一点,如果您愿意,可以增加它。
如何验证最大打开文件
首先,找到您的 Elasticsearch 进程的进程 ID (PID)。 一个简单的方法是使用 ps
命令列出属于 elasticsearch
用户的所有进程:
ps -u elasticsearch
您应该会看到如下所示的输出。 第一列中的数字是您的 Elasticsearch (java) 进程的 PID:
Output: PID TTY TIME CMD 11708 ? 00:00:10 java
然后运行此命令以显示 Elasticsearch 进程的打开文件限制(将突出显示的数字替换为上一步中您自己的 PID):
cat /proc/11708/limits | grep 'Max open files'
OutputMax open files 65535 65535 files
第二列和第三列中的数字分别表示软限制和硬限制,为 64k (65535)。 这对于许多设置都可以,但您可能需要增加此设置。
如何增加最大文件描述符限制
要增加 Elasticsearch 中打开文件描述符的最大数量,您只需更改一个设置。
打开/etc/default/elasticsearch
文件进行编辑:
sudo vi /etc/default/elasticsearch
找到 MAX_OPEN_FILES
,取消注释,并将其设置为您想要的限制。 例如,如果您想要 128k 描述符的限制,请将其更改为 131070
:
/etc/default/elasticsearch — MAX_OPEN_FILES
MAX_OPEN_FILES=131070
保存并退出。
现在重新启动 Elasticsearch 以使更改到位:
sudo service elasticsearch restart
然后按照上一小节验证限制是否已增加。
请务必在任何需要更高文件描述符限制的 Elasticsearch 服务器上重复此步骤。
配置专用主节点和数据节点(可选)
Elasticsearch 节点有两种常见类型:master 和 data。 主节点执行集群范围的操作,例如管理索引和确定哪些数据节点应该存储特定的数据分片。 数据节点保存索引文档的碎片,并处理 CRUD、搜索和聚合操作。 作为一般规则,数据节点会消耗大量的 CPU、内存和 I/O。
默认情况下,每个 Elasticsearch 节点都配置为“主节点”数据节点,这意味着它们存储数据(并执行资源密集型操作)并有可能被选为主节点。 对于小型集群,这通常很好; 但是,大型 Elasticsearch 集群应配置 专用主 节点,以便主节点的稳定性不会因密集的数据节点工作而受到影响。
如何配置专用主节点
在配置专用主节点之前,请确保您的集群至少有 3 个符合主节点条件的节点。 这对于避免脑裂情况很重要,这可能会在发生网络故障时导致数据不一致。
要配置专用主节点,请编辑节点的 Elasticsearch 配置:
sudo vi /etc/elasticsearch/elasticsearch.yml
添加以下两行:
elasticsearch.yml — 专用主控
node.master: true node.data: false
第一行 node.master: true
指定节点是主节点,实际上是默认设置。 第二行 node.data: false
限制节点成为数据节点。
保存并退出。
现在重新启动 Elasticsearch 节点以使更改生效:
sudo service elasticsearch restart
请务必在您的其他专用主节点上重复此步骤。
您可以使用以下命令查询集群以查看哪些节点被配置为专用主节点:curl -XGET 'http://localhost:9200/_cluster/state?pretty'
。 任何具有 data: false
和 master: true
的节点都是专用主节点。
如何配置专用数据节点
要配置专用数据节点(不符合主节点资格的数据节点),请编辑节点的 Elasticsearch 配置:
sudo vi /etc/elasticsearch/elasticsearch.yml
添加以下两行:
elasticsearch.yml — 专用数据
node.master: false node.data: true
第一行 node.master: false
指定节点不是主节点。 第二行 node.data: true
是允许节点成为数据节点的默认设置。
保存并退出。
现在重新启动 Elasticsearch 节点以使更改生效:
sudo service elasticsearch restart
请务必在您的其他专用数据节点上重复此步骤。
您可以使用以下命令查询集群以查看哪些节点被配置为专用数据节点:curl -XGET 'http://localhost:9200/_cluster/state?pretty'
。 任何列出 master: false
和 的节点没有 列出 data: false
是专用数据节点。
配置最小主节点
运行 Elasticsearch 集群时,设置集群正常运行所需的符合主节点的最小节点数非常重要,有时称为 quorum。 这是为了在一个或多个节点失去与集群其余部分的连接时确保数据一致性,防止所谓的“裂脑”情况。
要计算集群应具有的最小主节点数,请计算 n / 2 + 1
,其中 n 是健康集群中“符合主节点资格”的节点的总数,然后将结果向下取整到最接近的整数。 例如,对于 3 节点集群,法定人数为 2。
注意: 确保在仲裁计算中包括所有符合主节点资格的节点,包括符合主节点资格的任何数据节点(默认设置)。
可以通过 Elasticsearch HTTP API 动态设置最小主节点设置。 为此,请在任何节点上运行此命令(将突出显示的数字替换为您的法定人数):
curl -XPUT localhost:9200/_cluster/settings?pretty -d '{ "persistent" : { "discovery.zen.minimum_master_nodes" : 2 } }'
Output:{ "acknowledged" : true, "persistent" : { "discovery" : { "zen" : { "minimum_master_nodes" : "2" } } }, "transient" : { } }
注意: 此命令是“持久”设置,这意味着最小主节点设置将在整个集群重新启动后继续存在并覆盖 Elasticsearch 配置文件。 此外,如果您尚未动态设置此设置,则可以将其指定为 /etc/elasticsearch.yml
中的 discovery.zen.minimum_master_nodes: 2
。
如果您想稍后检查此设置,可以运行以下命令:
curl -XGET localhost:9200/_cluster/settings?pretty
如何访问 Elasticsearch
您可以通过向任何节点的 VPN IP 地址发送请求来访问 Elasticsearch HTTP API,或者如教程中所示,通过从其中一个节点向 localhost
发送请求来访问 Elasticsearch HTTP API。
客户端服务器可以通过任何节点的 VPN IP 地址访问您的 Elasticsearch 集群,这意味着客户端服务器也必须是 VPN 的一部分。
如果您有其他软件需要连接到您的集群,例如 Kibana 或 Logstash,您通常可以通过为您的应用程序提供一个或多个 Elasticsearch 节点的 VPN IP 地址来配置连接。
结论
您的 Elasticsearch 集群应该在健康状态下运行,并且配置了一些基本优化!
Elasticsearch 有许多其他的配置选项,这里没有介绍,例如索引、分片和复制设置。 建议您稍后重新访问您的配置以及官方文档,以确保您的集群配置满足您的需求。