ZooKeeper 集群配置

尽管 Solr 捆绑了 Apache ZooKeeper,但强烈建议您在生产环境中使用外部 ZooKeeper 设置。

虽然使用 Solr 的嵌入式 ZooKeeper 实例对于入门来说是可以的,但不应该在生产环境中使用它,因为它不提供任何故障转移:如果托管 ZooKeeper 的 Solr 实例关闭,ZooKeeper 也会关闭。任何依赖它的分片或 Solr 实例都将无法与它或彼此通信。

解决此问题的方案是设置一个外部 ZooKeeper *集群*,这是一组运行 ZooKeeper 的服务器,它们彼此通信以协调集群的活动。

ZooKeeper 节点数量?

要回答的第一个问题是您将在集群中运行的 ZooKeeper 节点的数量。

在规划要配置多少个 ZooKeeper 节点时,请记住 ZooKeeper 集群的主要原则是保持大多数服务器来服务请求。这个多数称为*仲裁*。

“为了使 ZooKeeper 服务处于活动状态,必须有大多数不失败的机器可以相互通信。为了创建一个可以容忍 F 台机器故障的部署,您应该考虑部署 2xF+1 台机器

— ZooKeeper 管理员指南
https://zookeeper.net.cn/doc/r3.9.2/zookeeperAdmin.html

为了正确维护仲裁,强烈建议您的集群中拥有奇数个 ZooKeeper 服务器,以便保持多数。

为了解释原因,请考虑以下场景:如果您有两个 ZooKeeper 节点,其中一个节点宕机,这意味着只有 50% 的可用服务器可用。由于这不是多数,ZooKeeper 将不再服务请求。

然而,如果您有三个 ZooKeeper 节点,其中一个发生故障,您仍有 66% 的服务器可用,并且 ZooKeeper 将在您修复发生故障的节点时继续正常运行。如果您有 5 个节点,必要时可以在两个节点发生故障的情况下继续运行。

通常不建议使用超过 5 个节点。虽然看起来更多的节点可以提供更高的容错能力和可用性,但实际上由于节点间协调的次数会增加,效率会降低。除非您有一个真正庞大的 Solr 集群(规模达到 1000 个节点),一般情况下,请尽量保持 3 个节点,如果您的集群较大,可以考虑 5 个节点。

有关 ZooKeeper 集群的更多信息,请参阅 ZooKeeper 文档,网址为 https://zookeeper.net.cn/doc/r3.9.2/zookeeperAdmin.html#sc_zkMulitServerSetup

下载 Apache ZooKeeper

设置 Apache ZooKeeper 的第一步当然是下载该软件。您可以从 https://zookeeper.net.cn/releases.html 下载。

Solr 当前使用 Apache ZooKeeper v3.9.2。

当使用外部 ZooKeeper 集群时,您需要保持本地安装与 Solr 分发的最新版本同步。由于在这种情况下它是一个独立的应用程序,它不会作为标准 Solr 升级的一部分进行升级。

ZooKeeper 安装

安装包括将文件提取到您希望 ZooKeeper 存储其内部数据的特定目标目录中。实际目录本身并不重要,只要您知道它在哪里即可。

解压 ZooKeeper 软件包的命令是

tar xvf zookeeper-3.9.2.tar.gz

此位置是此服务器上 ZooKeeper 的 <ZOOKEEPER_HOME>

必须在运行 ZooKeeper 的每台服务器上重复安装和解压 ZooKeeper 的步骤。

ZooKeeper 集群的配置

安装完成后,我们将首先了解 ZooKeeper 的基本配置,然后了解配置每个节点作为集群一部分的特定参数。

初始配置

要配置您的 ZooKeeper 实例,请创建一个名为 <ZOOKEEPER_HOME>/conf/zoo.cfg 的文件。ZooKeeper 安装包中包含一个示例配置文件,即 conf/zoo_sample.cfg。如果您愿意,您可以编辑并重命名该文件,而不是创建新文件。

该文件应具有以下初始信息

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok

参数如下:

tickTime

必需

默认值:无

ZooKeeper 的部分功能是确定哪些服务器在任何给定时间处于启动并运行状态,最小会话超时时间定义为两个“tick”。 tickTime 参数以毫秒为单位指定每个 tick 的时长。

dataDir

必需

默认值:无

这是 ZooKeeper 将存储有关集群数据的目录。在首次启动 ZooKeeper 之前,此目录必须为空。

clientPort

必需

默认值:无

这是 Solr 将访问 ZooKeeper 的端口。

4lw.commands.whitelist

可选

默认值:无

这允许 Solr 管理 UI 查询 ZooKeeper。您可以选择使用 * 启用所有“4 字命令”,列出的三个 (mntr, conf, ruok) 将启用管理 UI。

