Apache Solr

Apache Solr ist eine Open-Source-Suchplattform auf Basis von Apache Lucene. Solr ist in Java geschrieben und wird über eine HTTP-Schnittstelle (REST-artig) angesprochen. Daten liegen als Dokumente in einem Schema, Abfragen nutzen die Lucene Query Syntax. Zu den Funktionen gehören Volltextsuche, Facettierung, Indexierung und verteilte Suche über mehrere Knoten.

Solr 9 setzt Java 11 oder neuer voraus. Als Webserver bringt Solr ein eingebettetes Jetty mit, ein separater Application Server wie Tomcat ist nicht nötig. Im verteilten Betrieb (SolrCloud) verwaltet Apache ZooKeeper die Konfiguration und den Cluster-Status.

Begriffe
  • Collection: logischer Index im SolrCloud-Modus, verteilt über einen oder mehrere Shards.

  • Core: ein einzelner, eigenständiger Index auf einer Solr-Instanz, mit eigenem Schema, eigener Konfiguration und eigenem Datenverzeichnis. Im Standalone-Betrieb arbeitet man mit Cores.

  • Shard: eine Partition einer Collection. Mehrere Shards bilden zusammen den verteilten Index, optional repliziert.

  • SolrCloud: Solrs eigener Cluster-Modus, kein gehosteter Dienst und kein Produkt der Apache Software Foundation. Mehrere Solr-Knoten auf eigener Infrastruktur bilden zusammen einen Cluster, der Collections über Shards verteilt und repliziert. Apache ZooKeeper koordiniert Konfiguration und Cluster-Status. Gegenstück ist der Standalone-Modus (ein einzelner Knoten, der mit Cores arbeitet). Start mit bin/solr start -c.

  • ZooKeeper: koordiniert im SolrCloud-Modus Konfiguration und Cluster-Status.

Installation

Bemerkung

Die LFOps-Rolle apache_solr (siehe seealso) installiert Solr sauberer als das mitgelieferte Script und ist der empfohlene Weg. Sie verzichtet aus Idempotenz-Gründen auf install_solr_service.sh (nach Ansible portiert), installiert einen nativen systemd-Service statt eines init.d-Skripts, legt die Logs nach /var/log/solr und unterstützt mehrere parallel installierte Versionen.

Die manuelle Installation braucht zuerst eine Java-Runtime:

dnf --assumeyes install java-latest-openjdk

Das Release-Tarball von https://solr.apache.org/downloads.html herunterladen und mit dem mitgelieferten Script installieren:

sudo bash ./install_solr_service.sh solr-<version>.tgz \
    -i /opt -d /var/solr -u solr -s solr -p 8983

Das Script kennt nur diese Short-Options (-i Installationsverzeichnis, -d Datenverzeichnis, -u Benutzer, -s Service-Name, -p Port), Long-Parameter gibt es dafür nicht.

In Solr 9 richtet install_solr_service.sh einen init.d-Dienst unter /etc/init.d/solr ein, keinen nativen systemd-Service, und legt die Logs unter dem Datenverzeichnis ab (hier /var/solr/logs) statt unter /var/log.

Verwendung

Manueller Start:

cd /opt/solr
bin/solr --help

sudo -u solr bin/solr start --port 8983

Das Admin-Interface liegt unter http://<host>:8983/solr. Ein Aufruf von http://<host>:8983/ leitet dorthin um.

Cores und Collections

bin/solr create legt im Standalone-Betrieb einen Core an, im SolrCloud-Modus eine Collection:

bin/solr create -c my-core

Im SolrCloud-Modus lassen sich Shards und Replikation angeben:

bin/solr create -c my-collection --shards 2 --replication-factor 2

