MAATRIX / Блог / Свой Nominatim: сколько диска, памяти и часов съедает импорт планеты

Свой Nominatim: сколько диска, памяти и часов съедает импорт планеты

MAATRIX

Как только геокодирование адресов в проекте перестаёт быть редкой операцией и превращается в фоновый процесс — импорт клиентской базы, автодополнение адреса в форме заказа, привязка тысяч точек к координатам, — счёт за Google Maps Geocoding API начинает расти вместе с нагрузкой, а не с пользой от неё. Nominatim, открытый геокодер на данных OpenStreetMap, снимает эту зависимость от платы за каждый запрос. Но переход на самостоятельный хостинг меняет статью расходов, а не убирает её: вместо счёта за API вы получаете счёт за диск, время на первичный импорт и постоянную заботу об актуальности данных — и именно это на старте почти всегда недооценивают.

Что такое Nominatim и когда самостоятельный хостинг оправдан

Nominatim — тот самый движок, который отвечает за поиск на openstreetmap.org: он превращает текстовый адрес в координаты (forward geocoding) и координаты обратно в адрес (reverse geocoding), опираясь целиком на данные OpenStreetMap. Это не облачный сервис, а обычный набор компонентов — PostgreSQL с расширением PostGIS, инструмент импорта osm2pgsql и поисковый API поверх базы, — который можно поставить на свой сервер целиком.

Самостоятельный хостинг оправдан, если выполняется хотя бы одно из условий:

  • Объём запросов растёт быстрее бюджета. Массовое геокодирование существующей базы адресов клиентов, регулярный импорт CSV с адресами, автодополнение в форме с высокой посещаемостью — всё это быстро выводит вас за пределы бесплатного лимита платного API.
  • Адреса клиентов — чувствительные данные. Если политика компании (или требования заказчика) запрещает передавать адреса физлиц третьей стороне, у самостоятельного хостинга просто нет альтернативы — вопрос цены здесь вторичен.
  • Оплата зарубежного API — отдельная головная боль. У многих компаний из России сейчас в принципе нет рабочего способа привязать карту к биллинг-аккаунту Google Cloud напрямую, и это уже само по себе аргумент в пользу инфраструктуры, за которую платите так же, как за обычный сервер — картой или криптой.
  • Нужна предсказуемая задержка без сетевого прыжка до чужого дата-центра. Локальный геокодер в том же дата-центре, что и остальной бэкенд, отвечает без внешнего HTTP-запроса к стороннему API.

Если у вас счётное число запросов в месяц и нет требований к приватности данных — сравнение почти наверняка не в пользу собственного хостинга, и честнее остаться на управляемом API. Дальше речь о случаях, где объём или ограничения уже сделали выбор за вас.

Что вы теряете и что приобретаете, отказываясь от Google

С коммерческим API вы платите по счётчику запросов и не думаете об инфраструктуре — Google держит базу актуальной, масштабирует под нагрузку и отвечает за аптайм. Точные тарифы Google Maps Geocoding API стоит смотреть в актуальном прайс-листе на момент принятия решения — они меняются, и приводить здесь цифры бессмысленно: они устареют быстрее, чем вы прочитаете статью. Важнее понимать саму модель — счёт растёт линейно с числом запросов, без верхнего потолка «переплаты», и это именно то, что делает больно на масштабе.

С Nominatim на своём сервере схема переворачивается: платы за отдельный запрос нет вообще — вы платите фиксированную стоимость аренды сервера с диском независимо от того, сто запросов в сутки или сто тысяч, пока укладываетесь в мощность железа. Это выгодно ровно тогда, когда объём запросов уже сделал переменную часть счёта у Google больше, чем стоимость постоянно арендованного сервера с диском под свою копию OpenStreetMap.

Но бесплатным геокодирование не становится — оно становится предоплаченным. Вы платите не за запрос, а вперёд: за объём диска под базу, за время инженера на первичный импорт и настройку, и постоянно — за то, чтобы данные не устаревали. Ниже — то, что чаще всего недооценивают в этом расчёте: диск и время на импорт.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под Nominatim