这些是每个 ZooKeeper 节点都需要使用的基本参数,因此必须将此文件复制到每个节点或在每个节点上创建该文件。

接下来,我们将自定义此配置以在集群中工作。

集群配置

要完成集群的配置,我们需要设置其他参数,以便每个节点都知道它在集群中的身份以及每个其他节点的位置。

以下每个示例都假设您将 ZooKeeper 安装在具有不同主机名的不同服务器上。

完成后,您的 zoo.cfg 文件可能如下所示

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok

initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

autopurge.snapRetainCount=3
autopurge.purgeInterval=1

我们在已经有的三个参数中添加了这些参数:

initLimit

必需

默认值:无

允许 follower 连接并同步到 leader 的时间量,以 tick 为单位。在本例中,您有 5 个 tick,每个 tick 为 2000 毫秒,因此服务器将等待 10 秒以连接并与 leader 同步。

syncLimit

必需

默认值:无

允许 follower 与 ZooKeeper 同步的时间量,以 tick 为单位。如果 follower 落后于 leader 太远,它们将被删除。

server.X

必需

默认值:无

这些是集群中所有服务器的服务器 ID (X 部分)、主机名(或 IP 地址)和端口。ID 用于区分集群中的每个节点,并允许每个节点知道每个其他节点的位置。端口可以是您选择的任何端口;ZooKeeper 的默认端口为 2888:3888

由于我们已将服务器 ID 分配给特定的主机/端口,因此我们还必须定义此节点是列表中哪个服务器。我们使用存储在数据目录(由 dataDir 参数定义)中的 myid 文件来执行此操作。myid 文件的内容仅是服务器 ID。

在上面的配置示例中,您将创建文件 /var/lib/zookeeper/1/myid,其内容为“1”(不带引号),如本示例所示

1
autopurge.snapRetainCount

可选

默认值:3

在清除旧快照和事务日志时,要保留的快照和对应的事务日志的数量。

ZooKeeper 会自动保留一个事务日志并在进行更改时写入该日志。会定期拍摄当前状态的快照,并且此快照会取代比快照旧的事务日志。但是,ZooKeeper 永远不会清理旧快照或旧事务日志;随着时间的推移,它们会悄悄地填满每台服务器上的可用磁盘空间。

为避免这种情况,请设置 autopurge.snapRetainCountautopurge.purgeInterval 参数以启用定期自动清理(清除)。当发生清理时,autopurge.snapRetainCount 参数将保留定义的快照和事务日志数量。此参数可以配置为高于 3,但不能设置为低于 3。

autopurge.purgeInterval

可选

默认值:0

清除任务之间的时间间隔(以小时为单位)。此参数的默认值为 0,因此必须设置为 1 或更高才能启用快照和事务日志的自动清理。如果需要,可以接受设置为高达 24(每天一次)。

我们将在每个节点上重复此配置。

在第二个节点上,更新 <ZOOKEEPER_HOME>/conf/zoo.cfg 文件,使其与节点 1 上的内容匹配(特别是服务器主机和端口)

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok

initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

autopurge.snapRetainCount=3
autopurge.purgeInterval=1

在第二个节点上,创建一个内容为“2”的 myid 文件,并将其放在 /var/lib/zookeeper 目录中。

2

在第三个节点上,更新 <ZOOKEEPER_HOME>/conf/zoo.cfg 文件,使其与节点 1 和 2 上的内容匹配(特别是服务器主机和端口)

tickTime=2000
dataDir=/var/lib/zookeeper
clientPort=2181
4lw.commands.whitelist=mntr,conf,ruok

initLimit=5
syncLimit=2
server.1=zoo1:2888:3888
server.2=zoo2:2888:3888
server.3=zoo3:2888:3888

autopurge.snapRetainCount=3
autopurge.purgeInterval=1

并在 /var/lib/zookeeper 目录中创建 myid 文件

3

如果要创建 5 节点集群(一种罕见情况),请对服务器 4 和 5 重复此操作。

ZooKeeper 环境配置