Eine Collection wird in Shards aufgeteilt. Jeder Shard hält einen Teil der Dokumente, zusammen ergeben sie den vollständigen Index. So lässt sich ein Index über mehrere Knoten verteilen, der für eine einzelne Maschine zu gross wäre. Jeder Shard kann zusätzlich repliziert werden (Replicas), das bringt Ausfallsicherheit und verteilt die Lese-Last. Bei einer Suchanfrage fragt Solr alle Shards parallel ab und führt die Teilergebnisse zusammen. Sharding gibt es nur im SolrCloud-Modus; im Standalone-Betrieb mit einzelnen Cores entfällt es.

Die Collections-API (/solr/admin/collections?action=CREATE&...) funktioniert nur im SolrCloud-Modus. Im Standalone-Betrieb antwortet sie mit Solr instance is not running in SolrCloud mode:

curl "http://<host>:8983/solr/admin/collections?action=CREATE&name=my-collection&numShards=1"

solrconfig.xml

Die solrconfig.xml liegt pro Core bzw. Collection im conf/-Unterordner, also beispielsweise in /var/solr/data/my-core/conf/solrconfig.xml.

Plugins, Packages und Module

Bemerkung

Der Package Manager bin/solr package ... setzt ZooKeeper voraus und läuft daher nur im SolrCloud-Modus.

Der Data Import Handler ist seit Solr 9 nicht mehr Teil des Cores und wird als Community-Fork gepflegt. Das passende Release von https://github.com/SearchScale/dataimporthandler/releases herunterladen und in das lib/-Verzeichnis legen:

cd /opt/solr/lib
wget https://github.com/SearchScale/dataimporthandler/releases/download/v<version>/data-import-handler-<version>.jar

chown -R solr:solr /opt/solr
systemctl restart solr

MariaDB Connector/J für den Zugriff auf MariaDB/MySQL, von https://mariadb.com/downloads/connectors/ herunterladen:

cd /opt/solr/lib
wget https://dlm.mariadb.com/<path>/mariadb-java-client-<version>.jar

chown -R solr:solr /opt/solr
systemctl restart solr

Authentication

Apache Solr lässt sich mit Benutzername und Passwort absichern, indem eine security.json im Solr-Home (SOLR_HOME, hier /var/solr/data) abgelegt wird:

/var/solr/data/security.json
{
    "authentication":
    {
        "blockUnknown": true,
        "class": "solr.BasicAuthPlugin",
        "credentials":
        {
            "solr-admin": "IV0EHq1OnNrj6gv...XhgrF8c="
        },
        "realm": "My Solr users",
        "forwardCredentials": false
    },
    "authorization":
    {
        "class": "solr.RuleBasedAuthorizationPlugin",
        "permissions":
        [
            {
                "name": "all",
                "role": "admin"
            }
        ],
        "user-role":
        {
            "solr-admin": "admin"
        }
    }
}

Der Benutzername in user-role muss mit dem Schlüssel unter credentials übereinstimmen, sonst greift die Rolle nicht.

Mögliche Permission-Names für die Definition eigener Rollen:

  • all

  • collection-admin-edit

  • collection-admin-read

  • config-edit

  • config-read

  • core-admin-edit

  • core-admin-read

  • filestore-read

  • filestore-write

  • health

  • metrics-read

  • package-edit

  • package-read

  • read

  • schema-edit

  • schema-read

  • security-edit

  • security-read

  • update

  • zk-read

Solr hasht das Passwort als base64(sha256(sha256(salt + passwort))), gefolgt vom base64-kodierten Salt. Den Credential-Wert für den Benutzer „solr-admin“ erzeugt man so:

PW='linuxfabrik'
SALT="$(openssl rand -hex 24)"
HASH="$(printf '%s' "$SALT$PW" \
    | openssl dgst -sha256 -binary \
    | openssl dgst -sha256 -binary | base64 -w 0)"
printf '%s %s\n' "$HASH" "$(printf '%s' "$SALT" | base64 -w 0)"

Bemerkung

Die Permission all gehört immer ans Ende der Liste, damit spezifischere Permissions zuerst greifen.