將 Solr 投入生產環境

本節提供關於如何在 *nix 平台(例如 Ubuntu)上設定 Solr 以在生產環境中執行的指南。具體來說,我們將逐步說明如何在 Linux 主機上設定執行單一 Solr 執行個體的過程,然後提供關於如何支援在同一主機上執行多個 Solr 節點的提示。

服務安裝指令碼

Solr 包含一個服務安裝指令碼 (bin/install_solr_service.sh),可協助您在 Linux 上將 Solr 安裝為服務。目前,該指令碼僅支援 CentOS、Debian、Red Hat、SUSE 和 Ubuntu Linux 發行版本。執行指令碼之前,您需要確定一些關於您設定的參數。具體來說,您需要決定將 Solr 安裝在哪裡,以及哪個系統使用者應該是 Solr 檔案和程序的擁有者。

規劃您的目錄結構

我們建議將您的即時 Solr 檔案(例如日誌和索引檔案)與 Solr 發行套件中包含的檔案分開,因為這樣可以更容易升級 Solr,並且被視為系統管理員應遵循的良好實務。

Solr 安裝目錄

預設情況下,服務安裝指令碼會將發行壓縮檔解壓縮到 /opt。您可以在執行安裝指令碼時使用 -i 選項來變更此位置。指令碼還會建立指向 Solr 版本目錄的符號連結。例如,如果您執行 Solr 9.7.0 的安裝指令碼,則會使用以下目錄結構

/opt/solr-9.7.0
/opt/solr -> /opt/solr-9.7.0

使用符號連結可使任何指令碼都不依賴於特定的 Solr 版本。如果未來您需要升級到較新版本的 Solr,您只需更新符號連結以指向升級後的 Solr 版本。在本頁的其餘章節中,我們將使用 /opt/solr 來指稱 Solr 安裝目錄。

可寫入檔案的獨立目錄

您也應該將可寫入的 Solr 檔案分隔到不同的目錄中;預設情況下,安裝指令碼使用 /var/solr,但您可以使用 -d 選項覆寫此位置。使用這種方法,/opt/solr 中的檔案將保持不變,而當 Solr 執行時變更的所有檔案都將位於 /var/solr 下。

建立 Solr 使用者

不建議以 root 身分執行 Solr,因為這樣不安全,而且 bin/solr start 命令會拒絕這樣做。因此,您應該確定將擁有所有 Solr 檔案和執行中 Solr 程序的系統使用者名稱。預設情況下,安裝指令碼會建立 solr 使用者,但您可以使用 -u 選項覆寫此設定。如果您的組織對建立新使用者帳戶有特定要求,則您應該在執行指令碼之前建立使用者。安裝指令碼將使 Solr 使用者成為 /opt/solr/var/solr 目錄的擁有者。

您現在可以執行安裝指令碼了。

執行 Solr 安裝指令碼

若要執行指令碼,您需要下載最新的 Solr 發行壓縮檔,然後執行以下操作

tar xzf solr-9.7.0.tgz solr-9.7.0/bin/install_solr_service.sh --strip-components=2

先前的命令會將 install_solr_service.sh 指令碼從壓縮檔解壓縮到目前目錄。如果安裝在 Red Hat 上,請確保在執行 Solr 安裝指令碼之前已安裝 lsof (sudo yum install lsof)。安裝指令碼必須以 root 身分執行

sudo bash ./install_solr_service.sh solr-9.7.0.tgz

預設情況下,該指令碼會將發行壓縮檔解壓縮到 /opt,設定 Solr 將檔案寫入 /var/solr,並以 solr 使用者身分執行 Solr。因此,以下命令會產生與先前命令相同的結果

sudo bash ./install_solr_service.sh solr-9.7.0.tgz -i /opt -d /var/solr -u solr -s solr -p 8983

您可以使用傳遞給安裝腳本的選項,自訂服務名稱、安裝目錄、連接埠和擁有者。若要查看可用的選項,只需執行以下操作:

sudo bash ./install_solr_service.sh --help

一旦腳本完成,Solr 將會以服務的形式安裝,並在您的伺服器背景執行(在 8983 連接埠上)。若要驗證,您可以執行:

sudo service solr status

如果您不想立即啟動服務,請傳遞 -n 選項。之後您可以稍後手動啟動服務,例如在完成組態設定之後。

我們稍後將介紹一些您可以進行的其他組態設定,以微調您的 Solr 設定。在繼續之前,我們先仔細看看安裝腳本執行的步驟。這可讓您更好地了解,並在閱讀本指南中的其他頁面時,幫助您了解有關 Solr 安裝的重要詳細資訊;例如,當頁面提到 Solr 主目錄時,您會確切知道它在您系統上的位置。

Solr 主目錄

Solr 主目錄(不要與 Solr 安裝目錄混淆)是 Solr 管理含有索引檔案的核心目錄的位置。預設情況下,安裝腳本使用 /var/solr/data。如果安裝腳本使用了 -d 選項,則此路徑會變更為傳遞給 -d 選項的位置中的 data 子目錄。請花點時間檢查您系統上 Solr 主目錄的內容。如果您沒有將 solr.xml 儲存在 ZooKeeper 中,則主目錄必須包含 solr.xml 檔案。當 Solr 啟動時,Solr 控制腳本會使用 -Dsolr.solr.home=…​ 系統屬性傳遞主目錄的位置。

環境覆寫包含檔案

服務安裝腳本會建立一個環境特定的包含檔案,以覆寫 bin/solr 腳本使用的預設值。使用包含檔案的主要優點是,它提供了一個位置來定義所有環境特定的覆寫。請花點時間檢查 /etc/default/solr.in.sh 檔案的內容,這是安裝腳本設定的預設路徑。如果您在安裝腳本上使用了 -s 選項來變更服務的名稱,則檔案名稱的第一部分將會不同。對於名為 solr-demo 的服務,該檔案將命名為 /etc/default/solr-demo.in.sh。您可以使用此檔案覆寫許多設定。但是,至少此腳本需要定義 SOLR_PID_DIRSOLR_HOME 變數,例如:

SOLR_PID_DIR=/var/solr
SOLR_HOME=/var/solr/data

SOLR_PID_DIR 變數會設定 控制腳本 會將包含 Solr 伺服器處理程序 ID 的檔案寫入其中的目錄。

記錄設定

Solr 使用 Apache Log4J 進行記錄。安裝腳本會將 /opt/solr/server/resources/log4j2.xml 複製到 /var/solr/log4j2.xml。請花點時間驗證 Solr 包含檔案是否設定為將記錄傳送到正確的位置,方法是檢查 /etc/default/solr.in.sh 中的以下設定:

LOG4J_PROPS=/var/solr/log4j2.xml
SOLR_LOGS_DIR=/var/solr/logs

如需更多關於 Log4J 設定的資訊,請參閱:設定記錄

init.d 腳本

當在 Linux 上執行像 Solr 這樣的服務時,通常會設定 init.d 腳本,以便系統管理員可以使用服務工具來控制 Solr,例如:service solr start。安裝腳本會建立一個非常基本的 init.d 腳本來幫助您入門。請花點時間檢查 /etc/init.d/solr 檔案,這是安裝腳本設定的預設腳本名稱。如果您在安裝腳本上使用了 -s 選項來變更服務的名稱,則檔案名稱將會不同。請注意,以下變數會根據傳遞給安裝腳本的參數,為您的環境設定:

SOLR_INSTALL_DIR=/opt/solr
SOLR_ENV=/etc/default/solr.in.sh
RUNAS=solr

SOLR_INSTALL_DIRSOLR_ENV 變數應該是不言自明的。RUNAS 變數會設定 Solr 處理程序的擁有者,例如 solr;如果您不設定此值,腳本將會以 root 身分執行 Solr,這不建議用於生產環境。您可以透過以 root 身分執行以下操作來使用 /etc/init.d/solr 腳本啟動 Solr:

