ZincSearch: Alternativa Ligera a Elasticsearch

ZincSearch es un motor de búsqueda escrito en Go que ofrece una API compatible con Elasticsearch en un único binario de menos de 100 MB, con un consumo de memoria dramáticamente inferior al de su homólogo. Con ZincSearch puedes indexar millones de documentos, realizar búsquedas de texto completo y conectar herramientas como Grafana o clientes de Elasticsearch sin cambios en el código. Esta guía cubre la instalación, la gestión de índices, la ingesta de datos y la integración con Grafana para dashboards de logs.

Requisitos Previos

  • Ubuntu 20.04/22.04, Debian 11+ o CentOS 8+/Rocky Linux 8+
  • 512 MB de RAM mínimo (1-2 GB recomendado para índices grandes)
  • Espacio en disco según el volumen de datos
  • Puerto 4080 disponible

Instalación de ZincSearch

Instalación del binario precompilado

# Descargar la última versión estable para Linux x86_64
ZINC_VERSION=0.4.10
wget "https://github.com/zincsearch/zincsearch/releases/download/v${ZINC_VERSION}/zincsearch_${ZINC_VERSION}_Linux_x86_64.tar.gz" -P /tmp

cd /tmp && tar xzf zincsearch_${ZINC_VERSION}_Linux_x86_64.tar.gz

# Mover el binario al PATH del sistema
sudo mv zincsearch /usr/local/bin/
sudo chmod +x /usr/local/bin/zincsearch

# Verificar la instalación
zincsearch --version

Instalación con Docker

# Desplegar ZincSearch con Docker
docker run -d \
  --name zincsearch \
  -p 4080:4080 \
  -e ZINC_DATA_PATH="/data" \
  -e ZINC_FIRST_ADMIN_USER="admin" \
  -e ZINC_FIRST_ADMIN_PASSWORD="Admin_Contraseña123!" \
  -v zincsearch-data:/data \
  public.ecr.aws/zinclabs/zincsearch:latest

# Verificar el estado
docker logs zincsearch
curl http://localhost:4080/healthz

Instalación con Docker Compose

# docker-compose.yml
version: "3.8"
services:
  zincsearch:
    image: public.ecr.aws/zinclabs/zincsearch:latest
    container_name: zincsearch
    ports:
      - "4080:4080"
    environment:
      ZINC_DATA_PATH: /data
      ZINC_FIRST_ADMIN_USER: admin
      ZINC_FIRST_ADMIN_PASSWORD: Admin_Contraseña123!
      ZINC_PROMETHEUS_ENABLE: "true"
    volumes:
      - zincsearch-data:/data
    restart: unless-stopped

volumes:
  zincsearch-data:

Configuración y Primer Inicio

# Crear usuario y directorios para el servicio
sudo useradd -r -s /bin/false zincsearch
sudo mkdir -p /var/lib/zincsearch
sudo chown -R zincsearch:zincsearch /var/lib/zincsearch

# Crear el servicio systemd
sudo tee /etc/systemd/system/zincsearch.service > /dev/null <<EOF
[Unit]
Description=ZincSearch Search Engine
After=network.target

[Service]
Type=simple
User=zincsearch
Group=zincsearch
Environment="ZINC_DATA_PATH=/var/lib/zincsearch"
Environment="ZINC_FIRST_ADMIN_USER=admin"
Environment="ZINC_FIRST_ADMIN_PASSWORD=Admin_Contraseña123!"
Environment="ZINC_SERVER_PORT=4080"
Environment="ZINC_SERVER_ADDRESS=0.0.0.0"
Environment="ZINC_PROMETHEUS_ENABLE=true"
ExecStart=/usr/local/bin/zincsearch
Restart=on-failure
RestartSec=5

[Install]
WantedBy=multi-user.target
EOF

sudo systemctl daemon-reload
sudo systemctl enable zincsearch --now

# Verificar estado
sudo systemctl status zincsearch

# Probar la API
curl -u admin:Admin_Contraseña123! http://localhost:4080/healthz

Variables de entorno principales:

VariableDescripciónValor por defecto
ZINC_DATA_PATHDirectorio de datos./data
ZINC_SERVER_PORTPuerto de escucha4080
ZINC_SERVER_ADDRESSDirección de escucha0.0.0.0
ZINC_FIRST_ADMIN_USERUsuario administrador inicialadmin
ZINC_FIRST_ADMIN_PASSWORDContraseña administrador-
ZINC_MAX_RESULTSMáximo de resultados por búsqueda10000
ZINC_PROMETHEUS_ENABLEActivar métricas Prometheusfalse

