Pull to refresh

Comments 21

Лучше быть здоровым и богатым… это я про «у моей организации порядка 100 серверов по 515ГБ ОЗУ». Опыт показывает, что пользователи смотрят достаточно ограниченный набор тайлов из всей карты. Держать все эти гигабайты в памяти — пустая трата последней. По этой причине очень хорошо зарекомендовала себя связка CouchDB + NginX, гибче и масштабируемей придумать что-либо сложно… В CouchDB репликация из коробки.

Карта 22448958 тайла (256х256 px), размер базы в CouchDB 67.2 Гигабайта. Время генерации 10 часов.
Между прочим весьма распространенный формат карт mbtiles работает в СУБД sqlite3, которая, насколько мне известно, вся висит в памяти при работе. У них тоже пустая трата памяти? Память — это быстрый доступ к данным, а также возможность продлить ресурс жесткого диска, который явно будет служить меньше, если постоянно дергать файлы.
Нет, SQLite не висит в памяти. Это обычная дисковая база данных. То есть там можно создать таблицу в памяти, но это опционально и нужно специально запрашивать.
Лет 7 назад я работал с SQLite3 и неприятно для себя обнаружил, что эта субд поднимается из дампа и ПОЛНОСТЬЮ висит в ОЗУ (т.е. объем в памяти = размеру дампа), периодически сбрасывая данные обратно в дамп. Там не было как, например, в PostgreSQL в момент выполнения select обращения к файлам, а в памяти хранятся только индексы. Может я тогда плохо сконфигурировал, может тогда sqlite3 не умел не весь подниматься в память. Точно так же работает Redis. Только оперативки сейчас у меня много, да и no-sql субд работает всегда немного быстрее любых sql-субд за счет отсутствия необходимости поддержки sql синтаксиса.
Я отталкивался от инструментария, который уже применяется в продакшине у моего работодателя. Ничего не имею против CouchDB, но на поддержку еще одной СУБД мой работодатель не был готов. Зато Redis за год на бою показал себя исключительно положительно. И там тоже есть репликация из коробки.
Печально, что никто об этой особенности вслух не говорит (не пишет и пр.).
— об этой особенности всем хорошо известно, именно поэтому никто о ней и не говорит. Например, в распространённом стандарте хранения тайлов MBtiles дедупликация предусмотрена. (это же частичный ответ на вопрос о хранеинии тайлов в базе данных вместо файловой системы)
Это прекрасно, что предусмотрено. Но укажите хоть один ресурс, в котором говорится, что задублированы 60-70-80-90% тайлов? Неужели и это всем известно?
По той ссылке, что я привел:
MBTiles takes advantage of utilities found in SQLite for solving problems like duplicate imagery. Maps that cover large areas of solid color like ocean or empty land can contain thousands of duplicate, redundant tiles.
[...]
At higher zoom levels this could lead to millions of solid blue tiles, all exactly the same. Instead of loading all of those look-alike tiles, MBTiles can reference tile coordinates to raw imagery. Thousands of tile coordinates can be paired to the same raw image drastically reducing the filesize required to serve a map of multiple zoom levels.

Точных цифр я не видел. Но то, что все море можно не хранить, это общеизвестно. А море это много. Например, в OSM принадлежность тайла к морю определяется, используя отдельный файл береговой линии, и если это море, то отдаётся сплошной голубой тайл (упрощённо).

Я думаю просто в большинстве проектов даже не пытаются хранить все тайлы, а генерируют их по мере необходимости, поэтому точных долей дупликатов никто не знает (люди обычно не пытаются зумить на середине океана, если это только не точка (0,0) )
Чтобы узнать точные доли, читайте мою статью :) А если серьезно, то меня поразил масштаб проблемы, о чем я и захотел поделиться с хабра-общественностью. Возможно, мои исследования как-то помогут будущим разработчикам оптимальнее строить свои WMS.
Читал спецификацию MBtiles 1.1, никаких указаний на дедупликацию не заметил.

Где ж они? Ткните пальцем в них, чтобы я знал, куда смотреть.
В спецификации этого нет, потому что ни к чему: это лишь база данных с какой-то структурой. В описании MBTiles на сайте Mapbox написано, что можно применять sql-магию для оптимизации базы. И это делает основной инструмент для преобразования в/из формата: mbutil.
В mbutil довольно странная реализация. Там используется uuid в качестве ключа, дедупликачия только в пределах чанка. В node-mbtiles лучше.
Хм, вы правы, в спецификации нет. А вот в коде есть, в node-mbtiles.

Вкратце: вместо одной таблицы tiles используютя две: map которая маппит координаты в md5 ключ, и images которая хранит тайлы по их md5 от их содержимого. Схема тут.
А для совместимости создаётся view, поэтому можно читать MBtiles файл, даже не догадываясь о дедупликации.
Собственно, я в статье и не отвергал эту технологию. Но выходя за рамки статьи, Вам скажу, что хранение метатайлов в tilecache, с одной стороны решает проблемы маленьких файлов в блочных устройствах, с другой — дедупликация тайлов менее эффективна при объединении нескольких тайлов в метатайл. Да и дупликацию тайлов, наверное, как-то обошли. Можно, конечно, отгородиться от проблем дедупликации и блочных файловых систем убеждением, что в столь мощном и широко-используемом инструменте эти проблемы КАК-ТО решены. Но мне в продакшине еще один черный или серый ящик, честно говоря, не нужен. Вот и разбираюсь как это работает :)
Я несколько не о том, на самом деле. Скорее, о том, что, как правило, рендеринг по запросу экономит еще больше места, потому что тайлы высоких зумов посреди океана никто не смотрит — они, банально, никому не нужны.
Есть такие сервисы, которые выкачивают все подряд. Я писал такие когда-то. Например, в Google, в Яндекс и в Спутнике установлено ограничение по количеству запросов тайлов с одного клиента. Если этого ограничения нет, то рендеринг по запросу наплодит тайлов, в т.ч. и в океане. От этого никакой веб-ресурс не застрахован. Тот же Гугл и Яндекс стабильно «обкачивают» все доступные сайты, чтобы создать быстрые индексы для поиска. Это нормально. А кто-то будет выкачивать все тайлы.
За прошедший период я разобрался с форматом метатайла (на основе мануала по renderd), сам его паковал. Сейчас я могу с уверенностью сказать, что метатайлинг исключает дедупликацию в принципе (о чем я отметил в исправленной версии данной статьи). Поэтому у меня в продакшине крутятся Redis'ы с пре-рендеренными дедуплицированными тайлами (152ГБ), а все остальное перенаправляется lua-скриптом к серверу динамической генерации тайлов: мой lua-скрипт + мой git-клон библиотеки mapnik-c-api + mapnik2.3. Безо всяких apache, mod_tile, renderd и пр. лишних на мой взгляд прослоек. Кэш метатайлов хранится в nginx'e в lua_shared_dict на 10ГБ, что позволяет писать в него и читать из нескольких worker'ов nginx'а. Он также опеспечивает очистку/перезапись данных по алгоритму LRU, что очень удобно, т.к. не нужно заботиться об очистке кэша от неиспользуемых данных.
На клиенте может не найтись нужных программных средств для адекватного рендеринга вектора. Как правило, кроме самого вектора на карте бывает еще куча всяких пользовательских подписей (табличек, значков т.д. и т.п.), нанесенных с учетом взаимного непересечения и прочих условий. При отрисовке на клиенте вся эта красота может «поползти», начиная с того, что у клиента может просто не быть установлен нужный фонт.
Sign up to leave a comment.

Articles