first commit

This commit is contained in:
Sergey Antropoff
2026-10-09 07:08:09 +03:00
commit 4381350286
7 changed files with 973 additions and 0 deletions
+221
View File
@@ -0,0 +1,221 @@
# NebulaGraph 3.8 + Elasticsearch 7 + Studio
## Быстрый запуск
```bash
make verify
make es-health
make ps
```
Первый `make verify` сам создаёт `.env` из `.env.example`, поднимает контейнеры и проводит проверку.
| Команда | Что делает |
| --- | --- |
| `make verify` | Поднимает стек и проверяет регистрацию storage, вход в Elasticsearch, listener, полнотекстовый индекс и поиск `doc-001`. |
| `make es-health` | Показывает состояние кластера Elasticsearch. Ожидается `green` и три узла. |
| `make ps` | Печатает статус контейнеров. `es-certs` в `Exited (0)` значит, что сертификат уже создан. |
Локальный кластер:
| Сервис | Число | Адрес в сети Docker | Порт |
| --- | --- | --- | --- |
| metad | 3 | `172.30.80.11`–`.13` | 9559 |
| storaged | 3 | `172.30.80.21`–`.23` | 9779 |
| graphd | 1 | `172.30.80.31` | 9669 |
| storaged-listener | 1 | `172.30.80.41` | 9789 |
| Elasticsearch 7.17 | 3 | `172.30.80.51`–`.53` | 9200 |
| Nebula Studio 3.10 | 1 | имя `studio` | 7001 |
С хоста опубликованы только `127.0.0.1:9669` (graphd), `127.0.0.1:9200` (Elasticsearch) и `127.0.0.1:7001` (Studio).
Адреса заданы в `.env` и совпадают на macOS, Linux и Windows: контейнеры видят одну сеть `nebula-stack-net`, а не localhost хоста.
## Что нужно
- Docker Engine или Docker Desktop и Docker Compose v2 (`docker compose`).
- Для `make`: macOS, Linux, либо Windows через WSL или Git Bash.
- Память Docker: комфортно от 8 ГБ. В `.env` у каждого узла Elasticsearch куча 512 МБ.
- Место на диске под образы (около 3–4 ГБ).
На Linux перед первым запуском ядро должно разрешать Elasticsearch много memory map:
```bash
sudo sysctl -w vm.max_map_count=262144
echo 'vm.max_map_count=262144' | sudo tee /etc/sysctl.d/99-elasticsearch.conf
sudo sysctl --system
```
На macOS и Windows это настройка виртуальной машины Docker Desktop, обычно уже `262144`. Проверка из любого хоста:
```bash
make check
```
Число в ответе должно быть не меньше `262144`.
## Запуск
```bash
cp .env.example .env # make up сделает это сам
make up
make init # ADD HOSTS и SIGN IN TEXT SERVICE
make verify # listener, индекс и поиск по тестовым вершинам
```
`make verify` включает `make init`. Контейнер `es-certs` после успеха в `make ps` будет `Exited (0)`: сертификат транспортного TLS уже записан в том.
Studio: <http://127.0.0.1:7001>
| Поле | Значение |
| --- | --- |
| Graphd IP | `172.30.80.31` |
| Port | `9669` |
| Username | `root` |
| Password | `nebula` |
Адрес `127.0.0.1` в Studio не подходит: запрос к graphd уходит из контейнера Studio. `172.30.80.31` — адрес graphd в сети Docker. Авторизация NebulaGraph в этом стенде выключена, пароль `nebula` принимает консоль и Studio.
Интерактивная консоль:
```bash
make console
```
Остановить, не удаляя данные: `make down`. Удалить тома: `make clean`.
### Windows без make
В PowerShell из каталога проекта:
```powershell
Copy-Item .env.example .env
docker compose up -d
docker compose --profile ops run --rm --no-deps -e OPS_COMMAND=init ops
docker compose --profile ops run --rm --no-deps -e OPS_COMMAND=verify ops
docker compose --profile ops run --rm --no-deps console
```
### Полезные команды
```bash
make ps
make logs
make es-health
docker compose logs -f storaged-listener
```
Проверка Elasticsearch с хоста (пароль из `.env`):
```bash
curl -u "elastic:NebulaEsLab2026" "http://127.0.0.1:9200/_cluster/health?pretty"
curl -u "elastic:NebulaEsLab2026" "http://127.0.0.1:9200/_cat/indices?v"
```
Если меняли `ELASTIC_PASSWORD` в `.env`, подставьте его.
## Как подключён listener
Полнотекстовый индекс NebulaGraph пишет в Elasticsearch не сам storaged, а отдельный процесс Raft Listener. Это тот же бинарник `nebula-storaged`, но со своим портом и каталогом WAL. В compose у `storaged-listener` свой entrypoint: флаги listener не смешиваются с обычным `nebula-storaged.conf`.
Слушает он `172.30.80.41:9789` (`LISTENER_IP` в `.env`). В кластер хранения через `ADD HOSTS` его не добавляют. Для каждого графового пространства listener регистрируется один раз, все адреса — одним оператором `ADD LISTENER`. Пока `SHOW LISTENER` не покажет `ONLINE` по всем партициям, полнотекстовый индекс не создают.
Учётные данные Elasticsearch глобальные для кластера, не для пространства: один `SIGN IN TEXT SERVICE` на все space. Повторный вход делается после `SIGN OUT TEXT SERVICE`.
`make init` и `make verify` выполняют команды ниже сами и повторяют попытку, пока метаданные и listener не станут готовы. Вручную между `CREATE SPACE`, `CREATE TAG` и индексом нужно подождать одно-два сердцебиения meta (около 20 секунд): иначе пространство или тег ещё не видны.
Пароль в примерах — значение `ELASTIC_PASSWORD` из `.env`. Адреса — значения по умолчанию из `.env.example`.
### 1. Узлы хранения
```ngql
ADD HOSTS
"172.30.80.21":9779,
"172.30.80.22":9779,
"172.30.80.23":9779;
SHOW HOSTS;
```
В `SHOW HOSTS` три строки `ONLINE`. До этой команды контейнеры storaged уже запущены, но метаданные ещё не отдают им партиции. `make ps` может показывать их unhealthy, пока `ADD HOSTS` не пройдёт.
### 2. Elasticsearch
Транспорт между `es01`–`es03` зашифрован общим сертификатом, HTTP оставлен без TLS и закрыт basic-авторизацией. NebulaGraph ходит по HTTP, поэтому в `SIGN IN` схема `HTTP`, пользователь `elastic` и пароль из `.env`.
```ngql
SIGN IN TEXT SERVICE
(172.30.80.51:9200, HTTP, "elastic", "NebulaEsLab2026"),
(172.30.80.52:9200, HTTP, "elastic", "NebulaEsLab2026"),
(172.30.80.53:9200, HTTP, "elastic", "NebulaEsLab2026");
SHOW TEXT SEARCH CLIENTS;
```
Ожидаются три строки `ELASTICSEARCH`. Клиент один на весь кластер. Сброс: `SIGN OUT TEXT SERVICE;`.
### 3. Пространство и listener
```ngql
CREATE SPACE IF NOT EXISTS demo (
partition_num = 12,
replica_factor = 3,
vid_type = FIXED_STRING(64)
);
USE demo;
ADD LISTENER ELASTICSEARCH "172.30.80.41":9789;
SHOW LISTENER;
```
`USE` и `ADD LISTENER` должны быть в одной сессии консоли. `SHOW LISTENER` — тоже после `USE demo`. Для 12 партиций будет 12 строк. Ждите `ONLINE` в каждой. Снять listener с пространства: `REMOVE LISTENER ELASTICSEARCH;`.
### 4. Схема, индекс и данные
```ngql
USE demo;
CREATE TAG IF NOT EXISTS document (
title STRING,
content STRING
);
CREATE FULLTEXT TAG INDEX document_search
ON document(title, content)
ANALYZER = "standard";
SHOW FULLTEXT INDEXES;
```
В NebulaGraph 3.8 у `CREATE FULLTEXT TAG INDEX` нет `IF NOT EXISTS`. Повторный запуск отвечает `Existed!`, `make verify` это учитывает.
```ngql
INSERT VERTEX document(title, content) VALUES
"doc-001":("Kubernetes", "Container orchestration platform"),
"doc-002":("NebulaGraph", "Distributed graph database");
```
Индексация идёт асинхронно через listener. Для уже лежащих в пространстве данных:
```ngql
USE demo;
REBUILD FULLTEXT INDEX;
```
Проверка со стороны NebulaGraph — запрос в Elasticsearch через индекс:
```ngql
USE demo;
LOOKUP ON document
WHERE ES_QUERY(document_search, "Kubernetes")
YIELD id(vertex);
```
В ответе должен быть `doc-001`. Анализатор `standard` приводит слово к нижнему регистру, поэтому в Elasticsearch документ ищется и по `Kubernetes`.
Появление индекса снаружи:
```bash
curl -u "elastic:NebulaEsLab2026" "http://127.0.0.1:9200/_cat/indices?v"
```
## Если адреса другие
Поменяйте подсеть и IP в `.env`, затем `make clean && make up && make verify`. Команды nGQL и поле Graphd IP в Studio берите уже из своего `.env`: listener и `ADD HOSTS` должны указывать те же адреса, что `--local_ip` у контейнеров.
На сервере со свободным диском в `.env` поставьте `ES_DISK_THRESHOLD=true`. Кучу Elasticsearch увеличивают через `ES_JAVA_OPTS`. `ES_MEMORY_LOCK=true` включайте на Linux, где для контейнера разрешён memlock.