Pull to refresh

ФИАС с человеческим лицом

Reading time5 min
Views7.3K

Всем привет. Некоторое время назад пришлось разбираться в ФИАСе, хочу поделиться своими наработками. Эта статья расскажет о том как базу развернуть, как её обновлять и как ей пользоваться.

О внутреннем устройстве таблиц ФИАС, будет другая статья.

К счастью мне не пришлось во всём разбираться самому, потому что на Хабре есть хорошая серия статей о ФИАС (Адреса ФИАС в среде PostgreSQL), и у этих статей не менее ценные коменты. На их основе у меня получилось написать скрипты и написать Докер образ, всё опубликовано на ГитХабе.

Спасибо товарищам @gladkov @QuickJoey @amakarov @ploop без вас я бы не справился..

Как работать с образом описано в README.md, здесь я распишу всё тоже самое но более подробно.

Требования

Для работы на базе Linux нужны:

  • docker

  • docker-compose

Для работы на базе Windows нужны:

  • WSL2

  • Docker Desktop

Не менее 200 гигабайт постоянной памяти: 8 + 90 Гигабайт для бэкапа базы ФИАС, и 80 гигабайт на собственно базу (без Земельных участков и без Документов).

200 Гигабайт это минимум, конечно надо иметь в запасе хотя бы 50 Гигабайт, потому что апдейты в разархивированном виде весят по 4 Гигабайта, и конечно надо следить за свободным местом.

Как установить

Что бы развернуть базу надо иметь бэкап этой базы. Идём на сайт ФИАСа и выкачиваем полную базу в формате DBF (8 Гб).

Выбираем директорию для установки базы (в том числе набора скриптов для обслуживания базы), в этой директории разворачиваем гит репозиторий:

git clone https://github.com/SbWereWolf/fias.git

Теперь надо извлечь файлы из архива в директорию ./fias/fs/home/fias/base/, где ./ - это директория в которой мы развернули репозиторий (родительская для fias):

# извлечь файлы из архива
unzip /opt/fias_dbf.zip -d ./fias/fs/home/fias/base/
# удаляем "лишние" файлы
find ./fias/fs/home/fias/base/ -type f -regextype posix-awk \
    -regex ".*\/(STEAD|NORDOC)([0-9]{2}|[0-9]{4})\.DBF$" -exec rm {} \;

Для моего проекта нужны только Здания (HOUSE) и Помещения (ROOM), земельные участки (STEAD) и документы (NORDOC), мне не нужны, поэтому я их удаляю. Если вам в вашем проекте не нужны Помещения, то можно добавить их в маску поиска файлов для удаления: (STEAD|NORDOC|ROOM)

Переходим в директорию приложения

cd fias
# Делаем скрипт install.sh исполняемым и выполняем установку
chmod +x ./install.sh && ./install.sh

Все скрипты будут сделаны исполняемыми, будет создан docker-compose.yml

Открываем docker-compose.yml , изменяем параметры контейнера на свой вкус (можно поменять порт, можно установить пароль для пользователя postgres, можно сделать мапинг скриптов на директорию хостовой машины, что бы менять эти скрипты по ходу дела на свой вкус и тому подобное)

Образ разработан на основе официального, поэтому доступные опции пожалуйста смотрите в документации по ссылке.

Теперь всё готово к сборке образа и запуска контейнера:

# Выполняем сборку и запуск контейнера
bash ./run.sh
# Разворачиваем базу
bash ./deploy.sh

База установлена. Выполнение процесса журналируется в ./docker/run.log и ./docker/deploy.log

Скрипты написаны с условием логина пользователя postgres без пароля, если вы установите пароль, то надо переписать все места запуска psql, убрать ключ -w добавить ключ с указанием пароля.

База развёрнута, можно пользоваться.

