重要配置的修改edit

Elasticsearch 已经有了 很好 的默认值,特别是涉及到性能相关的配置或者选项。 如果你有疑问,最好就不要动它。 我们目睹了无数的集群被错误的设置所破坏,因为管理员认为改动一个配置或者选项就可以带来 100 倍的提升。

请阅读整节文章,所有的配置项都同等重要,与显示顺序无关。请阅读所有的配置选项,并应用到你的集群中。

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

尽管如此,有些 逻辑上的 配置在生产环境中是应该调整的。 这些调整是必要的,要么让你的工作更轻松,要么是因为没办法设定一个好的默认值(因为它取决于你的集群布局)。

指定名字edit

默认情况下, Elasticsearch 启动一个叫elasticsearch的集群。 最好给生产环境的集群改个名字,改名字的目的很简单, 就是防止某人的笔记本电脑加入了集群这种意外。 简单修改成 elasticsearch_production 会很省心。

你可以在配置文件elasticsearch.yml中修改:

cluster.name: elasticsearch_production

同样,最好也修改一下节点的名字。 就像你现在可能已经发现的那样, Elasticsearch 会在你的节点启动的时候随机给它指定一个漫威超级英雄的名字。 在开发的时候你可能会觉得很有趣,但是在凌晨 3 点钟, 你要去尝试回忆哪台物理机器是 Tagak the Leopard Lord 的时候,你就不觉得有趣了。

更重要的是,这些名字是在启动的时候产生的,每次重新启动节点, 它都会得到一个新的名字。 这会使日志变得很混乱,因为所有节点的名字都是不断变化的。

尽管这很无聊,但我们建议给每个节点设置一个对你有意义的名字 - 一个简单、描述性的名称。同样可以在 elasticsearch.yml 中配置:

node.name: elasticsearch_005_data

路径edit

默认情况下,Elasticsearch 会把插件、日志以及你最重要的数据放在安装目录下。 这可能导致不幸的事故,安装目录被新安装的 Elasticearch 意外覆盖。 如果你不够细心,你就可能把你的全部数据都删掉了。

不要笑,这种情况,我们见过很多次了。

最好的办法是将数据目录重新定位到安装目录以外的地方。 你也可以选择性的移动插件和日志目录。

可以更改如下:

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

提示:你可以通过逗号分隔的列表指定多个目录。

数据可以保存到多个不同的目录, 如果将每个目录分别挂载到不同的硬盘,这可是一个简单且高效实现一个软 RAID 0 的办法。 Elasticsearch 会自动把条带化数据分割到不同的目录以提高性能。注:RAID 0 又称为 Stripe(条带化),在磁盘阵列中,数据是以条带的方式贯穿在磁盘阵列所有硬盘中的

多个数据路径的安全性和性能

如同任何 RAID 0 的配置,只有一份数据拷贝保存到硬盘驱动器。 如果你失去了一个硬盘驱动器,你 肯定 会失去该计算机上的一部分数据。 运气好的话,在集群的其他地方有可以用来恢复数据的副本,或者一份最近的备份。

ElasticSearch试图通过将整个分片条带化到一个驱动器来最小化数据丢失的程度。 这意味着 分片 0 将完全被放置在单个驱动器上。 Elasticsearch 不会在条带化一个分片时跨多个驱动器,因为一个驱动器的损失就会破坏整个分片。

这对性能产生的影响是:如果您添加多个驱动器来提高一个单独索引的性能,可能帮助不大,因为大多数节点只有一个分片,也只对应一个活动的驱动器。 只有在单个节点上有许多索引/分片时,多个数据路径才能有所帮助。

多个数据路径是一个非常方便的功能,但到头来,Elasticsearch 并不是一个软磁盘阵列软件。 如果你需要更高级的、稳健的、灵活的配置, 建议你使用实际的软磁盘阵列软件,而不是多个数据路径的功能。

最小主节点数 (Minimum Master Nodes)edit

minimum_master_nodes 设置对集群的稳定性 极其 重要。 这个设置有助于防止裂(split brains),即: 在一个集群中存在两个主节点(master)。

如果发生了脑裂,那么集群就会处于丢失数据的危险中,因为主节点被认为是集群的最高统治者,它决定了什么时候新的索引可以创建,分片是如何移动的等等。 如果你有 两个 主节点(master),数据的完整性变得危险,因为有两个节点认为这事归他们管。

这个配置就是告诉 Elasticsearch,除非有足够的候选的主节点,否则不选举主节点。只有这样,选举才会发生。

此设置应该始终被配置为 候选主节点的法定个数(大多数)。法定个数就是( 候选主节点个数 / 2) + 1 。 这里有几个例子:

  • 如果你有 10 个常规节点(能保存数据,能成为 master),法定数就是 6
  • 如果你有 3 个专用的主节点,和 100 个 数据(data) 节点,法定数就是 2 ,你只要数数那些可以做 master 的节点数就可以了。
  • 如果你有两个常规节点,你遇到难题了。 法定数当然是 2 ,但这意味着丢失一个节点就会使整个集群不可用。 设置成 1 可以保证集群的功能,但就无法保证集群脑裂了。 像这样的情况,最好保证至少有 3 个节点。

