Главная
|
Услуги и цены
VDS
Выделенные серверы
Размещение сервера
|
F.A.Q
|
О компании
|

Установка и базовая настройка поискового движка Elasticsearch на Ubuntu

Elasticsearch - это мощный поисковый и аналитический движок. Его используют для логирования, поиска по сайту, аналитики и работы с большими объемами данных.

На VDS с его помощью можно искать логи, индексировать данные за миллисекунды.

На сайте с помощью него можно реализовать качественный поиск по сайту, с автодополнением, пониманием опечаток и пр.

В этой статье разберём установку, базовую настройку и несколько примеров применения (в администрировании сервера и применение в бекенде сайта) Elasticsearch на Ubuntu

Note

Если вы только купили сервер:

Подключитесь к серверу

Выполните подготовку сервера к работе

Установка Java

Elasticsearch работает на Java.

Проверим, установлена ли Java:

java -version 

Если система ответила «command not found», установите OpenJDK:

apt install openjdk-17-jdk -y 

Современные версии Elasticsearch ориентированы на эту ветку. С более старыми версиями возможны проблемы совместимости.

После установки снова проверьте:

java -version 

Если версия отображается, то всё готово.

Добавление репозитория Elasticsearch

Используем официальный репозиторий.

Добавим ключ подписи:

wget -qO - https://artifacts.elastic.co/GPG-KEY-elasticsearch | apt-key add - 

Затем добавим репозиторий:

echo "deb https://artifacts.elastic.co/packages/8.x/apt stable main" | tee /etc/apt/sources.list.d/elastic-8.x.list 

Обновим список пакетов:

apt update 

Установка Elasticsearch

apt install elasticsearch -y 

Пакет устанавливается как системный сервис.

Это удобно, он автоматически интегрируется с systemd.

После установки сервис не всегда запускается автоматически. Проверим статус:

systemctl status elasticsearch 

Если он не активен, запустите вручную:

systemctl start elasticsearch 

И добавьте автозапуск:

systemctl enable elasticsearch 

На практике лучше всегда включать автозапуск. После перезагрузки сервера сервис должен подниматься сам.

Первичная настройка

Основной конфигурационный файл находится здесь:

/etc/elasticsearch/elasticsearch.yml 

Откройте его:

nano /etc/elasticsearch/elasticsearch.yml 

Настройка network.host

По умолчанию Elasticsearch слушает только localhost. Это безопасно, но недоступно извне.

Если вы планируете подключаться удалённо, укажите IP сервера:

network.host: 0.0.0.0 

Открывать Elasticsearch в интернет без защиты не нужно. Если нужен внешний доступ, обязательно настройте firewall и аутентификацию.

Если сервер используется только локально (например, вместе с Nginx и приложением), лучше оставить localhost.

Задать пароль

Выполните

/usr/share/elasticsearch/bin/elasticsearch-reset-password -u elastic 

У вас запросят пароль, введите его, потом повторите.

Проверка работы

Проверим, отвечает ли сервер:

curl -u elastic:password -v https://127.0.0.1:9200 --insecure 

Если всё работает, вы получите JSON-ответ с информацией о версии и имени узла.

Это подтверждает, что сервис слушает порт и готов к работе.

Версию сервера нужно иметь ввиду, это пригодится при установке клиента. Если версии клиента и сервера не будут совместимы, то вы получите ошибку.

Настройка firewall

Если используется UFW, откройте порт 9200 только при необходимости:

ufw allow 9200 

Открытый Elasticsearch это частая цель атак

Если доступ нужен только приложению на том же сервере, то порт открывать не нужно. В нашем случае Elasticsearch используется локально.

Где смотреть логи

Проверить логи можно в директории:

/var/log/elasticsearch/ 

Или через journalctl:

journalctl -u elasticsearch -f 

Практический пример: индексирование логов веб-сервера

Например, у вас есть сайт на сервере Ubuntu. Нужно быстро искать ошибки 500, анализировать IP-адреса или смотреть, какие страницы чаще всего вызывают проблемы.