Для экономии места можно удалить резервную копию базы: rm -rf ./fs/home/fias/base/* + rm /opt/fias_dbf.zip , экономия от 90+ Гб.

Как пользоваться

Можно пользоваться прямо в контейнере, подключаемся к терминалу:

cd /home/fias/
docker-compose -f ./docker/docker-compose.yml exec fias \
    psql -U postgres -d fias -w

Конечно можно подключиться любым клиентом (любой IDE, любым другим приложением):

Открываем на редактирование ./docker/docker-compose.yml, прописываем внешний порт и пароль пользователя postgres (переменная окружения контейнера POSTGRES_PASSWORD).

В приложении прописываем указанные ранее порт и пароль, пользователь postgres, сервер или 0.0.0.0 или localhost.

Запускаем контейнер: bash ./run.sh

Пользуемся и получаем удовольствие.

Как обновить

Выкачиваем со странички обновлений, архив с обновлениями в формате DBF.

Перед извлечением файлов из архива, чистим директорию обновлений в приложении: rm -rf ./fs/home/fias/update/*

Переходим в директорию репозитория (допустим репозиторий мы развернули в директории /home/): cd /home/fias/

Разворачиваем обновления в директорию репозитория: unzip /opt/fias_delta_dbf.zip -d ./fs/home/fias/update/

Удаляем "лишние" обновления:

find ./fs/home/fias/update/ -type f -regextype posix-awk \
    -regex ".*\/(STEAD|NORDOC)([0-9]{2}|[0-9]{4})\.DBF$" -exec rm {} \;

Запускаем контейнер: bash ./run.sh

Выполняем обновление: bash ./update.sh

Процесс обновления журналируется в файл ./docker/update.log

Have fun.

Производительность

На Pentium Gold + HDD под WSL база работает очень не спеша, разворачивание занимает до 4-х часов, большое обновление занимает до 8 часов.

Разрабатывать в таких условиях конечно не продуктивно, и я попросил у админов машинку пошустрее, мне выделили:

10cpu | 18ram | 400hdd | nfs 10 раид из 16 sas дисков

На такой конфигурации затраты времени терпимые.

Разворачивание базы 1 час, обновление на 40 мегабайт (в архиве) раскатывается за полчаса, обновление на 400 мегабайт (в архиве) раскатывается около часа.

Выполнение построения полного адреса по uuid Здания занимает до 4-х секунд, но надо иметь в виду, что я не строил индексы для ускорения этой задачи, добавлены индексы только для ускорения разворачивания.

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

Хранимые процедуры для работы с базой смотрите в скриптах:

  • ./docker/cmd/deploy/get-address-object-group.sql

  • ./docker/cmd/deploy/get-address-object-name.sql

  • ./docker/cmd/deploy/get-address-object-tree.sql

  • ./docker/cmd/deploy/get-house-name.sql

И конечно читайте первоисточник - Адреса ФИАС в среде PostgreSQ

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

Дополнительно

Некоторые таблицы ФИАС в резервной копии разбиты на два файла, например HOUSE50.DBF и HOUSE5001.DBF, обработка дополнительного файла выполняется в ручную и является костылём, если какие то другие таблицы будут разбиты на два и более файлов, то вам самостоятельно придётся дописать код для импорта этих данных при разворачивании резервной копии.

Это тривиальный код, но кроме вас его ни кто не напишет, для примера:

insert into house50
select *
from house5001;

В целом, весь код лишён гибкости, и при добавлении новых регионов, код для их обработки, придётся дописывать самостоятельно.

Для выполнения VACUUM в СУБД, написан скрипт ./refresh.sh (если вам кажется что скрипты выполняются не адекватно долго, то возможно надо пересчитать статистику таблиц, по которой работает планировщик выполнения запросов, для этого выполняется VACUUM).

Что бы открыть консоль PostgreSQL можно запустить ./terminal.sh

Для ещё большего экономии места, колонки ID и GUID при импорте из DBF подтянутые как varchar(36), можно изменить на uuid, экономия до 5% от размера базы. Я сам не проверял, но в коментах несколько человек это подтвердили.

Tags:
Hubs:
Total votes 9: ↑7 and ↓2+5
Comments6

Articles