可以在 elasticsearch.yml 文件中这样配置:

discovery.zen.minimum_master_nodes: 2

但是由于 ELasticsearch 集群是动态的,你可以很容易的添加或删除节点, 而这会改变这个法定个数。 如果你必须将新配置推送到每个节点并重新启动整个集群来更新设置,这将是一件非常痛苦的事。

基于这个原因,允许通过 API 调用的方式动态配置minimum_master_nodes(还有一些其它配置)。 当集群在运行的时候,可以这样修改配置:

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

这将成为一个永久的配置,优先于静态配置中的任何内容。当你添加或删除 master 候选节点的时候,你应该更改这个配置。

集群恢复方面的配置edit

当集群重启时,有几个配置项会影响分片恢复的行为。首先,我们需要明白如果什么也没配置将会发生什么。

假设你有 10 个节点,每个节点只保存一个分片 - 主分片或者副本分片,一个有 5 个主分片/1 个副本分片的索引(原文"Imagine you have ten nodes, each node holds a single shard—​either a primary or a replica—​in a 5 primary / 1 replica index."理解起来有点费劲)。 要把整个集群离线做维护(比如,安装一个新的驱动器)。 当你重启集群时,恰巧 5 个节点在其他 5 个节点之前上线。

也许发送到其他5个节点的重启命令(切换状态)有点古怪,他们没有立马收到重启命令。 不管什么原因,你有 5 个节点在线上,这五个节点会相互通信,选出一个 master,从而形成一个集群。 他们注意到数据不再均匀分布,因为有 5 个节点在集群中丢失了,所以他们之间会立即启动分片复制。

最后,你的其它 5 个节点打开加入了集群。 这些节点会发现 它们 的数据正在被复制到其他节点,所以他们删除本地数据(因为这份数据要么是多余的,要么是过时的)。 然后整个集群重新进行平衡,因为集群的大小已经从 5 变成了 10。

在整个过程中,节点冲击着磁盘和网络带宽,无缘无故的来回移动数据。 对于有 TB 数据的大集群,这种无用的数据传输需要 很长时间 。 如果所有节点都只是等待集群上线,那么所有的数据都是本地的,没有什么需要移动的。

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

gateway.recover_after_nodes: 8

这将阻止 Elasticsearch 在至少 8 个节点(数据节点或者 master 节点)出现之前启动恢复。 这个值的设定取决于个人喜好:整个集群能提供服务之前你希望有多少个节点在线?这种情况下,我们设置为 8,这意味着至少要有 8 个节点,该集群才可用。

现在我们要告诉 Elasticsearch 集群中 应该 有多少个节点,以及我们愿意为这些节点等待多长时间:

gateway.expected_nodes: 10
gateway.recover_after_time: 5m

这意味着 Elasticsearch 会采取如下操作:

  • 等待集群中出现 8 个节点
  • 等待 5 分钟,或者有 10 个节点加入集群后,才进行数据恢复,以先达到的条件为准。

这三个设置可以在集群重启时避免过多的分片交换。这可能会让数据恢复从数个小时缩短为几秒钟。

注意:这些配置只能通过 config/elasticsearch.yml 文件中或者是在命令行里设置(它们不支持动态更新),它们只在整个集群重启的时候有实质性作用。

最好使用单播(Unicast)代替组播(Multicast)edit

ElasticSearch 被配置为使用开箱即用的单播发现(unicast discovery),以防止节点意外地加入集群。 只有在同一台机器上运行的节点才会自动组成集群。

虽然组播(multicast)仍然 作为插件提供, 但它应该永远不被使用在生产环境。 您最不希望的是节点意外地加入了你的生产网络,仅仅是因为它们收到了错误的组播回显信号。 否则你得到的结果就是一个节点意外的加入到了你的生产环境,仅仅是因为他们收到了一个错误的组播信号。 组播 本身 并没有错,组播只会导致一些愚蠢的问题,而且能导致集群变得更加脆弱(比如,一个网络工程师正在捣鼓网络,而没有告诉你,你会发现所有的节点突然发现不了对方了)。

要使用单播,你可以为 Elasticsearch 提供一些它应该去尝试连接的节点列表。 当一个节点联系到单播列表中的成员时,它就会得到整个集群所有节点的状态,然后它会联系 master 节点,并加入集群。

这意味着单播列表不需要包含集群中所有的节点, 它只是需要足够的节点,新节点就可以找到可以交流的目标。 如果使用专用的 master , 只需要列出三个专用的 master,这就够了。 这个配置在 elasticsearch.yml 文件中:

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

关于 Elasticsearch 节点发现的详细信息,请参阅 发现和集群信息 Elasticsearch 文献。