CentOS 7 - Sphinx

Installation - Sphinx 2.1 (default in CentOS repo)

user example , index_name and local_ip need to be customized

# yum -y install sphinx
# vim /etc/sphinx/sphinx.conf
copy/update config file amd:
- make sure pid file config option is set to /run/sphinx/searchd.pid
- make sure listen directive has correct local_ip set:
listen = 127.0.0.1:9312
listen = local_ip:9312

# indexer -c /etc/sphinx/sphinx.conf --rotate index_name
# chown example:root -R /var/lib/sphinx/
# chown example:root /run/sphinx/
# chown example.root -R /var/log/sphinx

# vim /usr/lib/systemd/system/searchd.service

[Unit]
Description=Sphinx - SQL Full Text Search Engine
After=local-fs.target network.target mysqld.service

[Service]
User=example
Type=forking
PIDFile=/run/sphinx/searchd.pid
ExecStart=/usr/bin/searchd --config /etc/sphinx/sphinx.conf
PermissionsStartOnly=true
ExecStartPre=/bin/chown example:root /run/sphinx

[Install]
WantedBy=multi-user.target

# systemctl enable searchd
# systemctl start searchd
# systemctl status searchd
# netstat -lpn | grep searchd

Sphinx 2.2+

Sphinx will be running under local user example (and not under sphinx user)
user example , index_name and local_ip need to be customized

# cd

# wget http://sphinxsearch.com/files/sphinx-2.2.11-1.rhel7.x86_64.rpm
# wget http://sphinxsearch.com/files/sphinx-2.3.2-1.rhel7.x86_64.rpm

# yum -y install ./sphinx-2.2.11-1.rhel7.x86_64.rpm
# vim /etc/sphinx/sphinx.conf
copy/update config file amd:
- make sure pid file config option is set to /run/sphinx/searchd.pid
- make sure listen directive has correct local_ip set:
listen = 127.0.0.1:9312
listen = local_ip:9312

# chown example.example -R /var/run/sphinx
# chown example.example -R /var/lib/sphinx
# chown example.example -R /var/log/sphinx

# su example
$ indexer -c /etc/sphinx/sphinx.conf --rotate index_name
$ CTRL+D

# cp /usr/lib/systemd/system/searchd.service /etc/systemd/system/searchd.service
# vim /etc/systemd/system/searchd.service
...
User=example
Group=example
...
ExecStartPre=/bin/chown example.example -R /var/run/sphinx
ExecStartPre=/bin/chown example.example -R /var/lib/sphinx
ExecStartPre=/bin/chown example.example -R /var/log/sphinx
...

# systemctl start searchd
# systemctl status searchd
# netstat -lpn | grep searchd

Install 2.2 from source (e.g. on EL9):

This installs into /usr/local folders

# dnf groupinstall "Development Tools"
# yum install mariadb-connector-c-devel
# cd ~
# wget https://sphinxsearch.com/files/sphinx-2.2.11-release.tar.gz
# tar xvzf ./sphinx-2.2.11-release.tar.gz
# ./configure
# make
# make install

# vim /etc/systemd/system/searchd.service

[Unit]
Description=Sphinx
After=local-fs.target network.target mysqld.service

[Service]
User=example
Type=forking
PIDFile=/run/sphinx/searchd.pid
ExecStart=/usr/local/bin/searchd --config /etc/sphinx/sphinx.conf
PermissionsStartOnly=true
ExecStartPre=/bin/chmod 775 /run/sphinx
ExecStartPre=/bin/chown example:example /run/sphinx

[Install]
WantedBy=multi-user.target

Adding firewall rules

# firewall-cmd --zone=internal --add-port=9306/tcp --permanent
# firewall-cmd --zone=internal --add-port=9312/tcp --permanent
# firewall-cmd --reload
# firewall-cmd --zone=internal --list-all

Adding auto-rotate shell script

# su example
~ mkdir -p ~/cron/prod
~ cd ~/cron/prod
~ vim ./cache_update.sh

#!/bin/bash

DBHOST="127.0.0.1"
DBNAME="example"
DBUSER="example"
DBPASS="dbpassword"
CONFIG="/etc/sphinx/sphinx.conf"
INDEXER="/usr/bin/indexer"

MY_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null && pwd )"
LOGFILE="${MY_DIR}/cache_update.log"

SAVEIFS=$IFS
IFS=$(echo -en "\n\b")
for row in `mysql -h $DBHOST -u $DBUSER --password=$DBPASS $DBNAME -N -B -e "SELECT index_name, MAX(create_stamp) FROM cache_update GROUP BY index_name;"`; do
    index=`echo $row | tr -s ' ' '\t' | cut -f 1`
    stamp=`echo $row | tr -s ' ' '\t' | cut -f 2`
    echo "Going to rotate '${index}', stamp='${stamp}' ..."
    echo -n "["`date`"] Rotating '${index}' (max stamp = ${stamp}) ... " >> $LOGFILE
    $INDEXER --config $CONFIG $index --rotate
    RET=$?

    if [[ $RET -eq 0 ]]; then
        mysql -h $DBHOST -u $DBUSER --password=$DBPASS $DBNAME -N -B -e "DELETE FROM cache_update WHERE index_name = '$index' AND create_stamp <= $stamp;"
        RET=$?
        if [[ $RET -eq 0 ]]; then
            echo "SUCCESS" >> $LOGFILE
        else
            echo "SUCCESS rotate, but ERROR deleting cache_update entry" >> $LOGFILE
        fi
    else
        echo "ERROR" >> $LOGFILE
    fi
done
IFS=$SAVEIFS

exit 0

~ chmod +x ./cache_update.sh

You can test run the script (providing some entry in cache_update table).

Making it run every 2 seconds as systemd unit, first create runner shell script:

~ vim ./cache_update_runner.sh

#!/bin/bash
#
# Run with this command:
# nohup /home/example/cron/prod/cache_update_runner.sh 0<&- &>/dev/null &
# 
# And put into cron to start automatically after reboot:
# @reboot nohup /home/example/cron/prod/cache_update_runner.sh 0<&- &>/dev/null &


#store the pid of this script into a temp file
echo $$ > /tmp/example_cache_update_runner_prod.pid

#poll interval in seconds
poll_interval=2

CMD="/home/example/cron/prod/cache_update.sh >/dev/null 2>&1"

while [ true ]; do
    #echo "Running cache_update..."
    $CMD
    #sleep poll_interval time
    sleep $poll_interval
done

~ chmod +x ./cache_update_runner.sh

Then create systemd unit:

# vim /etc/systemd/system/cache-update-runner-prod.service

[Unit]
After=mariadb.service

[Service]
User=example
ExecStart=/home/example/cron/prod/cache_update_runner.sh

[Install]
WantedBy=default.target

# chmod 664 /etc/systemd/system/cache-update-runner-prod.service
# systemctl daemon-reload
# systemctl enable cache-update-runner-prod.service
# systemctl start cache-update-runner-prod.service
# systemctl status cache-update-runner-prod.service