>> Apresentação e considerações

Fala ChurrOpers, vamos falar um pouco de Solr?

Faço esse artigo com base em estudos que realizei sobre como implantar um ambiente de SolrCloud em produção, vou procurar expor tudo o que eu consegui absorver nos meus estudos.

A abordagem que vou seguir é na visão de um Administrador de Sistemas e NÃO de um desenvolvedor, ou seja, falarei sobre a implantação e não sobre o seu uso.

Espero que tenham uma boa leitura, críticas e sugestões são bem vindas para o aperfeiçoamento do artigo.

Let`s go!

>> O que é Solr

O Solr é um poderoso search engine OpenSource para busca textual, escrito em Java e construído à partir do Apache Lucene.

Com o Solr você pode indexar documentos e fazer buscas com base na correspondência das consultas, o que torna as buscas muito mais rápidas.

Dentre os documentos que podem ser indexados temos: xml, json, csv, pdf, doc, docx, ppt, pptx, xls, xlsx, odt, odp, ods, ott, otp, ots, rtf, htm, html, txt e log.

Na Wiki oficial existe um link que lista quais são os sites que utilizam Solr para indexar suas pesquisas.

https://wiki.apache.org/solr/PublicServers

>> Arquitetura SolrCloud + Zookeeper

Considerando um ambiente de produção na AWS por exemplo, segue uma sugestão de arquitetura base e funcional para um site de pequeno a médio porte que está iniciando a utilização do SolrCloud.

Infelizmente não tenho benchmarks para dizer com precisão um dimensionamento adequado de ambiente, mais com essa arquitetura abaixo temos bastante espaço para escalar o cluster sem problemas.

solrcloud-zookeeper

>> Recomendação para a preparação dos discos de dados

Solr

É recomendado separar os arquivos do Solr, como logs e arquivos de índice, dos arquivos incluídos no pacote da distribuição, pois isso facilita a atualização do Solr e é considerado uma boa prática para o seu uso em produção e é recomendável que o disco de dados seja esteja apartado do disco do sistema operacional. O tamanho dos discos varia de acordo com a sua demanda esperada de dados a serem indexados.

Zookeeper

Para o Zookeeper podemos seguir a recomendação da mesma forma que para o Solr, o Zookeeper irá guardar todos os metadados e arquivos de configuração do Solr afim de garantir o serviço de descoberta, eleição e a alta disponibilidade do cluster. Com relação ao tamanho do disco do Zookeeper podemos considerar algo em torno de 30GB com a possibilidade de aumento, e dependendo do tamanho do seu cluster e do tanto que espera indexar de dados (digo isso para clusters muito grandes) podemos considerar um tamanho de até uns 100GB mais isso precisa ser avaliado na implantação.

>> Setup do meu LAB

  • 3 VMs Zookeeper – 256 RAM e 1 vCPU pra cada VM
  • 2 VMs SolrCloud – 2GB RAM e 1 vCPU pra cada VM
  • CentOS: 7.4
  • Solr: 7.2.1
  • Zookeeper: 3.4.11
  • Oracle JDK: 1.8.0_161

Captura de Tela 2018-03-30 às 14.45.10

>> Vamos iniciar a parte prática

Formatação dos discos de dados

Exemplo de formatação do device, vamos utilizar o sistema de arquivos ext4 , e o parâmetro -m0, remove a reserva de 5% no device que só poderia ser ocupado pelo usuário root:

mkfs.ext4 -m0 /dev/sdb

No arquivo /etc/fstab adicione os parâmetros "noatime,defaults" , segue um exemplo da montagem do fstab.

Exemplo de montagem ZK

/dev/sdb /var/zookeeper ext4 noatime,defaults 0 0

# Exemplo de montagem Solr

/dev/sdb /var/solr ext4 noatime,defaults 0 0

>> Preparação do sistema Operacional

A preparação deve ser feita em todos os nodes do cluster, tanto de Solr como de Zookeeper.

Instalação de dependências

Instalar em todos os hosts os pacotes base com as ferramentas que nos auxiliarão na configuração do Cluster.

yum update -y; yum install wget lsof vim nc net-tools -y

Configurando o /etc/hosts

A configuração ideal é que os nodes se comuniquem entre si utilizando DNS ao invés de IP, em ambientes que não temos DNS podemos configurar o arquivo /etc/hosts para que a comunicação por nome aconteça.

Neste artigo estamos considerando a instalação do SolrCloud e do Zookeeper nos mesmos nodes, segue uma forma sugerida para a configuração do /etc/hosts, lembrando de ajustar os IPs e os nomes de acordo com seu ambiente.

No meu lab ficou assim:

### Cluster SolrCloud ##
192.168.250.101 solr1.churrops.lab	solr1
192.168.250.102 solr2.churrops.lab	solr2
#### Cluster Zookeeper ##
192.168.250.103 zk1.churrops.lab	zk1
192.168.250.104 zk2.churrops.lab	zk2
192.168.250.105 zk3.churrops.lab	zk3

Desabilitar Swap

É muito importante que a memória Swap esteja desabilitada, pois o seu uso degrada muito a performance das aplicações.

echo "vm.swappiness=1" >> /etc/sysctl.conf
echo 1 > /proc/sys/vm/swappiness

OPCIONAL: Desabilitar Firewall e SELinux

Obs.: Esse artigo ainda não contempla a configuração desses itens (Firewall e SELinux), ficando a cargo da sua necessidade e conhecimento dessas ferramentas, para seguirmos vamos desativá-los.

systemctl disable firewalld; systemctl stop firewalld

sed -ri 's/SELINUX=enforcing/SELINUX=permissive/' /etc/selinux/config

setenforce 0

Instalação do Oracle JDK 8

Como o Solr e o Zookeeper são ambos escritos em Java rodando em cima de JVM (Java Virtual Machine), precisamos do pacote JDK, pode ser utilizado tanto o OpenJDK como o Oracle JDK 8, porém em ambientes produtivos recomenda-se o JDK da Oracle e de preferência em sua última versão, que pode ser consultada nesse link:

http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

Vamos realizar o download e instalação da versão: java version "1.8.0_161"

wget -c --header "Cookie: oraclelicense=accept-securebackup-cookie"  "http://download.oracle.com/otn-pub/java/jdk/8u161-b12/2f38c3b165be4555a1fa6e98c45e0808/jdk-8u161-linux-x64.rpm"

rpm -ivh jdk-8u161-linux-x64.rpm

>> Instalação do Zookeeper

O que é o Zookeeper

O O Apache Zookeeper é essencialmente um serviço centralizado para sistemas distribuídos de armazenamento chave/valor hierárquico, provê serviço de configuração distribuída, serviço de sincronização e registro de nomes para grandes sistemas. O ZooKeeper era um subprojeto do Hadoop, mas agora é um projeto Apache de nível superior por si só.

A arquitetura do ZooKeeper suporta alta disponibilidade através de serviços redundantes. Os clientes podem, assim, pedir a outro líder do ZooKeeper se o primeiro não responder. Os nós do ZooKeeper armazenam seus dados em um espaço de nomes hierárquico, muito parecido com um sistema de arquivos ou uma estrutura de dados em árvore. Os clientes podem ler e gravar nos nós e, desse modo, ter um serviço de configuração compartilhado. O ZooKeeper pode ser visto como um sistema de transmissão atômica, através do qual as atualizações são totalmente ordenadas. O protocolo ZooKeeper Atomic Broadcast (ZAB) é o núcleo do sistema.

É importante que um cluster de Zookeeper esteja em um número ÍMPAR de nodes para que haja QUORUM. Para ambientes produtivos recomenda-se 3 nodes.

A conta fica mais ou menos assim: Se você tem 3 nodes, pode perder 1 (depois voltar é claro…rs), se você tem 5, pode perder 2…agora se você tem 6 e perder 3 o seu cluster quebra porque a maioria do QUORUM precisa estar operante.

# Referencias:
http://zookeeper.apache.org/doc/r3.3.2/zookeeperAdmin.html
https://lucene.apache.org/solr/guide/7_2/setting-up-an-external-zookeeper-ensemble.html

No print abaixo temos as configurações base que fiz para que o cluster funcione, temos respectivamente o hostname com fqdn, o disco de dados montado no /etc/fstab, e o arquivo /etc/hosts configurado para que os hosts se falem pelo nome.

Captura de Tela 2018-03-30 às 13.22.14

Criando o usuário para o Zookeeper

Vamos criar o usuário e grupo que será responsável pela execução do serviço do Zookeeper, e será o Owner dos diretórios.

groupadd zookeeper; useradd -g zookeeper --comment "Zookeeper Service User" -s /bin/bash zookeeper

Download e descompactação

wget http://ftp.unicamp.br/pub/apache/zookeeper/zookeeper-3.4.11/zookeeper-3.4.11.tar.gz -O /tmp/zookeeper-3.4.11.tar.gz

tar xzf /tmp/zookeeper-3.4.11.tar.gz -C /opt/

ln -s /opt/zookeeper-3.4.11 /opt/zookeeper

Ajustando o zoo.cfg

O arquivo zoo.cfg é o arquivo que deve estar presente em todos os nodes que possuem Zookeeper, pois é através dele que os nodes irão se comunicar para formar o Cluster.

vim /opt/zookeeper/conf/zoo.cfg
tickTime=2000
dataDir=/var/zookeeper/data
clientPort=2181
initLimit=5
syncLimit=2
server.1=zk1:2888:3888
server.2=zk2:2888:3888
server.3=zk3:2888:3888

Criando o diretório de data e logs

O diretório de instalação fica em local separado do diretório de dados, o ideal é que o diretório de dados esteja em um disco dedicado para não ter concorrência no acesso.

mkdir /var/zookeeper/data; mkdir /var/log/zookeeper

Configurando o myid de cada node

O Arquivo myid é um arquivo que deve estar presente em todos os nodes do Zookeeper, a única informação que deve ter nele é o número do ID de cada host, o ID deve referenciar o node que está configurado no zoo.cfg.

Executar no node 1 – zk1

echo 1 > /var/zookeeper/data/myid

Executar no node 2 – zk2

echo 2 > /var/zookeeper/data/myid

Executar no node 3 – zk3

echo 3 > /var/zookeeper/data/myid

Ajustando o owner dos diretórios do Zookeeper

chown -R zookeeper:zookeeper /opt/zookeeper*
chown -R zookeeper:zookeeper /var/zookeeper
chown -R zookeeper:zookeeper /var/log/zookeeper
vim /opt/zookeeper/bin/zkEnv.sh

Agora precisamos configurar o arquivo zkEnv.sh adicionando a variável ZOO_LOG_DIR apontando para o diretório de logs criado.

	ZOO_LOG_DIR=/var/log/zookeeper

Adicionando o script do service no Systemd

Esse é o script iniciar, parar e restartar o serviço, vamos criar o script e ativá-lo para que possamos usar.

vim /etc/systemd/system/zookeeper.service
[Unit]
Description=Apache Zookeeper server
Documentation=http://zookeeper.apache.org
Requires=network.target
After=network.target 

[Service]
Type=forking
User=zookeeper
Group=zookeeper
SyslogIdentifier=zookeeper
ExecStart=/opt/zookeeper/bin/zkServer.sh start
ExecStop=/opt/zookeeper/bin/zkServer.sh stop
ExecReload=/opt/zookeeper/bin/zkServer.sh restart

[Install]
WantedBy=multi-user.target
systemctl daemon-reload
systemctl enable zookeeper; systemctl start zookeeper

Testando

Execute os comandos abaixo apontando para cada host, a linha mode indica se o node é um leader ou um fallower, se os 3 endereços responderam o seu Zookeeper foi configurado com sucesso.

echo srvr | nc zk1 2181
echo stat | nc zk1 2181

Se o status do Cluster está como a imagem abaixo, SUCESSO!
O Cluster de Zookeeper está funcional!

Captura de Tela 2018-03-30 às 13.51.14

>> Instalação do SolrCloud

No print abaixo temos as configurações base que fiz para que o cluster funcione, temos respectivamente o hostname com fqdn, o disco de dados montado no /etc/fstab, e o arquivo /etc/hosts configurado para que os hosts se falem pelo nome. (Assim como configurado nos hosts do Zookeeper)

Captura de Tela 2018-03-30 às 13.58.21

Executar o Solr como root não é recomendado por motivos de segurança, o usuário a ser utilizado deve ser criado previamente e será o owner dos diretórios de instalação e do home do Solr que contém os dados e logs.

groupadd solr; useradd -g solr --comment "Solr Service User" -s /bin/bash solr

Estrutura de diretórios

Vamos considerar o uso do diretório /opt/solr para os arquivos de instalação, e o diretório /var/lib/solr para os Writable Files e os logs.

mkdir /var/solr/data

Realizando o download do pacote de instalação do Solr

cd /tmp; wget http://ftp.unicamp.br/pub/apache/lucene/solr/7.2.1/solr-7.2.1.tgz

Com o comando abaixo vamos realizar somente a extração do instalador

install_solr_service.sh.

tar xzf /tmp/solr-7.2.1.tgz solr-7.2.1/bin/install_solr_service.sh --strip-components=2

Vamos executar o install_solr_service.sh, esse script realizará a instalação do solr como serviço, já copiando o script de init para /etc/init.d/solr, e o parâmetro -n vai ignorar o start do Solr, lembrando que antes de iniciar o serviço precisamos fazer as configurações para que ele funcione em Cluster.

./install_solr_service.sh /tmp/solr-7.2.1.tgz -i /opt -d /var/solr -u solr -s solr -p 8983 -n

Segue como ficará a saída.

Captura de Tela 2018-03-30 às 14.24.18

Configurando o arquivo que possui as variáveis utilizadas no start do SolrCloud

vim /etc/default/solr.in.sh

Adicione ao final do arquivo, ajustando os valores de acordo com o ambiente.

SOLR_PID_DIR="/var/solr"
SOLR_HOME="/var/solr/data"
LOG4J_PROPS="/var/solr/log4j.properties"
SOLR_LOGS_DIR="/var/solr/logs"
SOLR_PORT="8983"

SOLR_MODE=solrcloud
## Ajuste o Solr Heap de acordo com a quantidade de RAM que você tem na máquina
## aque cerca de 70% da RAM
SOLR_HEAP="768m"
ZK_HOST="zk1:2181,zk2:2181,zk3:2181,"
ZK_CLIENT_TIMEOUT="15000"
ENABLE_REMOTE_JMX_OPTS="False"

## Configuração do log do Garbage Collector
GCLOG_OPTS="-verbose:gc \
-Xloggc:logs/gc.log \
-XX:+PrintGCDateStamps \
-XX:+PrintGCDetails \
-XX:+PrintAdaptiveSizePolicy \
-XX:+PrintReferenceGC
"
## Configuração de tunning para utilizar o g1gc
## Referência: # https://wiki.apache.org/solr/ShawnHeisey
GC_TUNE="-XX:+UseG1GC \
-XX:+PerfDisableSharedMem \
-XX:+ParallelRefProcEnabled \
-XX:G1HeapRegionSize="8m" \
-XX:MaxGCPauseMillis="250" \
-XX:InitiatingHeapOccupancyPercent="75" \
-XX:+UseLargePages \
-XX:+AggressiveOpts
"

Saiba mais sobre o tunning da JVM clicando aqui nesse link:
https://lucene.apache.org/solr/guide/7_2/jvm-settings.html#jvm-settings

Iniciando o serviço

chkconfig solr on
service solr start

Se a saída ficou assim, SUCESSO!

Captura de Tela 2018-03-30 às 14.32.16

>> Acessando o serviço do Solr pelo Browser

Solr1 – http://192.168.250.101:8983/solr/#/

Captura de Tela 2018-03-30 às 14.34.53

Solr2 – http://192.168.250.101:8983/solr/#/

Captura de Tela 2018-03-30 às 14.35.45

>> Role para instalação automatizada via Ansible

Pra quem se interessar tenho no meu github a instalação desse setup de forma atumatizada com Ansible, faltam alguns ajustes mais do jeito que está já funciona muito bem.

https://github.com/churrops/solrcoud-automated

Enjoy!

>> Conclusão

O objetivo desse artigo era justamente mostrar como instalar um ambiente de SolrCloud no modo Cluster com Zookeeper para alta disponibilidade, se você chegou até esse ponto e instalou o Cluster o objetivo desse artigo foi atingido, as configurações ficarão para os próximos!

Muito obrigado!

>> Referências

https://lucene.apache.org/solr/guide/7_2/taking-solr-to-production.html

https://lucene.apache.org/solr/guide/7_2/aws-solrcloud-tutorial.html

https://lucene.apache.org/solr/guide/7_2/setting-up-an-external-zookeeper-ensemble.html

https://github.com/ajunior/solr