このページの前提
Jetson Nano(Ubuntu 18.04 / aarch64)に、GROWIの全文検索バックエンドとしてElasticsearchを入れる手順の記録だ。GROWIは日本語検索のためElasticsearchを推奨しており、そのDocker構成(growi-docker-compose)で使われる6.6.1に版を合わせている。
user@Jetson $ sudo apt-get update
user@Jetson $ sudo apt-get upgrade
後々使うので"nano"、"curl"をインストール。
user@Jetson $ sudo apt-get install nano curl
インストール可能なjavaを検索
user@Jetson $ sudo apt search openjdk-\(\.\)\+-jre$
ソート中... 完了
全文検索... 完了
openjdk-11-jre/bionic-updates,bionic-security 11.0.4+11-1ubuntu2~18.04.3 arm64
OpenJDK Java runtime, using Hotspot JIT
openjdk-8-jre/bionic-updates,bionic-security 8u222-b10-1ubuntu1~18.04.1 arm64
OpenJDK Java runtime, using Hotspot JIT
今回はjava8をインストール。
なぜJava 8なのか
Elasticsearch 6.xはJava 8で動く前提でビルドされている。Java 11以上だと6.6.1は起動時に弾かれる(逆に7.xはJava 11が必須でJava 8では動かない)。上のapt searchで11と8が出ているが、この版に合わせて8を選ぶ。
通常はJREだけで足りる。arm64用パッケージが用意されているのでx86用を混ぜないこと。
user@Jetson $ sudo apt-get install openjdk-8-jre
インストールしたjavaをチェック。
user@Jetson $ java -version
openjdk version "1.8.0_222"
OpenJDK Runtime Environment (build 1.8.0_222-8u222-b10-1ubuntu1~18.04.1-b10)
OpenJDK 64-Bit Server VM (build 25.222-b10, mixed mode)
user@Jetson $
パスの確認。
user@Jetson $ /usr/sbin/update-java-alternatives -l
java-1.8.0-openjdk-arm64 1081 /usr/lib/jvm/java-1.8.0-openjdk-arm64
①JAVA_HOMEの設定。.bashrcに追記
user@Jetson $ cd
user@Jetson $ sudo nano .bashrc
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-arm64 <-最後に追記
追記したら変数の設定を反映させる。
user@Jetson $ source ~/.bashrc
もしくは、
②"/etc/environment"に追記
/etc/environmentの書き方に注意
/etc/environmentはシェルスクリプトではないのでexportは付けない。JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-arm64のように変数=値だけを書く。exportを書いても無視されるかエラーになる。PAMがログイン時に読むファイルなので、反映には再ログインが要ることがある(sourceで効かない場合がある)。
.bashrc方式は対話シェル限定、/etc/environment方式は全プロセス共通。systemdから起動する場合はsystemdが/etc/environmentを読むが.bashrcは読まないので、サービス化するなら後者のほうが確実だ。
user@Jetson $ sudo nano /etc/environment
export JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-arm64 <-最後に追記
追記したら変数の設定を反映させる。
user@Jetson $ source /etc/environment
JAVA_HOMEの確認
user@Jetson $ echo $JAVA_HOME
/usr/lib/jvm/java-1.8.0-openjdk-arm64
Elasticsearchのダウンロード。今回はGROWI Docker-composeで推奨の6.6.1をインストール。
tarball版の位置づけ
配布物はtar.gzで、aptのようなパッケージ管理はされない。任意のディレクトリに展開してbin/elasticsearchを直接叩くスタイル。設定はconfig/elasticsearch.yml、ヒープはconfig/jvm.options、データはdata/、ログはlogs/に入る。
--no-check-certificateの例が用意されている。普通に到達できるなら通常のwgetで足りる。ダウンロードIPv6な人は次に。
user@Jetson $ wget https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.6.1.tar.gz
user@Jetson $ tar zxvf elasticsearch-6.6.1.tar.gz
user@Jetson $ cd elasticsearch-6.6.1/
IPv6な人は次のコマンドで。
user@Jetson $ wget --no-check-certificate https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-6.6.1.tar.gz
実行
user@Jetson $ cd bin/
user@Jetson $ ./elasticsearch
以下ログ
[2019-10-09T12:28:48,605][INFO ][o.e.e.NodeEnvironment ] [ELzCU7U] using [1] data paths, mounts [[/ (/dev/mmcblk0p1)]], net usable_space [44.9gb], net total_space [58.4gb], types [ext4]
[2019-10-09T12:28:48,616][INFO ][o.e.e.NodeEnvironment ] [ELzCU7U] heap size [494.9mb], compressed ordinary object pointers [true]
[2019-10-09T12:28:48,622][INFO ][o.e.n.Node ] [ELzCU7U] node name derived from node ID [ELzCU7U5Q9S3NoRHBqmGGQ]; set [node.name] to override
[2019-10-09T12:28:48,623][INFO ][o.e.n.Node ] [ELzCU7U] version[6.6.1], pid[7381], build[default/tar/1fd8f69/2019-02-13T17:10:04.160291Z], OS[Linux/4.9.140-tegra/aarch64], JVM[Private Build/OpenJDK 64-Bit Server VM/1.8.0_222/25.222-b10]
[2019-10-09T12:28:48,624][INFO ][o.e.n.Node ] [ELzCU7U] JVM arguments [-Xms512M, -Xmx512M, -XX:+UseConcMarkSweepGC, -XX:CMSInitiatingOccupancyFraction=75, -XX:+UseCMSInitiatingOccupancyOnly, -Des.networkaddress.cache.ttl=60, -Des.networkaddress.cache.negative.ttl=10, -XX:+AlwaysPreTouch, -Xss1m, -Djava.awt.headless=true, -Dfile.encoding=UTF-8, -Djna.nosys=true, -XX:-OmitStackTraceInFastThrow, -Dio.netty.noUnsafe=true, -Dio.netty.noKeySetOptimization=true, -Dio.netty.recycler.maxCapacityPerThread=0, -Dlog4j.shutdownHookEnabled=false, -Dlog4j2.disable.jmx=true, -Djava.io.tmpdir=/tmp/elasticsearch-8451650203435461048, -XX:+HeapDumpOnOutOfMemoryError, -XX:HeapDumpPath=data, -XX:ErrorFile=logs/hs_err_pid%p.log, -XX:+PrintGCDetails, -XX:+PrintGCDateStamps, -XX:+PrintTenuringDistribution, -XX:+PrintGCApplicationStoppedTime, -Xloggc:logs/gc.log, -XX:+UseGCLogFileRotation, -XX:NumberOfGCLogFiles=32, -XX:GCLogFileSize=64m, -Des.path.home=/home/too/elasticsearch-6.6.1, -Des.path.conf=/home/too/elasticsearch-6.6.1/config, -Des.distribution.flavor=default, -Des.distribution.type=tar]
[2019-10-09T12:28:55,342][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [aggs-matrix-stats]
[2019-10-09T12:28:55,343][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [analysis-common]
[2019-10-09T12:28:55,343][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [ingest-common]
[2019-10-09T12:28:55,344][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [lang-expression]
[2019-10-09T12:28:55,344][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [lang-mustache]
[2019-10-09T12:28:55,345][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [lang-painless]
[2019-10-09T12:28:55,345][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [mapper-extras]
[2019-10-09T12:28:55,346][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [parent-join]
[2019-10-09T12:28:55,346][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [percolator]
[2019-10-09T12:28:55,347][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [rank-eval]
[2019-10-09T12:28:55,347][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [reindex]
[2019-10-09T12:28:55,348][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [repository-url]
[2019-10-09T12:28:55,348][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [transport-netty4]
[2019-10-09T12:28:55,348][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [tribe]
[2019-10-09T12:28:55,349][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-ccr]
[2019-10-09T12:28:55,349][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-core]
[2019-10-09T12:28:55,350][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-deprecation]
[2019-10-09T12:28:55,350][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-graph]
[2019-10-09T12:28:55,350][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-ilm]
[2019-10-09T12:28:55,351][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-logstash]
[2019-10-09T12:28:55,351][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-ml]
[2019-10-09T12:28:55,352][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-monitoring]
[2019-10-09T12:28:55,352][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-rollup]
[2019-10-09T12:28:55,353][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-security]
[2019-10-09T12:28:55,353][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-sql]
[2019-10-09T12:28:55,354][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-upgrade]
[2019-10-09T12:28:55,354][INFO ][o.e.p.PluginsService ] [ELzCU7U] loaded module [x-pack-watcher]
[2019-10-09T12:28:55,356][INFO ][o.e.p.PluginsService ] [ELzCU7U] no plugins loaded
[2019-10-09T12:29:09,089][INFO ][o.e.x.s.a.s.FileRolesStore] [ELzCU7U] parsed [0] roles from file [/home/too/elasticsearch-6.6.1/config/roles.yml]
[2019-10-09T12:29:10,683][WARN ][o.e.b.ElasticsearchUncaughtExceptionHandler] [ELzCU7U] uncaught exception in thread [main]
org.elasticsearch.bootstrap.StartupException: ElasticsearchException[X-Pack is not supported and Machine Learning is not available for [linux-aarch64]; you can use the other X-Pack features (unsupported) by setting xpack.ml.enabled: false in elasticsearch.yml]
at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:163) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:150) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[elasticsearch-cli-6.6.1.jar:6.6.1]
at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-6.6.1.jar:6.6.1]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:116) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) ~[elasticsearch-6.6.1.jar:6.6.1]
Caused by: org.elasticsearch.ElasticsearchException: X-Pack is not supported and Machine Learning is not available for [linux-aarch64]; you can use the other X-Pack features (unsupported) by setting xpack.ml.enabled: false in elasticsearch.yml
at org.elasticsearch.xpack.ml.MachineLearningFeatureSet.isRunningOnMlPlatform(MachineLearningFeatureSet.java:107) ~[?:?]
at org.elasticsearch.xpack.ml.MachineLearningFeatureSet.isRunningOnMlPlatform(MachineLearningFeatureSet.java:98) ~[?:?]
at org.elasticsearch.xpack.ml.MachineLearning.createComponents(MachineLearning.java:395) ~[?:?]
at org.elasticsearch.node.Node.lambda$new$11(Node.java:470) ~[elasticsearch-6.6.1.jar:6.6.1]
at java.util.stream.ReferencePipeline$7$1.accept(ReferencePipeline.java:269) ~[?:1.8.0_222]
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1382) ~[?:1.8.0_222]
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:482) ~[?:1.8.0_222]
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:472) ~[?:1.8.0_222]
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708) ~[?:1.8.0_222]
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234) ~[?:1.8.0_222]
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:566) ~[?:1.8.0_222]
at org.elasticsearch.node.Node.<init>(Node.java:473) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.node.Node.<init>(Node.java:265) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.bootstrap.Bootstrap$5.<init>(Bootstrap.java:212) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:212) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:333) ~[elasticsearch-6.6.1.jar:6.6.1]
at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:159) ~[elasticsearch-6.6.1.jar:6.6.1]
... 6 more
user@Jetson $
ちなみにelasticsearchはrootユーザでは起動できないらしいので通常ユーザーで実行すること。
エラーの原因は
X-Pack is not supported and Machine Learning is not available for [linux-aarch64]; you can use the other X-Pack features (unsupported) by setting xpack.ml.enabled: false in elasticsearch.yml
らしいので、"elasticsearch.yml"に"xpack.ml.enabled: false"を追記する。
X-PackとMachine Learningの関係
X-Packは標準同梱の拡張機能群(監視、セキュリティ、SQL、MLなど)で、「x-」で始まるログのモジュールがそれにあたる。Machine Learning(x-pack-ml)はx86_64前提でビルドされており、aarch64(Jetson NanoのARM64)では動かない。そのため起動時に例外で落ちる。
xpack.ml.enabled: falseとするとML機能だけ無効化し、他のX-Pack機能は(非サポート扱いで)使える状態で起動できる。検索用途ではMLは不要なので素直に切ってよい。
user@Jetson $ sudo nano ../config/elasticsearch.yml
xpack.ml.enabled: false <-最下行に追記
再度実行すると今度はエラーが出ないはず。
実行した状態で他のターミナルからelasticsearchにアクセスしてみる。
user@Jetson $ curl http://localhost:9200
------------------------------------------以下出力
{
"name" : "ELzCU7U",
"cluster_name" : "elasticsearch",
"cluster_uuid" : "SRqK4n-zRd-vzvh9f4VOkQ",
"version" : {
"number" : "6.6.1",
"build_flavor" : "default",
"build_type" : "tar",
"build_hash" : "1fd8f69",
"build_date" : "2019-02-13T17:10:04.160291Z",
"build_snapshot" : false,
"lucene_version" : "7.6.0",
"minimum_wire_compatibility_version" : "5.6.0",
"minimum_index_compatibility_version" : "5.0.0"
},
"tagline" : "You Know, for Search"
}
ちゃんと動いたっぽい。
このレスポンスの読み方
curl http://localhost:9200はREST APIの疎通確認。返る各項目の意味は次のとおり。
name: ノード名(自動生成。node.nameで固定できる)cluster_name: クラスタ名(既定はelasticsearch)version.number: 本体の版。ここが6.6.1なら意図した版が動いているtagline: Elasticsearchのキャッチコピー使うポートは9200(REST/HTTP)と9300(ノード間transport)の2つ。他のマシンから触るなら9200、クラスタを組むなら9300も開ける。既定では9200はlocalhostバインドなので、外部公開するにはnetwork.hostの変更が要る。
ということで、プラグイン、"analysis-kuromoji"、"analysis-icu"のインストール
user@Jetson $ ./elasticsearch-plugin install analysis-kuromoji
-> Downloading analysis-kuromoji from elastic
[=================================================] 100%
-> Installed analysis-kuromoji
user@Jetson $ ./elasticsearch-plugin install analysis-icu
-> Downloading analysis-icu from elastic
[=================================================] 100%
-> Installed analysis-icu
これでelasticsearchのインストールは完了。
プラグインの役割
analysis-kuromoji: 日本語の形態素解析アナライザ。日本語を単語単位に分割する。これが無いと文字単位の分割になり日本語検索の精度が落ちる。GROWIの日本語検索の要。analysis-icu: ICU(Unicode)ベースの正規化・照合。全角半角、大文字小文字、濁点などのゆれを吸収し、日本語と英数の混在検索の精度が上がる。ヒープの調整
既定のヒープはログにあるとおり約495MB(-Xms512m -Xmx512m)。Jetson Nano 4GBで専用機にするならconfig/jvm.optionsの-Xms/-Xmxを1g程度まで上げると安定する。2GBモデルでは上げすぎない(OSとGROWI本体も同じRAMを使う)。上げる場合はXmsとXmxを同じ値にそろえるのが定石で、ヒープはRAMの半分以下に抑え、残りをLuceneのファイルキャッシュに残す。
systemdに登録する。
サービス化の前に決めておくこと
vm.max_map_countを262144以上にする。既定値のままではElasticsearchが起動時のブートストラップチェックで拒否する。sudo sysctl -w vm.max_map_count=262144で一時設定、/etc/sysctl.confに書けば永続化できる。User/Groupはroot以外にする。ExecStartとWorkingDirectoryは実際の展開パスに合わせる(例の/home/user/...は自分のパスに読み替える)。user@Jetson $ sudo nano /etc/systemd/system/elasticsearch.service
[Unit]
After=syslog.target network.target
[Service]
Environment="JAVA_HOME=/usr/lib/jvm/java-1.8.0-openjdk-arm64" <-修正
ExecStart=/home/user/elasticsearch-6.6.1/bin/elasticsearch <-修正
WorkingDirectory=/home/user/elasticsearch-6.6.1 <-修正
User=user <-修正
Group=user <-修正
Nice=10
SyslogIdentifier=Elasticsearch
StandardOutput=syslog
Restart=on-failure
KillSignal=SIGINT
[Install]
WantedBy=multi-user.target
サービスとして起動する。
user@Jetson $ sudo systemctl daemon-reload
user@Jetson $ sudo systemctl start elasticsearch
user@Jetson $ systemctl enable elasticsearch.service
journalctlで動作を確認。
user@Jetson $ journalctl -f
エラーが出ていなかったらサービスを自動起動。
sudo systemctl enable elasticsearch
どうもjavaが暴走していることもあるっぽい。一度だけ再現した。そういう場合は以下コマンドでPIDを調べてKillする。
「Failed to obtain node lock」など起動失敗の切り分け
ps aux | grep javaで確認し、いたらkillする。data/nodes/以下に残るnode.lockはプロセスが死ねば開放される。ls -lで所有者を確認する。df -hで空きを確認する。空きが閾値(既定95%)を切るとインデックスがread-onlyになる。ss -ltnpで確認する。dmesg | grep -i oomで確認できる。Elasticsearch, Failed to obtain node lock, is the following location writable
ps aux | grep 'java'
kill -9 <PID>
※ 本ページのAmazonリンクにはアフィリエイトタグ(toobf6-22)が付いている。
🤖 このページにはAIエージェント(ノア)による編集・加筆が含まれます。内容の正確性は保証できないため、重要な判断は一次情報でご確認ください。