service solr start

/etc/init.d/solr 腳本也支援 stoprestartstatus 命令。請記住,Solr 隨附的 init 腳本非常基本,旨在向您展示如何將 Solr 設定為服務。但是,也常見使用更進階的工具,例如 supervisordupstart 來控制 Linux 上的 Solr 服務。雖然展示如何將 Solr 與 supervisord 等工具整合超出了本指南的範圍,但 init.d/solr 腳本應該提供足夠的指導來幫助您入門。此外,安裝腳本會將 Solr 服務設定為在主機初始化時自動啟動。

進度檢查

在下一節中,我們將介紹一些其他的環境設定,以幫助您微調生產環境設定。但是,在我們繼續之前,我們先回顧一下到目前為止我們所取得的成果。具體來說,您應該能夠使用 /etc/init.d/solr 控制 Solr。請驗證以下命令是否在您的設定中運作:

sudo service solr restart
sudo service solr status

status 命令應該會提供一些關於正在執行的 Solr 節點的基本資訊,看起來類似於:

Solr process PID running on port 8983
{
  "version":"5.0.0 - ubuntu - 2014-12-17 19:36:58",
  "startTime":"2014-12-19T19:25:46.853Z",
  "uptime":"0 days, 0 hours, 0 minutes, 8 seconds",
  "memory":"85.4 MB (%17.4) of 490.7 MB"}

如果 status 命令不成功,請在 /var/solr/logs/solr.log 中尋找錯誤訊息。

微調您的生產環境設定

ConcurrentMergeScheduler 的動態預設值

合併排程器在 solrconfig.xml 中設定,預設為 ConcurrentMergeScheduler。此排程器使用多個執行緒在背景中合併 Lucene 區段。

預設情況下,ConcurrentMergeScheduler 會自動偵測 maxThreadCountmaxMergeCount 的預設值。maxThreadCount 會設定為 4 或 JVM 可用的處理器數量的一半,以較大者為準,而 maxMergeCount 會設定為 maxThreadCount+5

如果您有旋轉磁碟,最好在 SolrConfig.xml 的 IndexConfig 區段中明確設定 maxThreadCountmaxMergeCount 的值,以便使用適合您硬體的數值。

記憶體和 GC 設定

預設情況下,bin/solr 腳本會將最大 Java 堆積大小設定為 512MB (-Xmx512m),這對於開始使用 Solr 來說是沒問題的。對於生產環境,您會希望根據搜尋應用程式的記憶體需求增加最大堆積大小;對於生產伺服器來說,8 到 16 GB 之間的值並不罕見。當您需要變更 Solr 伺服器的記憶體設定時,請使用包含檔案中的 SOLR_HEAP 變數,例如:

SOLR_HEAP="8g"

除非您知道自己需要非常大的 Java 堆積,否則請勿配置。請參閱 選擇記憶體堆積設定 以取得詳細資訊。

此外,Solr 控制腳本隨附一組預先設定的 Garbage First 垃圾收集設定,這些設定已證明在許多不同的 Solr 工作負載中運作良好。但是,這些設定可能無法很好地滿足您對 Solr 的特定使用。因此,您可能需要變更 GC 設定,這也應該使用 /etc/default/solr.in.sh 包含檔案中的 GC_TUNE 變數來完成。

您也可以參考 JVM 設定 以調整您的記憶體和垃圾收集設定。

記憶體不足處理

bin/solr 腳本使用 -XX:+CrashOnOutOfMemoryError JVM 選項在發生 OutOfMemoryError 例外狀況時讓 Solr 當機。建議使用此行為。在 SolrCloud 模式下,ZooKeeper 會立即收到節點發生了無法復原的錯誤的通知。

使用 SolrCloud 上線生產環境