Диск: где ломается расчёт на старте

Первая развилка — вы геокодируете весь мир или конкретную страну/регион. От неё зависит вообще всё дальше по цепочке.

OpenStreetMap распространяет данные в формате .osm.pbf: полную «планету» — с planet.openstreetmap.org, и региональные вырезки по странам и даже отдельным областям — с download.geofabrik.de. Разница в исходном размере файла между экстрактом одной страны и полной планетой — на порядки, и эта разница напрямую переносится на объём импортированной базы.

Ключевая грабля в том, что база после импорта в PostgreSQL заметно больше исходного PBF-файла. Nominatim строит поверх «сырых» данных OSM собственные индексные таблицы для быстрого текстового и геопространственного поиска — словари названий, иерархию административных единиц, ранжирование результатов. Насколько именно вырастет объём — зависит от плотности застройки региона, выбранного стиля импорта (полный набор тегов или урезанный, только адреса и дороги) и версии Nominatim, поэтому точный множитель приводить не будем — это ориентир, который вам стоит перепроверить на своём экстракте перед тем, как заказывать диск под прод: сначала прогнать импорт на тестовом сервере с запасом места, замерить фактический размер pg_database_size(), и уже от этого числа планировать диск с запасом. Как обычно закладывать этот запас — отдельный разговор, и здесь работают те же принципы, что и для любой базы данных, которая растёт: не впритык, а с понятным горизонтом до следующего апгрейда.

Отдельная деталь для импорта полной планеты — flatnode-file, файл-кеш координат узлов OSM на диске, которым osm2pgsql пользуется вместо того, чтобы держать все координаты в оперативной памяти. Официальная документация Nominatim прямо рекомендует его для полнопланетного импорта, и по факту это ещё один файл на диске сопоставимого порядка с исходными данными — его тоже нужно закладывать в расчёт места, причём на быстром диске: это файл с произвольным доступом, и на медленном хранилище он сам становится узким местом импорта.

Практический вывод: если вам не нужна вся планета — не берите её «на всякий случай». Экстракт одной страны или даже одного региона, покрывающий реальную географию ваших адресов, на порядок дешевле по диску, чем полная планета, и импортируется предсказуемо быстрее. Расширять покрытие можно позже, когда появится реальная потребность, без пересборки всего с нуля.

Импорт: сколько это по времени и от чего это реально зависит

Второе, что недооценивают — не только объём диска, но и время, за которое база вообще соберётся. Официальная установочная документация Nominatim прямым текстом предупреждает: импорт — операция, интенсивная по дисковому вводу-выводу, и на медленном или сетевом хранилище он может растягиваться до величин, при которых проще пересчитать бюджет, чем ждать. Это не тот случай, где стоит экономить на классе диска — NVMe SSD здесь не роскошь, а условие, при котором импорт вообще укладывается в разумные сроки.

Реальное время зависит от комбинации факторов, и приводить конкретные часы для «типового сервера» было бы нечестно — слишком велик разброс:

  • Объём исходных данных — страна или планета, это главный множитель.
  • Класс диска — NVMe против SSD против сетевого блочного хранилища различаются по случайному I/O в разы, а импорт Nominatim именно на случайный доступ и упирается на этапе индексации.
  • Число ядер CPU — osm2pgsql и построение индексов Nominatim умеют использовать параллелизм, линейного масштабирования по ядрам не бывает, но эффект заметный.
  • Настройка PostgreSQL под импортshared_buffers, maintenance_work_mem, временное отключение autovacuum и fsync только на время загрузки (с возвратом к безопасным значениям сразу после) — стандартные рекомендации официальной документации, без них импорт на том же железе может идти заметно дольше.
  • Стиль импорта — полный набор тегов OSM против урезанного (IMPORT_STYLE=address вместо full) уменьшает и объём обрабатываемых данных, и итоговый размер базы, если вам не нужны все атрибуты POI.