Interfaz Web de Administración

ZincSearch incluye una interfaz web en http://tu-ip:4080. Desde ella puedes:

  • Crear y gestionar índices
  • Ejecutar búsquedas de forma visual
  • Ver estadísticas de índices
  • Gestionar usuarios y roles

Gestión de Índices

# Variables para facilitar los comandos
export ZINC_URL="http://localhost:4080"
export ZINC_AUTH="-u admin:Admin_Contraseña123!"

# Crear un índice con mapping explícito
curl -X POST "${ZINC_URL}/api/index" \
  ${ZINC_AUTH} \
  -H "Content-Type: application/json" \
  -d '{
    "name": "logs-nginx",
    "storage_type": "disk",
    "mappings": {
      "properties": {
        "timestamp": {"type": "date",    "format": "2006-01-02T15:04:05Z07:00", "index": true},
        "ip_cliente": {"type": "ip",     "index": true},
        "metodo":     {"type": "keyword","index": true},
        "ruta":       {"type": "text",   "index": true},
        "status":     {"type": "numeric","index": true},
        "user_agent": {"type": "text",   "index": true}
      }
    }
  }'

# Listar todos los índices
curl ${ZINC_AUTH} "${ZINC_URL}/api/index"

# Ver un índice específico
curl ${ZINC_AUTH} "${ZINC_URL}/api/index/logs-nginx"

# Eliminar un índice
curl -X DELETE ${ZINC_AUTH} "${ZINC_URL}/api/index/logs-nginx"

# Ver estadísticas de uso
curl ${ZINC_AUTH} "${ZINC_URL}/api/index/logs-nginx/stat"

Indexación de Documentos

ZincSearch crea el índice automáticamente si no existe al recibir el primer documento:

# Indexar un documento individual
curl -X POST "${ZINC_URL}/api/logs-nginx/_doc" \
  ${ZINC_AUTH} \
  -H "Content-Type: application/json" \
  -d '{
    "timestamp": "2024-01-15T10:30:45Z",
    "ip_cliente": "192.168.1.100",
    "metodo": "GET",
    "ruta": "/api/productos",
    "status": 200,
    "bytes": 1234,
    "user_agent": "Mozilla/5.0"
  }'

# Ingesta masiva con la API de bulk (compatible con Elasticsearch)
cat > /tmp/bulk-data.ndjson <<EOF
{"index": {"_index": "logs-nginx", "_id": "1"}}
{"timestamp": "2024-01-15T10:31:00Z", "ip_cliente": "192.168.1.101", "metodo": "POST", "ruta": "/api/pedidos", "status": 201, "bytes": 456}
{"index": {"_index": "logs-nginx", "_id": "2"}}
{"timestamp": "2024-01-15T10:31:05Z", "ip_cliente": "192.168.1.102", "metodo": "GET", "ruta": "/api/usuarios", "status": 401, "bytes": 78}
EOF

curl -X POST "${ZINC_URL}/es/_bulk" \
  ${ZINC_AUTH} \
  -H "Content-Type: application/x-ndjson" \
  --data-binary @/tmp/bulk-data.ndjson

# API nativa de ZincSearch para ingesta masiva (más eficiente)
curl -X POST "${ZINC_URL}/api/logs-nginx/_multi" \
  ${ZINC_AUTH} \
  -H "Content-Type: application/json" \
  -d '{
    "index": "logs-nginx",
    "records": [
      {"timestamp": "2024-01-15T10:32:00Z", "metodo": "GET", "status": 404},
      {"timestamp": "2024-01-15T10:32:05Z", "metodo": "DELETE", "status": 500}
    ]
  }'

Búsqueda con API Compatible con Elasticsearch

ZincSearch implementa un subconjunto de la API de Elasticsearch 7.x:

# Búsqueda básica (API ES compatible)
curl -X POST "${ZINC_URL}/es/logs-nginx/_search" \
  ${ZINC_AUTH} \
  -H "Content-Type: application/json" \
  -d '{
    "query": {
      "match": {
        "ruta": "api productos"
      }
    },
    "sort": [{"timestamp": "desc"}],
    "size": 20,
    "from": 0
  }'

