Elasticsearchの初期システム設定

Elasticsearchを運用する上で、細かい初期システムパラメータについてもメモしておきます。CentOS7でElasticsearchのバージョンは2.4.1です。

基本的にマニュアル通りです。

Configuration | Elasticsearch Reference [2.4] | Elastic

ES_HEAP_SIZE

Javaで利用するヒープサイズの設定。デフォルトでは最小256MB、最大1Gになってます。 ES_HEAP_SIZEのパラメータで設定できます。 最大でも実メモリの半分サイズ、または32GB以下にすべきとのこと。

Limiting Memory Usage | Elasticsearch: The Definitive Guide [2.x] | Elastic

Choosing a Heap Size
There are two rules to apply when setting the Elasticsearch heap size, with the $ES_HEAP_SIZE environment variable:

No more than 50% of available RAM
Lucene makes good use of the filesystem caches, which are managed by the kernel. Without enough filesystem cache space, performance will suffer. Furthermore, the more memory dedicated to the heap means less available for all your other fields using doc values.

No more than 32 GB
If the heap is less than 32 GB, the JVM can use compressed pointers, which saves a lot of memory: 4 bytes per pointer instead of 8 bytes. <

「/etc/sysconfig/elasticsearch」の該当部分を編集。

[/etc/sysconfig/elasticsearch]
# Heap size defaults to 256m min, 1g max
# Set ES_HEAP_SIZE to 50% of available RAM, but no more than 31g
ES_HEAP_SIZE=1g

サービスを上げ直すと、-Xmsと-Xmxの値が1gになっています。