为了方便以后在集群出现问题时进行故障排除,建议启用日志记录并使用适当的 JVM 垃圾回收 (GC) 设置来运行 ZooKeeper。

  1. 创建一个名为 zookeeper-env.sh 的文件,并将其放在 <ZOOKEEPER_HOME>/conf 目录中(与您放置 zoo.cfg 的位置相同)。此文件需要在集群的每台服务器上存在。

  2. 将以下设置添加到文件中

    ZOO_LOG_DIR="/path/for/log/files"
    ZOO_LOG4J_PROP="INFO,ROLLINGFILE"
    
    SERVER_JVMFLAGS="-Xms2048m -Xmx2048m -Xlog:gc*:file=$ZOO_LOG_DIR/zookeeper_gc.log:time,uptime:filecount=9,filesize=20M"

    属性 ZOO_LOG_DIR 定义服务器上 ZooKeeper 将打印其日志的位置。ZOO_LOG4J_PROP 设置日志记录级别和日志附加器。

    使用 SERVER_JVMFLAGS,我们定义了几个用于垃圾回收和记录与 GC 相关事件的参数。其中一个系统参数是 -Xloggc:$ZOO_LOG_DIR/zookeeper_gc.log,它将把垃圾回收日志放在我们为 ZooKeeper 日志定义的同一目录中,放在名为 zookeeper_gc.log 的文件中。

  3. 查看 <ZOOKEEPER_HOME>/conf/log4j.properties 中的默认设置,特别是 log4j.appender.ROLLINGFILE.MaxFileSize 参数。此参数设置日志文件将滚动的最大大小,默认值为 10MB。

  4. zookeeper-env.sh 和对 log4j.properties 的任何更改复制到集群中的每台服务器。

上述说明仅适用于 Linux 服务器。默认的 zkServer.sh 脚本包含对 zookeeper-env.sh 文件的支持,但 Windows 版本的脚本 zkServer.cmd 不包含。要在 Windows 服务器上进行相同的配置,需要直接在 zkServer.cmd 中进行更改。

此时,您已准备好启动您的 ZooKeeper 集群。

有关 ZooKeeper 的更多信息

ZooKeeper 通过其他配置提供了强大的功能,但深入研究它们超出了 Solr 文档的范围。有关更多信息,请参阅 ZooKeeper 文档

启动和停止 ZooKeeper

启动 ZooKeeper

要启动集群,请使用 <ZOOKEEPER_HOME>/bin/zkServer.shzkServer.cmd 脚本,如下所示

Linux 操作系统
zkServer.sh start
Windows 操作系统
zkServer.cmd start

需要在运行 ZooKeeper 的每台服务器上运行此命令。

您应该在您定义存储它们的目录中看到 ZooKeeper 日志。但是,在启动后立即,您可能看不到 zookeeper_gc.log,因为它可能要到垃圾回收首次发生后才会出现。

关闭 ZooKeeper

要关闭 ZooKeeper,请在每台服务器上使用相同的 zkServer.shzkServer.cmd 脚本,并使用“stop”命令

Linux 操作系统
zkServer.sh stop
Windows 操作系统
zkServer.cmd stop

Solr 配置

启动 Solr 时,您必须提供 ZooKeeper 的地址,否则 Solr 将不知道如何使用它。这可以通过两种方式完成:在 Solr 集群的每个节点的每次启动时定义连接字符串(ZooKeeper 运行所在服务器的列表),或者将 Solr 的包含文件编辑为永久系统参数。以下将介绍这两种方法。

在 Solr 中引用 ZooKeeper 的位置时,最好使用集群中所有服务器的地址。如果其中一个服务器发生故障,Solr 将能够自动将其请求发送到列表中的另一台服务器。

ZooKeeper 3.5 及更高版本支持动态重新配置服务器地址和角色。但请注意,Solr 只能与静态 ZooKeeper 连接字符串中列出的服务器通信。

使用 chroot

如果您的集群与其他系统(Solr 以外)共享或将要共享,您应该考虑定义特定于应用程序的 znodes,或仅包含 Solr 文件的分层命名空间。

为每个应用程序创建 znode 后,每当您告诉 Solr 在哪里访问 ZooKeeper 时,请将它的名称(也称为 chroot)添加到连接字符串的末尾。

可以使用 bin/solr 命令创建 chroot

bin/solr zk mkroot /solr -z zk1:2181,zk2:2181,zk3:2181

有关此命令的更多示例,请参阅创建 znode部分。

一旦创建了 znode,它的行为就类似于文件系统上的目录:Solr 存储在 ZooKeeper 中的数据嵌套在主数据目录之下,不会与使用同一 ZooKeeper 集群的其他系统或进程的数据混合。

或者,Solr 可以在第一个 Solr 实例启动时自动创建 znode,请阅读下面的示例。

使用 bin/solr 的 -z 参数

使用 bin/solr 脚本时,只需使用 -z 参数即可将 Solr 指向您创建的 ZooKeeper 集群。

例如,要将 Solr 实例指向您在三台服务器上端口 2181 上启动的 ZooKeeper,并使用 chroot /solr(请参阅上面的 使用 chroot),您需要执行以下操作

bin/solr start -e cloud -z zk1:2181,zk2:2181,zk3:2181/solr

如果 znode 不存在,您可以将 ZK_CREATE_CHROOT 环境变量设置为 true,以便在启动时自动创建它。

