パッケージマネージャーの内部構造
パッケージマネージャー (CLI) は、内部的にさまざまな Solr API を使用して、パッケージのインストール、デプロイ、および更新を行います。このドキュメントでは、これらの API の概要について説明します。
主な機能
-
中断のないデプロイ (ホットデプロイ): ノードの再起動やコアのリロードなしでパッケージをインストールおよび更新できる必要があるため、デプロイは迅速であり、リクエストの失敗や古いキャッシュなしに行われる必要があります。
-
簡単なパッケージング
-
クエリパーサー、検索コンポーネント、リクエストハンドラー、URP などの標準プラグインの概念は、特別なコード/パッケージの変更なしにサポートされる必要があります。
-
ユーザーがすでにデプロイしている (および本番環境で使用している) アーティファクト (カスタムプラグインを含む jar) は、再コンパイルや再パッケージングをしなくても、より多くの採用のために互換性がある必要があります。
-
単一の jar パッケージと複数の jar パッケージの両方をサポートする必要があります。
-
使い慣れた/標準的な命名を使用する
-
apt、dnf、homebrew などのようなパッケージマネージャーに関する業界標準の概念と用語を使用します。
-
クラスローダー
システムの中心には、クラスローダーの分離があります。これを実現するために、システムは 2 層のクラスローダーに単純化されています。
-
Solr クラスパスのすべての jar を持つルートクラスローダー。これを変更するには、Solr ノードの再起動が必要です。
-
ルートクラスローダーから継承する名前付きクラスローダーのセット。名前付きクラスローダーのライフサイクルは、ZooKeeper のパッケージ構成に結び付けられています。構成が変更されるとすぐに、対応するクラスローダーがリロードされ、コンポーネントがリロードを求められます。
パッケージのロードセキュリティ
パッケージはデフォルトで無効になっています。この機能を使用するには、システムプロパティ -Denable.packages=true
を指定してすべてのノードを起動します。
例
bin/solr -c -Denable.packages=true
パッケージストア
パッケージストアは、ファイルシステムに任意のファイルを保存できる分散ファイルストアです。
-
これは、完全にレプリケートされたファイルシステムベースのリポジトリです。
-
各Solrノードの
<solr.home>/filestore
に存在します。 -
各エントリは、ファイルとメタデータで構成されます。メタデータは
.<filename>.json
という名前です。 -
メタデータファイルには、ファイルのsha256、署名が含まれます。
-
ユーザーはピリオド(.)で始まるファイルを作成できません。
-
ファイルのコンテンツタイプには依存しません。jarファイルだけでなく、他のファイルも保存できます。
パッケージストアの仕組み
ファイルがパッケージストアにアップロードされると、次のようになります。
-
ローカルファイルシステムに保存されます。
-
メタデータとともに保存されます。メタデータファイルには、jarファイルのsha512と署名も保存されます。
-
クラスタ内のすべての稼働中のノードにも、ダウンロードするように要求されます。
パッケージストアAPI
エンドポイントは以下のとおりです。
-
各ノードの
PUT /api/cluster/files/{フル/パス/ファイルへ}
-
ファイルのダウンロードには
GET /api/node/files/{フル/パス/ファイルへ}
-
ファイルのメタデータ取得には
GET /api/node/files/{フル/パス/ファイルへ}?meta=true
-
/フル/パス/へ
にあるファイルの一覧取得にはGET /api/node/files/{フル/パス/へ}
アーティファクトの署名
公開鍵で署名されたjarをアップロードするには、次の手順に従います。
-
プラグインを含むjarファイルがない場合は、GitHubからサンプルをダウンロードしてください。
curl -o runtimelibs.jar -LO https://github.com/apache/solr/blob/releases/solr/9.5.0/solr/core/src/test-files/runtimecode/runtimelibs.jar.bin?raw=true
-
秘密鍵でjarに署名します。
openssl dgst -sha1 -sign my_key.pem runtimelibs.jar | openssl enc -base64 | sed 's/+/%2B/g' | tr -d \\n | sed
-
署名付きjarをアップロードし、
sig
パラメータを前のコマンドの出力で置き換えます。curl --data-binary @runtimelibs.jar -X PUT https://127.0.0.1:8983/api/cluster/files/mypkg/1.0/myplugins.jar?sig=<signature-of-jar>
-
jarのアップロードを検証します。
curl https://127.0.0.1:8983/api/node/files/mypkg/1.0?omitHeader=true
{ "files":{"/mypkg/1.0":[{ "name":"myplugins.jar", "timestamp":"2019-11-11T07:36:17.354Z", "sha512":"d01b51de67ae1680a84a813983b1de3b592fc32f1a22b662fc9057da5953abd1b72476388ba342cad21671cd0b805503c78ab9075ff2f3951fdf75fa16981420", "sig":["elNjhmWIOgTgbAzeZ+OcwR42N7vqL6Ig9eAqn4YoP2thT7FJuhiaZuCPivjMkD682EBo9gveSCTyXIsZKjOCbQ=="]}]}}
パッケージ
パッケージには次の属性があります。
-
一意の名前
-
次の属性を持つ1つ以上のバージョン
-
version
:バージョン文字列 -
files
:パッケージストアからのファイルの配列
-
パッケージ定義内のすべてのパッケージ/バージョンに対して、一意のSolrResourceLoader
インスタンスが存在します。これはCoreContainer
リソースローダーの子です。
Solrは、バージョン文字列が特定の形式に従うことを要求しません。任意の文字列、または空の文字列でも構いません。 |
packages.json
パッケージ構成は、ZooKeeper内のpackages.json
というファイルに存在します。任意の時点で、パッケージ構成内に特定のパッケージの複数のバージョンを持つことができます。システムは常に最新バージョンを使用します。バージョンは、それらの値を辞書式順序でソートされ、最大の文字列が最新と見なされます。
バージョン文字列の辞書式順序とは、バージョンが1.2.0、1.9.0、1.11.0のパッケージの場合、Solrは1.9.0を最新バージョンとして選択することを意味します。 |
例:
{
"packages" : {
"mypkg" : {
"name": "mypkg",
"versions": [
{"version" : "0.1",
"files" : ["/path/to/myplugin/1.1/plugin.jar"]
},
{"version" : "0.2",
"files" : ["/path/to/myplugin/1.0/plugin.jar"]
}]}}}
APIエンドポイント
-
GET /api/cluster/package
パッケージの一覧を取得 -
POST /api/cluster/package
パッケージを編集-
add
コマンド:パッケージのバージョンを追加 -
delete
コマンド:パッケージのバージョンを削除
-
複数のバージョンを並行して使用する
コレクション構成のparams.json
を使用して、使用するパッケージのバージョンを保存します。デフォルトでは、$LATEST
です。
{"params":{
"PKG_VERSIONS": {
"mypkg": "0.1", (1)
"pkg2" : "$LATEST", (2)
}}}
1 | mypkg の場合、新しいバージョンが利用可能かどうかに関係なく、バージョン0.1 を使用します。 |
2 | pkg2 の場合、最新のものを使用します。これはオプションです。デフォルトは$LATEST です。 |
したがって、上記の例では、 |
ワークフロー
-
パッケージの新しいバージョンが追加されます。
-
パッケージローダーはクラスをロードし、新しいバージョンの可用性をすべてのプラグインホルダーに通知します。
-
特定のバージョンを使用することになっているかどうかを確認し、更新を無視します。
-
そうでない場合は、プラグインをリロードします。
プラグインでのパッケージの使用
任意のクラス名の前にパッケージ名を付けることができます(例:mypkg:fully.qualified.ClassName
)。Solrは、最新バージョンのパッケージを使用してクラスをロードします。パッケージからロードされたプラグインは、コアレベルのクラスに依存することはできません。
solrconfig.xml
でのプラグイン宣言<requestHandler name="/myhandler" class="mypkg:full.path.to.MyClass">
</requestHandler>
完全な動作例
-
パッケージを作成します。
curl https://127.0.0.1:8983/api/cluster/package -H 'Content-type:application/json' -d ' {"add": { "package" : "mypkg", "version":"1.0", "files" :["/mypkg/1.0/myplugins.jar"]}}'
-
作成したパッケージを検証します。
curl https://127.0.0.1:8983/api/cluster/package?omitHeader=true
{"result":{ "znodeVersion":0, "packages":{"mypkg":[{ "version":"1.0", "files":["/mypkg/1.0/myplugins.jar"]}]}}}
-
この時点で、パッケージは使用できるようになっているはずです。次に、パッケージからコレクションにプラグインを登録します。
class
属性に適用されたmypkg:
プレフィックスに注意してください。同じ結果は、solrconfig.xml
を編集することでも実現できます。curl https://127.0.0.1:8983/solr/gettingstarted/config -H 'Content-type:application/json' -d '{ "create-requesthandler": { "name": "/test", "class": "mypkg:org.apache.solr.core.RuntimeLibReqHandler" }}'
-
コンポーネントが作成され、パッケージの正しいバージョンを使用してクラスをロードしていることを確認します。
curl https://127.0.0.1:8983/solr/gettingstarted/config/requestHandler?componentName=/test&meta=true&omitHeader=true
{ "config":{"requestHandler":{"/test":{ "name":"/test", "class":"mypkg:org.apache.solr.core.RuntimeLibReqHandler", "_packageinfo_":{ "package":"mypkg", "version":"1.0", "files":["/mypkg/1.0/myplugins.jar"]}}}}}
-
リクエストハンドラーをテストします。
curl https://127.0.0.1:8983/solr/gettingstarted/test?omitHeader=true
{ "params":{ "omitHeader":"true"}, "context":{ "webapp":"/solr", "path":"/test", "httpMethod":"GET"}, "class":"org.apache.solr.core.RuntimeLibReqHandler", "loader":"java.net.FactoryURLClassLoader"}
-
コンポーネントのバージョンを更新します。新しいバージョンのjarを取得し、署名してアップロードします。
curl -o runtimelibs3.jar -LO https://github.com/apache/solr/blob/releases/solr/9.5.0/solr/core/src/test-files/runtimecode/runtimelibs_v3.jar.bin?raw=true openssl dgst -sha1 -sign my_key.pem runtimelibs.jar | openssl enc -base64 | sed 's/+/%2B/g' | tr -d \\n | sed curl --data-binary @runtimelibs3.jar -X PUT https://127.0.0.1:8983/api/cluster/files/mypkg/2.0/myplugins.jar?sig=
-
検証します。
curl https://127.0.0.1:8983/api/node/files/mypkg/2.0?omitHeader=true
{ "files":{"/mypkg/2.0":[{ "name":"myplugins.jar", "timestamp":"2019-11-11T11:46:14.771Z", "sha512":"60ec88c2a2e9b409f7afc309273383810a0d07a078b482434eda9674f7e25b8adafa8a67c9913c996cbfb78a7f6ad2b9db26dbd4fe0ca4068f248d5db563f922", "sig":["ICkC+nGE+AqiANM0ajhVPNCQsbPbHLSWlIe5ETV5835e5HqndWrFHiV2R6nLVjDCxov/wLPo1uK0VzvAPIioUQ=="]}]}}
-
パッケージの新しいバージョンを追加します。
curl https://127.0.0.1:8983/api/cluster/package -H 'Content-type:application/json' -d ' {"add": { "package" : "mypkg", "version":"2.0", "files" :["/mypkg/2.0/myplugins.jar"]}}'
-
プラグインを検証して、パッケージの正しいバージョンが使用されているかどうかを確認します。
curl https://127.0.0.1:8983/solr/gettingstarted/config/requestHandler?componentName=/test&meta=true&omitHeader=true
{ "config": { "requestHandler": { "/test": { "name": "/test", "class": "mypkg:org.apache.solr.core.RuntimeLibReqHandler", "_packageinfo_": { "package": "mypkg", "version": "2.0", "files": [ "/mypkg/2.0/myplugins.jar" ] }}}}}
-
プラグインをテストします。
curl https://127.0.0.1:8983/solr/gettingstarted/test?omitHeader=true
{ "params": { "omitHeader": "true" }, "context": { "webapp": "/solr", "path": "/test", "httpMethod": "GET" }, "class": "org.apache.solr.core.RuntimeLibReqHandler", "loader": "java.net.FactoryURLClassLoader", "Version": "2" }
Version
の値が"2"
であることに注意してください。これは、プラグインが更新されたことを意味します。
自動アップグレードを回避する方法
任意のコレクションで使用されるデフォルトのバージョンは常に最新です。ただし、params.json
にコレクションごとのプロパティを設定すると、コレクションは、後でSolrに追加される可能性のある2.0よりも後のバージョンに関係なく、同じパッケージバージョン(つまり、バージョン2.0)を使用することが保証されます。
curl https://127.0.0.1:8983/solr/gettingstarted/config/params -H 'Content-type:application/json' -d '{
"set":{
"PKG_VERSIONS":{
"mypkg":"2.0"
}
}}'