Docker 中的 Solr

開始使用 Docker 映像

以下說明適用於 solr:8.0.0 及更高版本。

請參閱 Docker Hub 頁面 以取得可用標籤和架構的完整清單。

可用映像

每個版本都提供兩個 Docker 映像,分別為 full 和 slim。這些對應於每個 Solr 版本產生的兩個二進位發行版本。這些發行版本的 Docker 映像可以在以下位置找到

完整發行版本

solr:<版本>

精簡發行版本

solr:<版本>-slim

請參閱 可用 Solr 套件 一節,以取得有關每個發行版本的更多資訊。

使用主機掛載目錄執行 Solr

通常,使用者首先希望在容器中執行單一獨立 Solr 伺服器,其中包含單一核心用於資料,同時將資料儲存在本機目錄中。這對於開發人員來說是一種方便的機制,也可以用於單伺服器生產主機。

mkdir solrdata
docker run -d -v "$PWD/solrdata:/var/solr" -p 8983:8983 --name my_solr solr solr-precreate gettingstarted

然後使用 Web 瀏覽器前往 https://127.0.0.1:8983/ 以檢視 Solr 的管理 UI(調整 Docker 主機的主機名稱)。在 UI 中,按一下「核心管理」,現在應該會看到「gettingstarted」核心。

接下來,載入容器中包含的一些範例資料

docker exec -it my_solr post -c gettingstarted example/exampledocs/manufacturers.xml

在 UI 中,找到「核心選取器」快顯功能表,並選取「gettingstarted」核心,然後選取「查詢」功能表項目。這會為您提供 : 的預設搜尋,這會傳回所有文件。按一下「執行查詢」按鈕,您應該會看到一些包含資料的文件。恭喜!

Docker-Compose

您可以使用 Docker Compose 來執行單一獨立伺服器或多節點叢集。而且您可以使用 Docker 磁碟區,而不是主機掛載目錄。例如,使用包含以下內容的 docker-compose.yml

version: '3'
services:
  solr:
    image: solr
    ports:
     - "8983:8983"
    volumes:
      - data:/var/solr
    command:
      - solr-precreate
      - gettingstarted
volumes:
  data:

您可以直接執行

docker compose up -d

以下是一個範例撰寫檔案,會啟動一個具有 Zookeeper 的 Solr Cloud 叢集。透過建立 Docker 網路,Solr 可以使用內部名稱 zoo 連線到 Zookeeper 容器。

version: '3'
services:
  solr:
    image: solr:9-slim
    ports:
      - "8983:8983"
    networks: [search]
    environment:
      ZK_HOST: "zoo:2181"
    depends_on: [zoo]

  zoo:
    image: zookeeper:3.9
    networks: [search]
    environment:
      ZOO_4LW_COMMANDS_WHITELIST: "mntr,conf,ruok"

networks:
  search:
    driver: bridge

單一命令示範

若要快速示範 Solr Docker,有一個單一命令會啟動 Solr、建立一個名為「demo」的集合,並將範例資料載入其中

docker run --name solr_demo -d -p 8983:8983 solr solr-demo

映像的運作方式

容器包含由 服務安裝腳本 安裝的 Solr 安裝。這會將 Solr 發行版本儲存在 /opt/solr 中,並將 Solr 設定為使用 /var/solr 來儲存資料和記錄,同時使用 /etc/default/solr 檔案進行設定。如果您想要保存資料,請在 /var/solr 上掛載磁碟區或目錄。Solr 需要 /var/solr 中的某些檔案和目錄;如果您使用自己的目錄或磁碟區,您可以預先填入它們,或讓 Solr Docker 為您複製它們。如果您想要使用自訂設定,請將其掛載在適當的位置。請參閱以下範例。

Solr Docker 發行版本會在 /opt/solr/docker/scripts 中新增指令碼,以便在 Docker 下更容易使用,例如在容器啟動時建立核心。

建立核心

當 Solr 以獨立模式執行時,您會建立「核心」來儲存資料。在非 Docker Solr 上,您會在背景中執行伺服器,然後使用 Solr 控制指令碼 來建立核心並載入資料。使用 Solr Docker,您有各種選項。