# ps -aef | grep elasticsearch | grep -v grep
elastic+   3162      1  1 03:04 ?        00:00:05 /bin/java -Xms1g -Xmx1g -Djava.awt.headless=true -XX:+UseParNewGC -XX:+UseConcMarkSweepGC -XX:CMSInitiatingOccupancyFraction=75 -XX:+UseCMSInitiatingOccupancyOnly -XX:+HeapDumpOnOutOfMemoryError -XX:+DisableExplicitGC -Dfile.encoding=UTF-8 -Djna.nosys=true -Des.path.home=/usr/share/elasticsearch -cp /usr/share/elasticsearch/lib/elasticsearch-2.4.1.jar:/usr/share/elasticsearch/lib/* org.elasticsearch.bootstrap.Elasticsearch start -Des.pidfile=/var/run/elasticsearch/elasticsearch.pid -Des.default.path.home=/usr/share/elasticsearch -Des.default.path.logs=/var/log/elasticsearch -Des.default.path.data=/var/lib/elasticsearch -Des.default.path.conf=/etc/elasticsearch
ファイルディスクリプタ

1プロセスあたりオープンできるファイル数。32Kか64Kが推奨。 Systemdで起動管理するOSの場合、「/usr/lib/systemd/system/elasticsearch.service」のLimitNOFILEパラメータを使えとのこと。

[/usr/lib/systemd/system/elasticsearch.service]
# Specifies the maximum file descriptor number that can be opened by this process
LimitNOFILE=32768

サービスを上げ直して確認すると、open_file_discriptorsの値が変更されています。

# curl localhost:9200/_nodes/stats/process?pretty
{
  "cluster_name" : "elasticsearch",
  "nodes" : {
    "xFDFpDnDSQKb_eNv5gfX7Q" : {
      "timestamp" : 1475951361843,
      "name" : "Flatman",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : [ "127.0.0.1:9300", "NONE" ],
      "process" : {
        "timestamp" : 1475951361843,
        "open_file_descriptors" : 116,
        "max_file_descriptors" : 32768,
        "cpu" : {
          "percent" : 0,
          "total_in_millis" : 5380
        },
        "mem" : {
          "total_virtual_in_bytes" : 3710349312
        }
      }
    }
  }
}
仮想メモリ(mmapの上限)

1プロセスあたり使用できるメモリマップの上限数。 OS標準の値だと小さすぎてout of memoryの原因になりうると。OS標準では65530。rpmで入れた場合、自動的に最適値に更新されるらしい。更新したい場合は「/etc/sysctl.conf」を直接いじる。

僕はrpmで入れたので、「262144」に更新されていた。標準値と比べると結構大きな値になってます。

# sysctl vm.max_map_count
vm.max_map_count = 262144
メモリ設定(スワップ無効化)

「Swapping Is the Death of Performance」とか公式で言ってます。

Heap: Sizing and Swapping | Elasticsearch: The Definitive Guide [2.x] | Elastic

そのためスワップ無効化が推奨されるのですが、マニュアル読むと3種類ほど設定方法が紹介されています。無効化範囲をElasticsearchに限定できるmlockallを利用する方法が良さげです。 「/etc/elasticsearch/elasticsearch.yml」でbootstrap.memory_lockの部分をアンコメントします。

[/etc/elasticsearch/elasticsearch.yml]
# Lock the memory on startup:
#
bootstrap.memory_lock: true

サービスを上げ直して確認すると、mlockallの値がtrueになっています。

# curl http://localhost:9200/_nodes/process?pretty
{
  "cluster_name" : "elasticsearch",
  "nodes" : {
    "ro0SHp5ZRa27Gsj7aohGJA" : {
      "name" : "Kurse",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1",
      "version" : "2.4.1",
      "build" : "c67dc32",
      "http_address" : "127.0.0.1:9200",
      "process" : {
        "refresh_interval_in_millis" : 1000,
        "id" : 3437,
        "mlockall" : false
      }
    }
  }
}

って、なってねえよ。 マニュアルでは「The most probable reason, on Linux/Unix systems, is that the user running Elasticsearch doesn’t have permission to lock memory. This can be granted by running ulimit -l unlimited as root before starting Elasticsearch.」とか言ってますが、以下サイトの情報に助けられました。

mlockall: false despite being configured · Issue #9357 · elastic/elasticsearch · GitHub

ElasticSearchでmlockall:trueが効かない時にチェックすること - サナギわさわさ.json

「/etc/sysconfig/elasticsearch」よりMAX_LOCKED_MEMORYの部分をアンコメントします。

[/etc/sysconfig/elasticsearch]
# The maximum number of bytes of memory that may be locked into RAM
# Set to "unlimited" if you use the 'bootstrap.memory_lock: true' option
# in elasticsearch.yml (ES_HEAP_SIZE  must also be set).
# When using Systemd, the LimitMEMLOCK property must be set
# in /usr/lib/systemd/system/elasticsearch.service
MAX_LOCKED_MEMORY=unlimited

また上記コンフィグの記載通り、CnetOS7でSystemdを利用してるので、「/usr/lib/systemd/system/elasticsearch.service」のLimitMEMLOCKもアンコメントします。

[/usr/lib/systemd/system/elasticsearch.service]
# Specifies the maximum number of bytes of memory that may be locked into RAM
# Set to "infinity" if you use the 'bootstrap.memory_lock: true' option
# in elasticsearch.yml and 'MAX_LOCKED_MEMORY=unlimited' in /etc/sysconfig/elasticsearch
LimitMEMLOCK=infinity

もう1回上げ直すと、trueになりました。

# curl http://localhost:9200/_nodes/process?pretty
{
  "cluster_name" : "elasticsearch",
  "nodes" : {
    "W6v06t6LRjmdoqas4AFXdw" : {
      "name" : "Solara",
      "transport_address" : "127.0.0.1:9300",
      "host" : "127.0.0.1",
      "ip" : "127.0.0.1",
      "version" : "2.4.1",
      "build" : "c67dc32",
      "http_address" : "127.0.0.1:9200",
      "process" : {
        "refresh_interval_in_millis" : 1000,
        "id" : 3675,
        "mlockall" : true
      }
    }
  }
}

初期設定で必要なシステム設定箇所は以上のようです。