将 Solr 投入生产
本部分提供了有关如何设置 Solr 以在 *nix 平台(如 Ubuntu)上运行的指南。具体来说,我们将逐步介绍在 Linux 主机上运行单个 Solr 实例的设置过程,然后提供有关如何在同一主机上支持多个 Solr 节点运行的提示。
服务安装脚本
Solr 包含一个服务安装脚本 (bin/install_solr_service.sh
),可帮助您在 Linux 上将 Solr 安装为服务。目前,该脚本仅支持 CentOS、Debian、Red Hat、SUSE 和 Ubuntu Linux 发行版。在运行脚本之前,您需要确定有关设置的一些参数。具体来说,您需要决定将 Solr 安装在何处,以及哪个系统用户应为 Solr 文件和进程的所有者。
规划目录结构
我们建议将实时 Solr 文件(如日志和索引文件)与 Solr 发行包中包含的文件分开,因为这使得升级 Solr 变得更加容易,并且被认为是系统管理员应遵循的良好做法。
创建 Solr 用户
出于安全原因,不建议以 root
身份运行 Solr,并且 bin/solr start
命令将拒绝这样做。因此,您应确定将拥有所有 Solr 文件和正在运行的 Solr 进程的系统用户的用户名。默认情况下,安装脚本将创建 solr 用户,但您可以使用 -u 选项覆盖此设置。如果您的组织对创建新用户帐户有特定要求,那么您应在运行脚本之前创建用户。安装脚本将使 Solr 用户成为 /opt/solr
和 /var/solr
目录的所有者。
现在,您已准备好运行安装脚本。
运行 Solr 安装脚本
要运行脚本,您需要下载最新的 Solr 分发存档,然后执行以下操作
tar xzf solr-9.5.0.tgz solr-9.5.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.5.0.tgz
默认情况下,脚本将分发存档解压到 /opt
,将 Solr 配置为将文件写入 /var/solr
,并将 Solr 作为 solr
用户运行。因此,以下命令产生的结果与之前的命令相同
sudo bash ./install_solr_service.sh solr-9.5.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 主目录的内容。如果你没有在 ZooKeeper 中存储 solr.xml
,则主目录必须包含一个 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_DIR
和 SOLR_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
。花点时间通过检查 /etc/default/solr.in.sh
中的以下设置来验证 Solr 包含文件已配置为将日志发送到正确的位置
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_DIR
和 SOLR_ENV
变量应该是自解释的。RUNAS
变量设置 Solr 进程的所有者,例如 solr
;如果您不设置此值,脚本将以 root 身份运行 Solr,这不建议用于生产。您可以使用 /etc/init.d/solr
脚本通过以下操作以 root 身份启动 Solr
service solr start
/etc/init.d/solr
脚本还支持 stop、restart 和 status 命令。请记住,Solr 附带的 init 脚本非常基础,旨在向您展示如何将 Solr 设置为服务。但是,使用更高级的工具(如 supervisord 或 upstart)来控制 Solr 作为 Linux 上的服务也很常见。虽然展示如何将 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
会自动检测 maxThreadCount
和 maxMergeCount
的默认值。maxThreadCount
设置为 4 或提供给 JVM 的处理器数量的一半(以较大者为准),而 maxMergeCount
设置为 maxThreadCount+5
。
如果您有旋转磁盘,最好在 SolrConfig.xml 的 IndexConfig 部分 中明确设置 maxThreadCount
和 maxMergeCount
的值,以便使用适合您硬件的值。
内存和 GC 设置
默认情况下,bin/solr
脚本将最大 Java 堆大小设置为 512M (-Xmx512m),这对于开始使用 Solr 来说很好。对于生产环境,您需要根据搜索应用程序的内存要求增加最大堆大小;对于生产服务器,8 到 16 千兆字节的值并不罕见。当您需要更改 Solr 服务器的内存设置时,请在 include 文件中使用 SOLR_HEAP
变量,例如
SOLR_HEAP="8g"
除非您知道需要,否则不要分配非常大的 Java 堆。有关详细信息,请参见 选择内存堆设置。 |
此外,Solr 控制脚本 附带了一组预配置的 Garbage First 垃圾回收设置,这些设置已被证明可以很好地与 Solr 配合使用,适用于许多不同的工作负载。但是,这些设置可能不适用于您对 Solr 的特定使用。因此,您可能需要更改 GC 设置,这也应该在 /etc/default/solr.in.sh
include 文件中的 GC_TUNE
变量中完成。
有关垃圾回收设置的更多信息,请参阅以下文章:. https://cwiki.apache.org/confluence/display/solr/ShawnHeisey . https://www.oracle.com/technetwork/articles/java/g1gc-1984535.html
您还可以参考 JVM 设置 来调整您的内存和垃圾回收设置。
使用 SolrCloud 投入生产
要在 SolrCloud 模式下运行 Solr,您需要在 include 文件中设置 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 创建的所有 znode 都存储在 /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 主机名
在 include 文件中使用 SOLR_HOST
变量设置 Solr 服务器的主机名。
SOLR_HOST=solr1.example.com
建议设置 Solr 服务器的主机名,尤其是在以 SolrCloud 模式运行时,因为这决定了节点在向 ZooKeeper 注册时的地址。
管理 UI 中的环境横幅
为了防止意外地对错误的集群进行更改,您可以在 Admin UI 中配置一个可视指示,以指示您当前是否使用生产环境。为此,使用 -Dsolr.environment=prod
设置编辑您的 solr.in.sh
或 solr.in.cmd
文件,或设置名为 environment
的集群属性。允许的值为 dev
、test
、stage
或 prod
。每个值都有预定义的默认标签和颜色。若要指定标签和/或颜色,请使用逗号分隔的格式,如下所示。必须在颜色之前定义标签。可以使用 +
字符代替空格,以避免使用引号。颜色可以是有效的 CSS 颜色或数字,例如,#ff0000
表示亮红色。有效环境配置示例
-
prod
(默认标签为“生产”,默认颜色为红色调) -
test,label=Functional+test
(默认颜色仍为黄色,但覆盖标签) -
dev,label=MyDev,color=blue
(按名称覆盖标签和颜色) -
stage,color=#ff8888
(使用代码自定义颜色)
覆盖 solrconfig.xml 中的设置
Solr 允许使用在启动时使用 -Dproperty=value
语法传递的 Java 系统属性覆盖配置属性。例如,在 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。对于在生产中运行,我们建议在包含文件中定义的 SOLR_OPTS
变量中设置这些属性。以我们的软提交示例为例,在 /etc/default/solr.in.sh
中,您将执行
SOLR_OPTS="$SOLR_OPTS -Dsolr.autoSoftCommit.maxTime=10000"
Ulimit 设置(*nix 操作系统)
有几个设置应该尽可能地进行监控并设置为最高值,最好是“无限制”。在大多数 *nix 操作系统上,您可以通过在命令提示符下键入以下内容来查看当前值。
ulimit -a
尤其重要的是将这四个设置设置为非常高,如果可能的话设置为无限制。
-
最大进程数(
ulimit -u
):65,000 是推荐的最小值。 -
文件句柄(
ulimit -n
):65,000 是推荐的最小值。所有副本使用的所有文件都同时打开了其文件句柄,因此它可能会增长得非常大。 -
虚拟内存(
ulimit -v
):设置为无限制。这是通过 MMapping 索引使用的。 -
最大内存大小(
ulimit -m
):也由 MMap 使用,设置为无限制。 -
如果您的系统支持,则
sysctl vm.max_map_count
也应设置为无限制。
我们强烈建议永久提高这些设置。永久提高这些设置的确切过程因操作系统而异。某些系统需要编辑配置文件并重新启动服务器。请咨询系统管理员以获取特定环境中的指导。
每次升级内核或操作系统时,请检查这些限制。这些操作可以将这些限制重置为其默认值。 |
如果超过这些限制,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.sh
或 solr.in.cmd
)中设置 SOLR_JETTY_HOST
值来完成
----
SOLR_JETTY_HOST="0.0.0.0"
----
相同的设置也可作为 -Dsolr.jetty.host
系统属性使用。
如果嵌入式 Zookeeper 与 Solr 一起运行,则同样适用于嵌入式 Zookeeper。默认情况下,嵌入式 Zookeeper 仅侦听环回接口(“127.0.0.1”)。绑定主机通过环境的“include 脚本”(solr.in.sh
或 solr.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.5.0.tgz -s solr2 -p 8984
上面显示的命令将添加一个名为 solr2
的服务,该服务在端口 8984 上运行,并使用 /var/solr2
作为可写(又称“实时”)文件;第二个服务器仍将归 solr
用户所有并由其运行,并将使用 /opt
中的 Solr 分发文件。在安装 solr2 服务后,通过执行以下操作验证其是否正常工作
sudo service solr2 restart
sudo service solr2 status