手動

第一種方式完全相同:啟動在容器中執行的 Solr,然後在同一個容器中手動執行控制指令碼

docker run -d -p 8983:8983 --name my_solr solr
docker exec -it my_solr solr create_core -c gettingstarted

這對使用者來說不是很方便,而且更難將其轉換為 Docker Compose 和 Kubernetes 等協調工具的設定。

使用 solr-precreate 命令

因此,您通常會使用 solr-precreate 命令,該命令會準備指定的核心,然後執行 Solr

docker run -d -p 8983:8983 --name my_solr solr solr-precreate gettingstarted

solr-precreate 命令接受一個可選的額外參數,以指定 /opt/solr/server/solr/configsets/ 目錄下的 configset 目錄,或者您可以指定容器內自訂 configset 的完整路徑。

docker run -d -p 8983:8983 --name my_solr -v $PWD/config/solr:/my_core_config/conf solr:8 solr-precreate my_core /my_core_config

注意:當指定 configset 的完整路徑時,實際的核心組態應位於該目錄內的 conf 目錄中。詳情請參閱 Configsets

使用 solr-create 命令

第三種選項是使用 solr-create 命令。這會在容器中於背景執行 Solr,然後使用 Solr 控制腳本來建立核心,接著停止 Solr 伺服器並在前台重新啟動。這種方法比較不常見,因為雙重 Solr 執行可能會造成混淆。

docker run -d -p 8983:8983 --name my_solr solr solr-create -c gettingstarted

自訂設定腳本

最後,您可以執行自己的命令列並指定要執行的動作,甚至調用已掛載的腳本。例如:

docker run -p 8983:8983 -v $PWD/mysetup.sh:/mysetup.sh --name my_solr solr bash -c "precreate-core gettingstarted && source /mysetup.sh && solr-foreground"

建立集合

在「SolrCloud」叢集中,您會建立「集合」來儲存資料;並且,您有多種建立核心的選項。

這些範例假設您正在執行 docker compose 叢集

建立集合的第一種方法是前往 Solr 管理 UI,從左側導覽選單中選取「集合」,然後按下「新增集合」按鈕,給予集合一個名稱,選取 _default 設定集,然後按下「新增集合」按鈕。

第二種方法是透過其中一個容器上的 Solr 控制腳本。

docker exec solr1 solr create -c gettingstarted2

第三種方法是使用單獨的容器。

docker run -e SOLR_HOST=solr1 --network docs_solr solr solr create_collection -c gettingstarted3 -p 8983

第四種方法是使用遠端 API,從主機或其中一個容器,或同一個網路上的某些新容器 (請相應地調整主機名稱)。

curl 'https://127.0.0.1:8983/solr/admin/collections?action=CREATE&name=gettingstarted3&numShards=1&collection.configName=_default'

如果您想為您的集合使用自訂組態,您必須先上傳它,然後在建立集合時依名稱引用它。您可以使用 bin/solr zk 命令Configsets API

載入您自己的資料

有多種載入資料的方法;讓我們看看最常見的方法。

最常見的首次部署是在工作站或伺服器上,以獨立 (非叢集) 模式執行 Solr,您需要在該處載入本機資料。其中一種方法是使用單獨的容器,其中掛載包含資料的磁碟區,並使用主機網路,以便您可以連線到對應的連接埠。

# start Solr. Listens on localhost:8983
docker run --name my_solr -p 8983:8983 solr solr-precreate books

# get data
mkdir mydata
wget -O mydata/books.csv https://raw.githubusercontent.com/apache/solr/main/solr/example/exampledocs/books.csv
docker run --rm -v "$PWD/mydata:/mydata" --network=host solr post -c books /mydata/books.csv

如果您使用 範例 docker compose 叢集,或只是在同一個網路中啟動載入容器,也適用相同的方法。

docker run -e SOLR_HOST=solr1 --network=mycluster_solr solr solr create -c books -p 8983
docker run --rm -v "$PWD/mydata:/mydata" --network=mycluster_solr solr post -c books /mydata/books.csv --host solr1

或者,您可以在 Solr 啟動時將資料放在磁碟區上,然後從 docker exec 或自訂啟動腳本中載入資料。

