Docker 中的 Solr

Docker 镜像入门

以下说明适用于 solr:8.0.0 及更高版本。

有关可用标签和架构的完整列表,请参阅 Docker Hub 页面

可用镜像

每个版本都提供两个 Docker 镜像:完整版和精简版。它们对应于为每个 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 的管理界面(根据您的 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

以下是一个示例 Compose 文件,该文件启动一个带有 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-entrypoint.sh 脚本在 Docker 日志中执行的 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,并在其下运行 Solr。如果您真的不想运行 tini,而只是作为 PID 1 运行 Solr,则可以设置 TINI=no 环境变量。

内存不足处理

有关更多信息,请参阅 内存不足处理 部分。Docker 镜像不再具有用于 OOM 的自定义逻辑。

历史

Docker-Solr 项目于 2015 年由 Martijn Kosterdocker-solr 存储库中启动。2019 年,维护和版权被转移到 Apache Lucene/Solr 项目,2020 年,该项目被迁移到 Solr 项目中。非常感谢 Martijn 多年来做出的所有贡献!