Elasticsearch идеально подходит для этого.

Шаг 1. Создадим индекс для логов

Создадим индекс с простым описанием структуры данных:

curl -X PUT "https://localhost:9200/nginx-logs" \
-u elastic:password \
-H 'Content-Type: application/json' \
-d '{
  "mappings": {
    "properties": {
      "timestamp": { "type": "date" },
      "ip":        { "type": "ip" },
      "method":    { "type": "keyword" },
      "url":       { "type": "text" },
      "status":    { "type": "integer" }
    }
  }
}' --insecure 

Теперь Elasticsearch знает, какие поля мы будем хранить.

Шаг 2. Добавим тестовую запись

Добавим одну запись, имитирующую строку лога:

curl -X POST "https://localhost:9200/nginx-logs/_doc" \
-u elastic:password \
-H 'Content-Type: application/json' \
-d '{
  "timestamp": "2026-02-28T12:00:00",
  "ip": "192.168.1.10",
  "method": "GET",
  "url": "/login",
  "status": 500
}' --insecure 

Документ мгновенно индексируется. Теперь по нему можно искать.

Шаг 3. Найдём все ошибки 500

curl -X GET "https://localhost:9200/nginx-logs/_search" \
-u elastic:password \
-H 'Content-Type: application/json' \
-d '{
  "query": {
    "match": {
      "status": 500
    }
  }
}' --insecure 

В ответе вы получите найденные записи.

Даже если таких записей будут миллионы, поиск займёт миллисекунды.

Шаг 4. Поиск по IP

Например, нужно проверить активность конкретного IP:

curl -X GET "https://localhost:9200/nginx-logs/_search" \
-u elastic:password \
-H 'Content-Type: application/json' \
-d '{
  "query": {  
    "match": {  
      "ip": "192.168.1.10"  
    }  
  }  
}' --insecure 

Так можно быстро выявлять подозрительную активность или анализировать поведение пользователей.

Как это применяется в реальной инфраструктуре

Например, приложение на PHP, Node.js или Python может напрямую отправлять JSON-документы в Elasticsearch.

Дальше данные визуализируют через Kibana или используют для построения внутренней аналитики.

Практический пример: реализация поиска по сайту на Python

Представим, что у вас есть сайт с товарами или статьями. Нужно реализовать быстрый полнотекстовый поиск.

1. Установка клиента Elasticsearch для Python

Установим официальный клиент:

pip install elasticsearch==8.19.0 

Он позволяет работать с Elasticsearch напрямую через API.

2. Создание контента, индекса, поиск

Разберем пример на Python. Тут реализована инициация Elasticsearch в коде, заполнение БД данными (для презентации функционала поиска, если у вас уже есть база с данными, то это делать не нужно), создание индекса и индексация данных и сам поиск по данным.

import random
import string
from datetime import datetime, timedelta
import mysql.connector
from elasticsearch import Elasticsearch, exceptions, helpers


# -------------------------------
# Настройки MySQL
# -------------------------------
DB_CONFIG = {
    "host": "localhost",
    "user": "example_user",
    "password": "password",  # ваш пароль
    "database": "example_database"
}

# -------------------------------
# Настройки Elasticsearch
# -------------------------------
es = Elasticsearch(
    "https://localhost:9200",
    basic_auth=("elastic", "password"),  # ваш пароль elastic
    verify_certs=False
)

index_name = "articles"

# -------------------------------
# Подключение к MySQL
# -------------------------------
conn = mysql.connector.connect(**DB_CONFIG)
cursor = conn.cursor()

# -------------------------------
# Создадим тестовую базу данных, вы можете использовать для поиска свою, если она у вас уже есть
# -------------------------------
cursor.execute("DROP TABLE IF EXISTS articles")
cursor.execute("""
CREATE TABLE articles (
    id INT AUTO_INCREMENT PRIMARY KEY,
    title VARCHAR(255),
    content TEXT,
    category VARCHAR(50),
    published_at DATE
)
""")

conn.commit()