solr.in.sh 組態

在 Solr 中,通常會在 solr.in.sh 中組態設定,如 環境覆寫包含檔案 一節所述。

solr.in.sh 檔案可以在 /etc/default 中找到。

docker run solr cat /etc/default/solr.in.sh

它有各種註解掉的值,您可以在執行容器時覆寫這些值,例如:

docker run -d -p 8983:8983 -e SOLR_HEAP=800m solr

您也可以掛載自己的組態檔案。請勿修改檔案結尾處設定的值。

擴充映像檔

Solr Docker 映像檔具有擴充機制。在執行時,在啟動 Solr 之前,容器將執行 /docker-entrypoint-initdb.d/ 目錄中的腳本。您可以透過使用掛載的磁碟區或使用自訂 Dockerfile,將您自己的腳本新增至該處。這些腳本可以例如複製具有預先載入資料的核心目錄,以進行持續整合測試,或修改 Solr 組態。

以下是一個簡單的範例。使用類似於這樣的 custom.sh 腳本:

#!/bin/bash
set -e
echo "this is running inside the container before Solr starts"

您可以執行:

$ docker run --name solr_custom1 -d -v $PWD/custom.sh:/docker-entrypoint-initdb.d/custom.sh solr
$ sleep 5
$ docker logs solr_custom1 | head
/opt/docker-solr/scripts/docker-entrypoint.sh: running /docker-entrypoint-initdb.d/set-heap.sh
this is running inside the container before Solr starts

Starting Solr on port 8983 from /opt/solr/server

透過此擴充機制,檢視 Docker 日誌中 docker-entrypoint.sh 腳本正在執行的 Shell 命令會很有幫助。若要執行此操作,請使用 Docker 的 -e VERBOSE=yes 設定環境變數。

當然,除了使用這種機制之外,您也可以建立自己的腳本來進行設定,然後調用 solr-foreground,將該腳本掛載到容器中,並在執行容器時將其作為命令執行。

擴充映像檔的其他方法是建立繼承自此映像檔的自訂 Docker 映像檔。

使用 jattach 進行偵錯

jcmdjmapjstack 工具可用於偵錯容器內的 Solr。這些工具不包含在 JRE 中,但此映像檔包含 jattach 公用程式,可讓您執行許多相同的操作。

Usage: jattach <pid> <cmd> [args ...]

  Commands:
    load : load agent library
    properties : print system properties
    agentProperties : print agent properties
    datadump : show heap and thread summary
    threaddump : dump all stack traces (like jstack)
    dumpheap : dump heap (like jmap)
    inspectheap : heap histogram (like jmap -histo)
    setflag : modify manageable VM flag
    printflag : print VM flag
    jcmd : execute jcmd command

若要找出 Solr 的 PID,您可以執行下列命令:

ps -ef | grep java

執行緒傾印和取得 PID 10 的堆積資訊的範例命令:

jattach 10 threaddump
jattach 10 jcmd GC.heap_info

在 tini 下執行

Solr Docker 映像檔在 tini 下執行 Solr,以使訊號處理運作得更好;特別是,這允許您 kill -9 JVM。如果您執行 docker run --init,或在 docker-compose.yml 中使用 init: true,或將 --init 新增至 dockerd,則 Docker 將啟動其 tini,而 docker-solr 將會注意到它不是 PID 1,而只是 exec Solr。如果您不使用 --init 執行,則 Docker 進入點腳本會偵測到它以 PID 1 執行,並將啟動 docker-solr 映像檔中存在的 tini,並在該 tini 下執行 Solr。如果您真的不想執行 tini,而只是改為以 PID 1 執行 Solr,則可以設定 TINI=no 環境變數。

記憶體不足處理

如需更多資訊,請參閱 記憶體不足處理 一節。Docker 映像檔不再具有 OOM 的自訂邏輯。

歷史

Docker-Solr 專案於 2015 年由 Martijn Kosterdocker-solr 儲存庫中啟動。2019 年,維護和版權轉移給 Apache Lucene/Solr 專案,並於 2020 年將專案移至 Solr 專案內。非常感謝 Martijn 多年來的貢獻!