ZK_CREATE_CHROOT=true bin/solr start -e cloud -z zk1:2181,zk2:2181,zk3:2181/solr

更新 Solr 包含文件

如果您更新 Solr 包含文件(solr.in.shsolr.in.cmd),这将覆盖 bin/solr 使用的默认值,您将不必在 bin/solr 命令中使用 -z 参数。

  • Linux

  • Windows

solr.in.sh

要查找的部分将被注释掉

# Set the ZooKeeper connection string if using an external ZooKeeper ensemble
# e.g. host1:2181,host2:2181/chroot
# Leave empty if not using SolrCloud
#ZK_HOST=""

删除行首的注释标记并输入 ZooKeeper 连接字符串

# Set the ZooKeeper connection string if using an external ZooKeeper ensemble
# e.g. host1:2181,host2:2181/chroot
# Leave empty if not using SolrCloud
ZK_HOST="zk1:2181,zk2:2181,zk3:2181/solr"
solr.in.cmd

要查找的部分将被注释掉

REM Set the ZooKeeper connection string if using an external ZooKeeper ensemble
REM e.g. host1:2181,host2:2181/chroot
REM Leave empty if not using SolrCloud
REM set ZK_HOST=

删除行首的注释标记并输入 ZooKeeper 连接字符串

REM Set the ZooKeeper connection string if using an external ZooKeeper ensemble
REM e.g. host1:2181,host2:2181/chroot
REM Leave empty if not using SolrCloud
set ZK_HOST=zk1:2181,zk2:2181,zk3:2181/solr

现在您在启动 Solr 时不必输入连接字符串。

增加文件大小限制

ZooKeeper 设计用于保存小文件,大小约为几 KB。默认情况下,ZooKeeper 的文件大小限制为 1MB。尝试写入或读取大于此值的文件将导致错误。

某些 Solr 功能,例如,文本分析同义词、LTR 和 OpenNLP 命名实体识别,需要可能大于默认限制的配置资源。可以通过 Java 系统属性 jute.maxbuffer 配置 ZooKeeper,以增加此限制。请注意,此配置对于 ZooKeeper 服务器和所有连接到服务器的客户端都是必需的,并且在指定它的任何地方都必须相同。

在 ZooKeeper 节点上配置 jute.maxbuffer

必须在每个外部 ZooKeeper 节点上配置 jute.maxbuffer。可以通过以下任何一种方式实现;请注意,只有第一种方式适用于 Windows

  1. <ZOOKEEPER_HOME>/conf/zoo.cfg 中,例如,要将文件大小限制增加到小于 10MB 的一个字节,请添加此行

    jute.maxbuffer=0x9fffff
  2. <ZOOKEEPER_HOME>/conf/zookeeper-env.sh 中,例如,要将文件大小限制增加到 50MiB,请添加此行

    JVMFLAGS="$JVMFLAGS -Djute.maxbuffer=50000000"
  3. <ZOOKEEPER_HOME>/bin/zkServer.sh 中,在脚本顶部附近添加 JVMFLAGS 环境变量赋值,例如,要将文件大小限制增加到 5MiB

    JVMFLAGS="$JVMFLAGS -Djute.maxbuffer=5000000"

为 ZooKeeper 客户端配置 jute.maxbuffer

bin/solr 脚本调用充当 ZooKeeper 客户端的 Java 程序。当您使用 Solr 捆绑的 ZooKeeper 服务器而不是设置外部 ZooKeeper 集群时,下面描述的配置也将配置 ZooKeeper 服务器。

将设置添加到 Solr 包含文件(bin/solr.in.shsolr.in.cmd)中的 SOLR_OPTS 环境变量

  • Linux

  • Windows

solr.in.sh

要查找的部分将从这里开始

# Anything you add to the SOLR_OPTS variable will be included in the java
# start command line as-is, in ADDITION to other options. If you specify the
# -a option on start script, those options will be appended as well. Examples:

添加以下行以将文件大小限制增加到 2MB

SOLR_OPTS="$SOLR_OPTS -Djute.maxbuffer=0x200000"
solr.in.cmd

要查找的部分将从这里开始

REM Anything you add to the SOLR_OPTS variable will be included in the java
REM start command line as-is, in ADDITION to other options. If you specify the
REM -a option on start script, those options will be appended as well. Examples:

添加以下行以将文件大小限制增加到 2MB

set SOLR_OPTS=%SOLR_OPTS% -Djute.maxbuffer=0x200000

保护 ZooKeeper 连接

您可能还希望保护 ZooKeeper 和 Solr 之间的通信。

要设置 znode 的 ACL 保护,请参阅 ZooKeeper 访问控制 部分。