categories = ["devops", "web", "data", "security"]

def random_text(words=10):
    return " ".join("".join(random.choices(string.ascii_lowercase, k=random.randint(3,10)))
                    for _ in range(words))

# Добавим 10_000 записей
for _ in range(10000):
    title = random_text(5)
    content = random_text(20)
    category = random.choice(categories)
    published_at = datetime.now() - timedelta(days=random.randint(0, 365))
    cursor.execute(
        "INSERT INTO articles (title, content, category, published_at) VALUES (%s, %s, %s, %s)",
        (title, content, category, published_at.date())
    )
conn.commit()
print("Добавлено 10 000 записей в MySQL")

# -------------------------------
# Перенос данных из MySQL в Elasticsearch
# -------------------------------
cursor.execute("SELECT title, content, category, published_at FROM articles")  
rows = cursor.fetchall()

# -------------------------------
# Создание индекса в Elasticsearch
# -------------------------------
# Создание индекса  
try:  
    if not es.indices.exists(index=index_name):  
        es.indices.create(  
        index=index_name,  
        mappings={  
            "properties": {  
                "title": {"type": "text"},  
                "content": {"type": "text"},  
                "category": {"type": "keyword"},  
                "published_at": {"type": "date"}  
            }  
        }  
        )  
        print(f"Индекс '{index_name}' создан")  
    else:  
        print(f"Индекс '{index_name}' уже существует")  
except exceptions.BadRequestError as e:  
    print("Ошибка при создании индекса:", e)


actions = [  
    {  
        "_index": index_name,  
        "_source": {  
            "title": row[0],  
            "content": row[1],  
            "category": row[2],  
            "published_at": row[3].isoformat()  
        }  
    }  
    for row in rows  
]

helpers.bulk(es, actions) # используем bulk API вместо одиночных insert, т.к. у нас 10000 записей

print("Данные загружены в Elasticsearch")

# -------------------------------
# Пример поиска через Elasticsearch
# -------------------------------
def search_es(query_text):
    response = es.search(
        index=index_name,
        body={
            "query": {
                "multi_match": {
                    "query": query_text,
                    "fields": ["title", "content"]
                }
            }
        }
    )
    for hit in response["hits"]["hits"][:10]:  # первые 10 результатов
        print(f"Title: {hit['_source']['title']}")
        print(f"Category: {hit['_source']['category']}")
        print(f"Published: {hit['_source']['published_at']}")
        print("-"*40)

# Пример поиска
search_es("abc")  # замените на слово, которое хотите искать 

После выполнения видим результат поиска по нашим тестовым данным

Это можно подключить к:

  • фронтенду на React/Vue
  • обычному PHP-сайту
  • CMS
  • интернет-магазину

Почему это лучше обычного SQL-поиска

  • Поддержка морфологии
  • Ранжирование по релевантности
  • Высокая скорость на больших объёмах
  • Масштабируемость

SQL отлично подходит для точных выборок. Но для полнотекстового поиска Elasticsearch даёт гораздо более гибкий результат.

Полезные практические советы

1. Не размещайте Elasticsearch на слабых VDS.

1 ГБ RAM - это минимальный порог для тестов, если RAM будет мало, сервис не запустится и не будет работать

2. Следите за диском.

Elasticsearch активно пишет данные. Когда диск заканчивается, кластер блокирует запись.

3. Делайте снапшоты.

4. Не отключайте защиту

Современные версии включают базовую безопасность по умолчанию

5. Несовместимость версии клиента и сервера

Клиент и сервер должны быть совместимы, поэтому нужно проверять версию сервера перед установкой клиента

logo
© 2022 62yun
Все права защищены
vk.com/62yuncom
support@62yun.ru
logo
vk.com/62yuncom
support@62yun.ru
Услуги
VDS Выделенные серверы
Полезное
F.A.Q О компании Политика конфиденциальности Оферта
Способы оплаты
wechatpay visa mastercard
MirAccept
Партнеры
25port
© 2022 62yun Все права защищены
ВВЕРХ