Практический ориентир, который стоит держать в голове при планировании: импорт экстракта одной страны на нормальном NVMe-сервере с несколькими ядрами обычно укладывается в часы, а не в дни, а полная планета — это уже многодневная задача даже на сильном железе, и именно поэтому большинство прикладных проектов, которым не нужен весь мир, разумно ограничиваются регионом. Прежде чем закладывать это время в план проекта, прогоните тестовый импорт на реальном экстракте вашего региона — это единственный способ получить число, которому можно доверять.

Установка: рабочий стенд на Docker

Быстрее всего поднять Nominatim через готовый Docker-образ сообщества — он избавляет от ручной сборки osm2pgsql и настройки PostgreSQL с нуля. Пример docker-compose.yml для одной страны/региона:

services:
  nominatim:
    image: mediagis/nominatim:4.5
    restart: always
    ports:
      - "8080:8080"
    environment:
      PBF_URL: https://download.geofabrik.de/europe/russia-latest.osm.pbf
      REPLICATION_URL: https://download.geofabrik.de/europe/russia-updates/
      IMPORT_STYLE: address
      NOMINATIM_PASSWORD: замените-на-свой-пароль
      THREADS: 4
    volumes:
      - nominatim-data:/var/lib/postgresql/14/main
      - nominatim-flatnode:/nominatim/flatnode
    shm_size: 1gb

volumes:
  nominatim-data:
  nominatim-flatnode:

Проверьте актуальный тег образа на Docker Hub перед запуском — версии выходят регулярно, а конкретную стоит зафиксировать явно, не полагаясь на latest. Первый запуск инициирует полный импорт:

docker compose up -d
docker compose logs -f nominatim

Дальше остаётся ждать — прогресс виден в логах по этапам: загрузка через osm2pgsql, построение индексов, расчёт ранжирования. После завершения проверьте API:

curl "http://localhost:8080/search?q=Москва,Тверская+7&format=jsonv2"
curl "http://localhost:8080/reverse?lat=55.7558&lon=37.6173&format=jsonv2"

Если вы разворачиваете Nominatim не через готовый образ, а поверх своего PostgreSQL-сервера (например, чтобы не плодить отдельный инстанс СУБД под каждый сервис) — отталкивайтесь от базовой установки и настройки PostgreSQL на VPS, а поверх уже добавляйте специфичные для Nominatim параметры maintenance_work_mem и shared_buffers, увеличенные на время импорта.

Обновления: геокодер не должен застывать во времени

OpenStreetMap меняется непрерывно — новые дома, переименованные улицы, изменившаяся нумерация. Импортированная один раз база без обновлений медленно расходится с реальностью, и через несколько месяцев начинает не находить то, что давно появилось на карте. Nominatim решает это через репликацию — регулярное применение diff-файлов (минутных, часовых или суточных) с того же сервера, откуда брался исходный экстракт.

Инициализация и разовый прогон обновлений:

nominatim replication --init
nominatim replication --once

Для постоянного фонового обновления есть режим демона (nominatim replication без --once, работающий в цикле) или обычный cron-джоб с периодическим запуском --once — второй вариант проще контролировать и логировать в типовой инсталляции на VPS.

Важный нюанс для раздела про диск: обновления — это не «бесплатная» операция в фоне. Каждое применение diff генерирует WAL-трафик PostgreSQL и может со временем раздувать таблицы и индексы, если autovacuum не успевает за темпом изменений в плотно застроенном регионе. Периодически проверяйте фактический размер базы (\l+ в psql или pg_database_size()), и если он растёт быстрее, чем вы закладывали изначально — это тот самый сигнал, что пора спланировать расширение диска заранее, а не после того, как место закончится в момент импорта очередного diff.

Когда это реально выгоднее, а когда нет

Честный расчёт требует сравнивать не абстрактную «цену геокодирования», а вашу конкретную нагрузку с полной стоимостью владения — включая диск, время на первичный импорт и постоянную работу по поддержанию актуальности.