# Búsqueda con filtros por rango de fecha
curl -X POST "${ZINC_URL}/es/logs-nginx/_search" \
  ${ZINC_AUTH} \
  -H "Content-Type: application/json" \
  -d '{
    "query": {
      "bool": {
        "must": [
          {"match": {"metodo": "GET"}}
        ],
        "filter": [
          {"range": {
            "timestamp": {
              "gte": "2024-01-15T00:00:00Z",
              "lte": "2024-01-15T23:59:59Z"
            }
          }},
          {"term": {"status": 200}}
        ]
      }
    },
    "aggs": {
      "por_status": {
        "terms": {"field": "status", "size": 10}
      },
      "por_hora": {
        "date_histogram": {
          "field": "timestamp",
          "calendar_interval": "hour"
        }
      }
    },
    "size": 0
  }'

# API de búsqueda nativa de ZincSearch (más simple)
curl -X POST "${ZINC_URL}/api/logs-nginx/_search" \
  ${ZINC_AUTH} \
  -H "Content-Type: application/json" \
  -d '{
    "search_type": "match",
    "query": {
      "term": "api",
      "field": "ruta",
      "start_time": "2024-01-15T00:00:00Z",
      "end_time": "2024-01-15T23:59:59Z"
    },
    "sort_fields": ["-timestamp"],
    "from": 0,
    "max_results": 50
  }'

Integración con Grafana

ZincSearch puede usarse como fuente de datos en Grafana mediante el plugin de Elasticsearch:

# Añadir ZincSearch como datasource en Grafana vía API
curl -X POST http://grafana:3000/api/datasources \
  -u admin:contraseña_grafana \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ZincSearch",
    "type": "elasticsearch",
    "url": "http://zincsearch:4080",
    "access": "proxy",
    "basicAuth": true,
    "basicAuthUser": "admin",
    "secureJsonData": {
      "basicAuthPassword": "Admin_Contraseña123!"
    },
    "jsonData": {
      "esVersion": "7.10.0",
      "index": "logs-nginx",
      "timeField": "timestamp",
      "logMessageField": "message",
      "logLevelField": "level"
    }
  }'

En la interfaz de Grafana:

  1. Ve a Configuration → Data Sources → Add data source
  2. Selecciona Elasticsearch
  3. URL: http://tu-ip-zincsearch:4080
  4. Activa Basic auth con las credenciales de ZincSearch
  5. En Elasticsearch details: versión 7.x, nombre del índice y campo de tiempo
  6. Haz clic en Save & Test

Solución de Problemas

ZincSearch no arranca:

# Verificar logs del servicio
sudo journalctl -u zincsearch -n 50 --no-pager

# Verificar permisos del directorio de datos
ls -la /var/lib/zincsearch/
sudo chown -R zincsearch:zincsearch /var/lib/zincsearch/

# Probar el binario directamente
ZINC_DATA_PATH=/tmp/zinc-test ZINC_FIRST_ADMIN_USER=admin ZINC_FIRST_ADMIN_PASSWORD=test123 zincsearch

Error 401 en las peticiones:

# Verificar credenciales
curl -v -u admin:Admin_Contraseña123! http://localhost:4080/healthz

# Si olvidaste la contraseña, borrar los datos y reiniciar con nuevas credenciales
# ¡ATENCIÓN: esto borra todos los índices!
sudo systemctl stop zincsearch
sudo rm -rf /var/lib/zincsearch/*
sudo systemctl start zincsearch

Alto consumo de disco:

# Ver el tamaño de cada índice
du -sh /var/lib/zincsearch/*/

# Configurar tiempo de vida (TTL) de documentos
# ZincSearch no tiene TTL nativo, gestionar la retención eliminando índices antiguos:
curl -X DELETE ${ZINC_AUTH} "${ZINC_URL}/api/index/logs-nginx-2024-01"

La API de Elasticsearch no es compatible:

# ZincSearch implementa solo un subconjunto de la API de ES
# Funcionalidades no disponibles: ILM, snapshots, rollover, pipelines de ingest
# Para estas funciones, considerar OpenSearch o Elasticsearch

Conclusión

ZincSearch es una alternativa práctica y eficiente a Elasticsearch para casos de uso donde los requisitos de recursos son una prioridad y no se necesitan las funcionalidades más avanzadas de Elasticsearch. Su compatibilidad con la API de Elasticsearch simplifica la migración y permite usar clientes y herramientas existentes como Grafana sin modificaciones. Especialmente adecuado para centralizar logs de aplicaciones pequeñas o medianas donde el coste operativo de mantener un clúster Elasticsearch completo no está justificado.