若要以 SolrCloud 模式執行 Solr,您需要在包含檔案中設定 ZK_HOST 變數,以指向您的 ZooKeeper 集群。生產環境中不支援執行內嵌的 ZooKeeper。例如,如果您的 ZooKeeper 集群在預設的用戶端連接埠 2181 (zk1、zk2 和 zk3) 上託管在以下三個主機上,則您可以設定:

ZK_HOST=zk1,zk2,zk3

當設定了 ZK_HOST 變數時,Solr 將會以「雲端」模式啟動。

ZooKeeper chroot

如果您使用的 ZooKeeper 執行個體與其他系統共用,建議使用 ZooKeeper 的 chroot 支援來隔離 SolrCloud znode 樹。例如,若要確保 SolrCloud 建立的所有 znodes 都儲存在 /solr 下方,您可以在 ZK_HOST 連接字串的末尾放置 /solr,例如:

ZK_HOST=zk1,zk2,zk3/solr

首次使用 chroot 之前,您需要使用 Solr 控制腳本 在 ZooKeeper 中建立根路徑 (znode)。我們可以使用 mkroot 命令來執行此操作:

bin/solr zk mkroot /solr -z <ZK_node>:<ZK_PORT>

未知核心刪除

當 Solr 從檔案系統載入核心時,它將檢查 ZooKeeper 中是否存在對應的叢集狀態。如果不存在對應的項目,則會略過該核心,並記錄警告。這可防止錯誤設定(例如,連線到錯誤的 ZooKeeper 執行個體或 chroot),在更正設定後索引仍然有效。但是,您可能需要手動刪除不想要的、未在有計劃刪除集合時成功移除的核心。

如果您希望自動移除孤立的檔案,您可以編輯您的包含檔案,將 SOLR_DELETE_UNKNOWN_CORES 設定為 true

SOLR_DELETE_UNKNOWN_CORES=true

Solr 主機名稱

使用包含檔案中的 SOLR_HOST 變數設定 Solr 伺服器的主機名稱。

SOLR_HOST=solr1.example.com

建議設定 Solr 伺服器的主機名稱,尤其是在以 SolrCloud 模式執行時,因為這會決定節點在 ZooKeeper 中註冊時的位址。

管理 UI 中的環境橫幅

為了防止意外對錯誤的叢集進行變更,您可以在管理介面中設定視覺指示,以顯示您目前是否正在使用生產環境。為此,請編輯您的 solr.in.shsolr.in.cmd 檔案,並加入 -Dsolr.environment=prod 設定,或設定名為 environment 的叢集屬性。允許的值為 devteststageprod。每個值都有預設的標籤和顏色。若要指定標籤和/或顏色,請使用以逗號分隔的格式,如下所示。標籤必須在顏色之前定義。可以使用 + 字元來代替空格,以避免使用引號。顏色可以是有效的 CSS 顏色或數值,例如 #ff0000 代表鮮紅色。以下是一些有效的環境設定範例:

  • prod (預設標籤為 'Production',預設顏色為紅色系)

  • test,label=Functional+test (預設顏色將維持黃色,但會覆寫標籤)

  • dev,label=MyDev,color=blue (使用名稱覆寫標籤和顏色)

  • stage,color=#ff8888 (使用代碼自訂顏色)

覆寫 solrconfig.xml 中的設定

Solr 允許使用 Java 系統屬性 (在啟動時使用 -Dproperty=value 語法傳遞) 來覆寫組態屬性。例如,在 solrconfig.xml 中,預設的自動軟提交設定設定如下:

<autoSoftCommit>
  <maxTime>${solr.autoSoftCommit.maxTime:3000}</maxTime>
</autoSoftCommit>

一般來說,當您在 Solr 組態檔案中看到使用 ${solr.PROPERTY:DEFAULT_VALUE} 語法的屬性時,您就知道可以使用 Java 系統屬性來覆寫它。例如,若要將軟提交的 maxTime 設定為 10 秒,您可以使用 -Dsolr.autoSoftCommit.maxTime=10000 來啟動 Solr,例如:

bin/solr start -Dsolr.autoSoftCommit.maxTime=10000

bin/solr 指令碼只會在啟動期間將以 -D 開頭的選項傳遞給 JVM。為了在生產環境中執行,我們建議在 include 檔案中定義的 SOLR_OPTS 變數中設定這些屬性。延續我們的軟提交範例,在 /etc/default/solr.in.sh 中,您應該執行:

SOLR_OPTS="$SOLR_OPTS -Dsolr.autoSoftCommit.maxTime=10000"

Ulimit 設定 (*nix 作業系統)

有幾個設定應該監控並盡可能設定為高值,最好是「unlimited」。在大多數 *nix 作業系統上,您可以透過在命令提示字元中輸入以下內容來查看目前的值。

ulimit -a

這四個設定尤其重要,應該設定得非常高,如果可能的話,設定為 unlimited。

  • 最大程序數 (ulimit -u):建議的最小值為 65,000。

  • 檔案控制代碼 (ulimit -n):建議的最小值為 65,000。所有複本使用的所有檔案都會一次開啟其檔案控制代碼,因此這個值可能會變得非常大。

  • 虛擬記憶體 (ulimit -v):設定為 unlimited。這用於 MMapping 索引。

  • 最大記憶體大小 (ulimit -m):也由 MMap 使用,設定為 unlimited。

  • 如果您的系統支援,sysctl vm.max_map_count 也應設定為 unlimited。

我們強烈建議您永久提高這些設定。永久提高這些設定的確切程序會因作業系統而異。某些系統需要編輯組態檔案並重新啟動伺服器。請諮詢您的系統管理員,以取得您特定環境的指導。

每次升級核心或作業系統時,請檢查這些限制。這些操作可能會將這些設定重設為預設值。

如果超出這些限制,Solr 回報的問題會因造成超出限制的特定操作而異。已經回報過的錯誤包括「開啟的檔案過多」、「連線錯誤」和「超出最大程序數」,以及 SolrCloud 復原失敗。

避免交換 (*nix 作業系統)

當執行像 Solr 這樣的 Java 應用程式時,讓作業系統將記憶體交換到磁碟會是一個非常糟糕的情況。我們通常比較偏好硬式當機,讓其他健康的 Solr 節點接管,而不是讓 Solr 節點交換,造成嚴重的效能問題、逾時和不穩定的系統。因此,我們的建議是完全停用主機上的交換或降低「swappiness」。這些指示適用於 Linux 環境。另請注意,在 Docker 容器中執行 Solr 時,這些變更必須套用至主機

停用交換

若要在 Linux 系統上暫時停用交換,您可以執行 swapoff 命令

sudo swapoff -a

如果您想要永久設定此設定,請先確保您的主機上有足夠的實體 RAM,然後查閱您的 Linux 系統文件,以取得停用交換的正確程序。

降低 Swappiness

另一種選擇是降低系統的「swappiness」。Linux 系統預設會相當積極地將記憶體交換到磁碟,因為預設的「swappiness」值很高。將此值降低到非常低的值,將會產生幾乎與使用 swapoff 相同的效果,但 Linux 仍然可以在緊急情況下進行交換。若要檢查目前的 swappiness 設定,請執行

cat /proc/sys/vm/swappiness

接下來,若要永久變更設定,請以 root 使用者身分開啟 /etc/sysctl.conf。然後,將此行變更或新增至檔案

vm.swappiness = 1

或者,您可以透過執行此命令來暫時變更設定

echo 1 > /proc/sys/vm/swappiness

安全性考量

管理員應仔細考慮其安全性設定,作為移至生產環境的重要步驟。Solr 開箱即用提供許多功能,以滿足使用者的安全性需求:可以使用一系列安全性外掛程式來設定驗證和授權,可以透過啟用 SSL/TLS 來加強隱私,並且 (在 SolrCloud 中) 可以使用 ACL 規則來保護 ZooKeeper 資料,以防止未經授權的讀取和寫入。