СценарийЧто обычно выгоднее
Единичные запросы, нерегулярно, без требований к приватностиУправляемый API — содержать сервер ради редких вызовов не окупается
Массовый разовый импорт большой базы адресов (геокодировать раз и сохранить результат)Часто выгоднее арендовать сервер на время задачи, прогнать импорт и геокодирование, затем данные держать у себя
Постоянный поток запросов растущего продукта (автодополнение адреса, логистика)Self-hosted почти всегда выигрывает по предельной стоимости запроса при достаточном объёме
Адреса — персональные данные с требованиями по обработкеSelf-hosted обязателен независимо от цены — вопрос не экономики, а соответствия требованиям
Нужна коммерческая точность и полнота POI за пределами хорошо прорисованных в OSM регионовКоммерческий API может выигрывать по качеству данных, особенно там, где карта OSM неполна

Отдельно стоит учитывать скрытую статью расходов — время инженера. Self-hosted Nominatim не работает по принципу «настроил и забыл»: кто-то должен следить за диском, обновлениями, при необходимости пересобирать индексы после долгого простоя реплики. Если это время некому выделить на регулярной основе, часть «экономии» на API незаметно уходит в часы разбора инцидентов вместо плановой работы.

Нужен сервер под эту задачу?

Разверните VPS MAATRIX за пару минут: NVMe, AMD EPYC, root-доступ, локации UK, США, Франция и РФ. Оплата картой РФ и по СБП.

Арендовать VPS под Nominatim

Нужны сами нейросети для контента?

Генерируйте изображения, видео и озвучку нейросетями на falapi.io — десятки моделей в одном окне. Оплата картой РФ и по СБП.

Частые вопросы

Можно ли развернуть Nominatim только для одной страны, а не для всего мира?

Да, и для большинства прикладных задач это правильный выбор — используйте региональный экстракт с Geofabrik вместо полной планеты, это на порядки меньше по диску и по времени импорта.

Хватит ли обычного VPS с HDD-хранилищем?

Нет, официальная документация прямо предупреждает про чувствительность импорта к случайному I/O — на медленном или сетевом хранилище процесс может растягиваться неприемлемо долго. Берите NVMe SSD, особенно под flatnode-file, если импортируете полную планету.

Что будет, если не настроить обновление данных?

База постепенно расходится с реальной картой — не находятся новые адреса, остаются переименованные улицы. Для прод-использования репликацию нужно настраивать сразу, а не «потом».

Можно ли использовать публичный демо-сервис nominatim.openstreetmap.org вместо своего сервера?

Для разовых ручных проверок — да, но у публичного инстанса действует жёсткая политика использования по частоте запросов, и он явно не предназначен для продакшен-нагрузки стороннего проекта — условия использования стоит проверить актуальные на его странице перед тем, как на него полагаться.

Точность геокодирования Nominatim такая же, как у Google в любой стране?

Нет, качество результата напрямую зависит от того, насколько подробно регион прорисован в OpenStreetMap. В плотно замэппленных городах результат обычно сопоставим, а в регионах с неполной OSM-разметкой Nominatim может не находить то, что найдёт коммерческий сервис с собственной базой адресов.

Что дешевле для разового геокодирования базы в сто тысяч адресов — арендовать сервер на неделю или заплатить за API?

Считайте от объёма: если сто тысяч запросов у вашего текущего тарифа API стоят больше, чем недельная аренда сервера с диском под нужный регион плюс время на импорт и настройку — self-hosted вариант окупается уже на этой разовой задаче, а не только при постоянной нагрузке.

Обсудить статью, задать вопрос или начать новую тему

Есть вопрос по этой статье, идея для обсуждения или просто хотите поделиться опытом? Сообщество MAATRIX ждёт. Для общения, пожалуйста, зарегистрируйтесь в нашем личном кабинете.

Перейти в сообщество →