😇

OpenSearch で vm.max_map_count の問題が出たときに読むやつ

2022/12/23に公開

OpenSearch 1.3 / 2.4 では Linux 環境(org.apache.lucene.util.Constants.LINUX が true のとき)に MaxMapCountCheck が行われ、ここで vm.max_map_count という Kernel Parameter が確認されます。値が小さいと警告が出て起動しません。

Mac OS X 13.1 (Ventura) / Apple M1 Max / lima (Rancher Desktop) で opensearchproject/opensearch:latest を起動しようとすると(OpenSearch の https://opensearch.org/downloads.html から docker-compose.yml を拾って実行すると)以下のエラーが出て起動してくれません。

ERROR: [1] bootstrap checks failed
[1]: max virtual memory areas vm.max_map_count [65530] is too low, increase to at least [262144]
ERROR: OpenSearch did not exit normally - check the logs at /usr/share/opensearch/logs/opensearch-cluster.log

ちなみに Elasticsearch 8.0 ではこの制約がないのかドキュメントから vm.max_map_count に関する記述が削除されています。

対処法

正攻法

わからんけど vm.max_map_count ってやつを上げればいいらしいです。これは Linux の Kernel Parameter らしいです。Kernel Parameter ってなに?

lima は Max OS X 上で動作する Linux VM とのことなので、多分 Rancher Desktop が Max OS X 上で lima を起動してその内部で docker が動いていて、Max OS X 上の docker CLI の I/O がそのまま lima 上の docker にパイプされているんだろう。知らんけど。つまり vm.max_map_count は lima の Kernel Parameter が読まれてる……? え? あれ? そうなの? 確信が持てない。

とりあえず Rancher Desktop の CLI rdctl を使って lima の shell に入れるみたいなので、入って vm.max_map_count を見たり書き換えたりしたら通ったので、多分そういうことなんでしょうね。

host:$ rdctl shell

$ sysctl -a | grep 'vm.max_map_count'
vm.max_map_count = 65530
$ sudo sysctl -w vm.max_map_count=262144
$ sysctl -a | grep 'vm.max_map_count'
vm.max_map_count = 262144

Rancher Desktop を再起動しても VM の設定はそのままだったのでめでたしめでたし。(嘘です。これは Temporary なので /etc/sysctl.d/*.conf に書くほうが確実です)

そもそも起動時のチェックをさせない

これは Bootstrap Checks に行われる MaxMapCountCheck で引っかかっています。OpenSearch の実際のコードはざっくり書くとこんな感じ。

if node.store.allow_mmap == true {
    if get(vm.max_map_count) < 262144 {
        fail!
    }
}

なので node.store.allow_mmapfalse にしてしまえば vm.max_map_count がいくつでも良さそうです。(node.store.allow_mmap は Kernel Parameter ではなく OpenSearch の Configuration です)

OpenSearch のドキュメントには残念ながら(なぜ?)node.store.allow_mmap についての記述はないのですが、Elasticsearch にはちょっとだけ記述があります。

https://www.elastic.co/guide/en/elasticsearch/reference/8.5/_maximum_map_count_check.html
https://www.elastic.co/guide/en/elasticsearch/reference/master/index-modules-store.html

You can restrict the use of the mmapfs and the related hybridfs store type via the setting node.store.allow_mmap.

File System Storage Type の mmapfs または hybridfs を利用するかどうかを node.store.allow_mmap で制御できる(false にすることで mmap の利用をしないように設定できるので、結果的に mmapfshybridfs は使わないことになるっぽい)ようです。mmap はなんかファイルの中身をメモリにマッピングしてくれる Linux のシステムコール(?)だそうです。要するにファイルの読み方の一種と考えて良さそう。

vm.max_map_count はそもそも mmap で割り当てられるメモリの数だか大きさだかを設定しているっぽいので、mmap を使わないなら関係ないってことですね。

https://man7.org/linux/man-pages/man2/mmap.2.html
https://mkguytone.github.io/allocator-navigatable/ch73.html

docker-compose.yml の environment に - node.store.allow_mmap=false を追加しましょう。

discovery.type=single-node を使う

https://www.elastic.co/guide/en/elasticsearch/reference/7.0/bootstrap-checks.html

discovery.typesingle-node にすると Bootstrap Checks が行われないっぽいです。明確に書かれているかと言われると怪しいが事実そう。Single-node discovery のセクションにはそれっぽいことは書いてないけど、Forcing the bootstrap checks にはそういうことが書いてある。

docker-compose.yml の environment に - discovery.type=single-node を追加しましょう。

OpenSearch のコードをしばらく探索してみたんですが、single-node 時に Bootstrap をスキップしているようなコードを見つけることはできませんでした。誰か見つけたら教えてください。

Docker で起動した場合

試してないが、多分 vm.max_map_count のチェックが行われないんじゃないかな。知らんけど。

Production 環境では

そもそも OpenSearch の Bootstrap Checks は Elasticsearch の時代に「ユーザーが Elasticsearch を起動させたシステムが要件を満たしてないときに警告が出てても気づかないから、強制的に起動させないようにしたぜ」という経緯で導入されているものです。そのため、Production 環境では Bootstrap Checks を通すほうが良いです。(Max Map Count 以外のチェックにどういうものがあるか見ていないが)

Production 環境では vm.max_map_count を調整するか、node.store.allow_mmap を false にしましょう。mmap を利用しないことにするとどういうパフォーマンス上の劣化があるのかはわかりません。調べていないので。

OpenSearch を使うのってだいたいは AWS OpenSeach Service 上で利用することになると思います。AWS上でこの問題が発生することってないんじゃないかな。知らんけど。

Discussion