即使採取了這些措施或其他措施,強烈建議 Solr 始終受到防火牆的保護。Solr 並非設計為在開放網路上公開。

也強烈建議 Solr 只監聽嚴格要求的網路介面。為了防止管理員無意中更廣泛地公開 Solr,Solr 預設只監聽迴路介面 ("127.0.0.1")。大多數部署都需要將此值變更為限制較少的值,以便可以從其他盒子存取。這可以透過在您環境的「include 指令碼」(solr.in.shsolr.in.cmd) 中設定 SOLR_JETTY_HOST 值來完成

 ----
 SOLR_JETTY_HOST="0.0.0.0"
 ----

相同的設定也可以作為 -Dsolr.jetty.host 系統屬性使用。

如果使用 Solr 執行內嵌的 Zookeeper,情況也一樣。依預設,內嵌的 Zookeeper 只監聽迴路介面 ("127.0.0.1")。綁定主機是透過您環境的「include 指令碼」(solr.in.shsolr.in.cmd) 中的 SOLR_ZK_EMBEDDED_HOST 值來控制

 ----
 SOLR_ZK_EMBEDDED_HOST="0.0.0.0"
 ----

相同的設定也可以作為 -Dsolr.zk.embedded.host 系統屬性使用。

每個主機執行多個 Solr 節點

bin/solr 指令碼能夠在一台機器上執行多個執行個體,但對於典型安裝而言,這不是建議的設定。每個額外執行個體都需要額外的 CPU 和記憶體資源。單一執行個體可以輕鬆處理多個索引。

何時忽略建議

每個建議都有例外情況。對於上述建議,該例外情況大多適用於討論極端可擴展性。在一個主機上執行多個 Solr 節點的最佳原因,是減少對極大堆積的需求。

當 Java 堆積變得非常大時,即使使用啟動指令碼預設提供的 GC 調整,也可能導致極長的垃圾收集暫停。堆積被認為「非常大」的確切點,會因 Solr 的使用方式而異。這表示無法提供硬性數字作為閾值,但如果您的堆積達到 16 到 32 GB 的範圍,可能就該考慮分割節點。理想情況下,這表示需要更多機器,但預算限制可能會使這不可能。

一旦堆積達到 32GB,還有另一個問題。低於 32GB 時,Java 能夠使用壓縮指標,但在該點以上,則需要更大的指標,這會使用更多記憶體並減慢 JVM 的速度。

如果您的使用案例需要超過 31GB 的堆積,請考慮多個節點,因為它們通常會比具有 >32GB 堆積的單一節點執行得更好。

如果您的使用案例需要多個執行個體,至少您需要為您要執行的每個節點使用唯一的 Solr 首頁目錄;理想情況下,每個首頁都應該位於不同的實體磁碟上,這樣多個 Solr 節點就不必在存取磁碟上的檔案時互相競爭。擁有不同的 Solr 首頁目錄表示您需要為每個節點使用不同的 include 檔案。此外,如果使用 /etc/init.d/solr 指令碼將 Solr 作為服務控制,那麼您需要為每個節點使用個別的指令碼。最簡單的方法是使用服務安裝指令碼在同一主機上新增多個服務,例如:

sudo bash ./install_solr_service.sh solr-9.7.0.tgz -s solr2 -p 8984

上面顯示的命令會新增一個名為 solr2 的服務,該服務在 8984 埠上執行,並使用 /var/solr2 作為可寫入 (又稱「即時」) 檔案;第二個伺服器仍然由 solr 使用者擁有和執行,並將使用 /opt 中的 Solr 發行檔案。在安裝 solr2 服務後,請執行以下操作來驗證其是否正常運作

sudo service solr2 restart
sudo service solr2 status