Где-то год назад при разработке нашего проекта мы дошли до некой точки развития, когда или начинается кропотливая настройка и оптимизация MySQL-сервера, или начинается опять же кропотливое изучение запросов, которые идут в БД. Так получилось, что именно тогда был бум статей про MongoDB, CouchDB и прочие NoSQL базы данных и соблазн попробовать их на живом проекте был крайне велик.
При выборе главную роль сыграла фраза «CouchDB предназначен именно для веба», а также то, что для доступа не требовались никакие прослойки — доступ осуществляется по любимому мной REST, а API выглядит очень простым и изящным. Вдобавок к этому CouchDB имеет крайне удобный веб-интерфейс для администрирования Futon, чего на тот момент не было у MongoDB, а также железную устойчивость к падениям.
Забегая вперед скажу, что выбор полностью себя оправдал — мы избавились от огромного количества проблем при разработке и проектировании БД, код проекта сильно упростился и стал гораздо лучше структурирован, но самое главное — тот самый поворот в сознании, который нам дал CouchDB. За это время я лично набил множество шишек при разработке и хотел бы поделиться опытом с Хабрасообществом. Эти советы не для начинающих — это советы по использованию CouchDB на живом production.
Во многих пособиях для начинающих (в том числе CouchDB: The Definitive Guide) примеры выглядят очень красиво, но совершенно не сочетаются с жизнью. Суть в том, что как только количество ваших документов перерастает сколько-нибудь реальные масштабы, скажем 100000 документов в БД, разработка temporary views становится практически нереальной, поскольку серверу теперь уже нужно прошерстить все ваши документы на предмет соответствия map-функции. Плюс к этому, каждый map будет содержать что-то в таком роде:
Логика CouchDB такова, что при обновлении одного документа в БД это обновление «затрагивает» все выборки. То есть абсолютно все выборки обновят свои ETag при обновлении всего лишь одного документа. Это еще один минус использования множества документов с различными полями type в одной БД. В то же время обновление одного документа не затрагивает ETag, который будут отдавать другие документы этой БД, поскольку ETag'ами для документов служат их последние ревизии.
Именно репликация считается одним из конкурентных преимуществ CouchDB. Она запускается POST-запросом и может работает в фоне. На живом сервере выснилось, что процесс репликации успешно проходит только в локальной сети. Как только ваши сервера начинают находиться далеко друг от друга, то начинаются совершенно неотлавливаемые глюки, как например: обрыв соединения, невозможность получения изменений и прочее-прочее. При всем этом реплика может выдать сообщение в лог и спокойно делать вид, что все хорошо. Потому совет: реплицируйте данные только в одной локальной сети.
Не изобретайте велосипедов. В документации в качестве примеров reduce-функций часто используются такие вещи:
Этот момент не освещен в документации, однако в ней говорится о том, что если вы не используете reduce-функции, то вполне возможно, вы очень много теряете. Reduce может вызывать саму себя при слишком большой выборке, порождая rereduce. Но в жизни все это теряет смысл как только ваша выборка становится чуть более сложной.
В нашем проекте мы имеем базу comments, в которой храним комментарии. Каждый комментарий находится в отдельном документе, также в этом документе хранится город комментария (у нас российский портал, несколько городов), а также его т.н. принадлежность — поле belongs. Задача заключается в том, чтобы вывести N последних обсуждений. Если говорить языком MySQL, задача сводится к чему-то в таком духе:
Получение данных через связку «If-Modified-Since / ETag» действительно быстрее простого получения данных примерно в 3 раза (синтетические тесты). Не забывайте о том, что когда вы используете заголовки If-None-Match, при статусе ответа 304 тело ответа всегда пустое, поскольку сервер подразумевает, что вы храните данные на своей в стороне. В нашем проекте для этих целей мы используем Memcached с небольшой простой оболочкой для работы с CouchDB (ссылка)
Thinking in CouchDB — отдельная, требующая вникания вещь. Мало написать парсер из %СУБД% в CouchDB, важно действительно привыкнуть мыслить в стиле CouchDB, и тогда все задачи будут восприниматься вами с совершенно иной точки зрения.
Приведу простой пример. Есть события, которые проходят в какой-то промежуток времени. Если нам надо узнать в MySQL, какие события проходят именно сегодня, то мы пишем такой запрос:
Я лишь разбавлю этот псевдожелтый заголовок своим наблюдением 3-летней давности. В свое время мне довелось работать младшим программистом в фирме, штампующей сателлиты. На этих сайтах посещаемость была не больше 30 человек в день, но под каждым из них стоял мощный движок с преобразователем XSL-шаблонов на серверной стороне. Я даже не хочу объяснять, почему это глупо. Общая идея — вы всегда должны выбирать именно то средство, которое наиболее хорошо подходит к решению проблем. В случае саттелитов это простые html-страницы, которые может генерировать ваша CMS; в случае мощных порталов с большой посещаемостью это ни в коем случае не может быть бесплатная Joomla.
Вернемся к заголовку. Не все программисты понимают как работает их код, а особенно как происходит взаимодействие с БД. Зачастую встречаются запросы, в которых есть огромное количество JOIN'ов для выборки простых данных, и даже EXPLAIN не поможет этому человеку определить, какая часть его запроса тормозит, поскольку весь запрос составлен без применения головы. Более того, на живом проекте все сводится к простым выборкам по PRIMARY KEY, все остальные запросы становятся обузой, а знания по составлению сложных SQL-запросов становятся бесполезными.
В настоящий момент я глубоко убежден, что CouchDB позволяет начинающим программистам включать голову и не городить мощнейшие запросы только ради того, чтобы они работали. Удобство reduce-функций позволяет не писать глупые усечения данных, выбрасывая memory overflow. Почти все вещи, которые используются при работе простых сайтов с посещаемостью до 5,000 человек в день, гораздо красивей и проще реализовываются на CouchDB: получение страниц по URL, получение списка новостей, работа с гостевой книгой, фотогалереи и прочее. В то же время единственно возможная используемая кодировка UTF-8 избавит вас от множества вещей, о которых при разработке думать не нужно.
Все текущие действия в CouchDB можно просмотреть. В MacOS утилита для работы с CouchDB называется CouchDBX. Похожая утилита есть и для Windows. Они запускают CouchDB-сервер на порту 5984 и позволяют смотреть текущие запросы к серверу в реальном времени. В Linux достаточно запустить сервер не в режиме демона (за это отвечает параметр -d в /usr/bin/couchdb) и все запросы будут выводиться в консоль.
Также все текущие действия можно смотреть во вкладке «Status» в «Futon».
У каждой вещи есть свои наиболее лучшие методы применения. У CouchDB к этим сторонам точно не относится работа с часто обновляемыми данными. Выборка же данных в CouchDB — это идеал. Почему так происходит? Когда обновляется один документ в БД, то ETag сбрасываются для всех выборок в БД. Это означает, что все они становятся невалидными, устаревшими. Для выборок это означает обновление и обновление их ETag при следующем вызове (т.е. min +1 запрос для всех выборок в БД). На уровне сервера это означает разрастание БД в размерах, с чем придется бороться с помощью операции Compaction.
Каждое обновление документа ведет к созданию его более новой ревизии. Также это ведет к регенерации выборок, в которых участвует этот документ (на регенерацию также влияют операции добавления и удаления документов) при их следующем вызове. Все старые ревизии сохраняются, и далеко не всегда вам необходимо иметь доступ к 600 ревизии документа, в то время как его нынешняя — тысячная. Размер БД растет, а место на сервере не всегда резиновое, поэтому не забывайте выполнять операцию compaction для видов и документов. Это сэкономит массу свободного места на дисках.
До релиза CouchDB версии 1.10 небольшой проблемой была выборка данных из несгенерированных видов. Для этого предлагалось использовать параметр «stale=ok» при выборе вида, а саму регенерацию видов повесить, допустим, в crontab. Начиная с версии 1.10 появился параметр «stale=update_after», который действует так же, как и «stale=ok», однако вызывает обновление вида после его получения. Вместе с простым получением данных вида, мы имеем все возможности для быстрой работы с даже сложными design-документами.
При добавлении вида в design-документ происходит его сборка. Это значит, что все время пока будет собираться вид (скажем, _design/list/_view/by_name), соседние с ним виды (скажем, _design/list/_view/by_age) будут недоступны. Не забывайте про это, когда добавляете вид на production-сервере.
Как многие уже привыкли, мэйнтейнеры Ubuntu/Debian не торопятся обновлять пакеты в репозиториях. Это значит, что в Ubuntu Maverick CouchDB имеет версию 1.0.1, а в Lucid так вообще 0.10, в то время как CouchDB давно включен в список приоритетных проектов Apache и все время развивается. Последняя версия на данный момент (1.10) содержит следующие вещи:
Я говорил о том, что CouchDB подходит для многих задач, но не всех. Полнотекстовый поиск как раз попадает под это исключение. Поскольку мы не можем передать какой-либо параметр прямиком в вид, мы не можем искать что-то точно в БД. Поэтому вы не сможете организовать поиск на сайте, используя CouchDB. Есть различные решения этих проблем, но все это — велосипеды. Скажу честно — это не всегда так плохо: зачастую это позволяет вам понять, что захотят искать ваши посетители. Есть еще один важный момент: на малопосещаемом сайте поиск почти не нужен. А на большом портале поиск должен быть достаточно релевантным, что не позволит вам обойтись простыми LIKE/LOCATE-запросами.
Простым решением данной проблемы является использование Поиска по сайту от Яндекса или Custom Search Engine от Google.
Более сложным и цельным решением этой проблемы может стать использование отдельного поискового сервера. Это может быть Sphinx, Apache Solr, Lucene (есть связка couchdb-lucene, упомянутая в документации). По сути это тема для отдельной статьи, поэтому сейчас заострять внимание на этом не буду.
Помимо этого вы должны четко отделять в голове полнотекстовый поиск и поиск по тэгам, хотя внешне по URL-адресам они похожи.
Еще одной проблемой в CouchDB является геопоиск, например нахождение всех объектов в радиусе N метров. В SQL-подобных БД данная задача реализуется с помощью небольшой функции, которая позволяет по широте и долготе определить расстояние между двумя точками. В CouchDB мы имеем только одну шкалу сортировки в ключах, поэтому найти все точки, попадающие в квадрат — почти невыполнимо. Однако автор CouchDB в твиттере упомянул, что вы можете реализовать геопоиск точно так же, как он реализован в MongoDB, а именно с использованием идеи Geohash. заключается она в том, что любые координаты могут быть представлены в виде численно-буквенного хэша. При этом чем точнее указаны координаты, тем больше будет длина хэша. Таким образом, вы можете передавать геохэш в качестве ключа и варьировать его длину в параметрах startkey/endkey для уточнения радиуса поиска (конечно, это не совсем радиус). Реализаций geohash существует великое множество, вы всегда можете ознакомиться с ними или же написать свою.
Бэкапы данных — одна из вещей в CouchDB, за который его стоит любить. Бэкапы делаются простым копированием файлов БД из директории /var/lib/couchdb. Помните, что копировать файлы можно только при выключенном сервере CouchDB, иначе все ваши файлы БД будут побитыми. Таким образом, общий порядок действий таков:
Не забывайте о том, что все файлы БД и видов должны принадлежать соответствующему пользователю CouchDB, поэтому проверяйте права файлов при копировании и устанавливайте их при необходимости через утилиту chown.
Пост написан хабраюзером 1999 и опубликован по его просьбе.
При выборе главную роль сыграла фраза «CouchDB предназначен именно для веба», а также то, что для доступа не требовались никакие прослойки — доступ осуществляется по любимому мной REST, а API выглядит очень простым и изящным. Вдобавок к этому CouchDB имеет крайне удобный веб-интерфейс для администрирования Futon, чего на тот момент не было у MongoDB, а также железную устойчивость к падениям.
Забегая вперед скажу, что выбор полностью себя оправдал — мы избавились от огромного количества проблем при разработке и проектировании БД, код проекта сильно упростился и стал гораздо лучше структурирован, но самое главное — тот самый поворот в сознании, который нам дал CouchDB. За это время я лично набил множество шишек при разработке и хотел бы поделиться опытом с Хабрасообществом. Эти советы не для начинающих — это советы по использованию CouchDB на живом production.
Используйте больше баз данных
Во многих пособиях для начинающих (в том числе CouchDB: The Definitive Guide) примеры выглядят очень красиво, но совершенно не сочетаются с жизнью. Суть в том, что как только количество ваших документов перерастает сколько-нибудь реальные масштабы, скажем 100000 документов в БД, разработка temporary views становится практически нереальной, поскольку серверу теперь уже нужно прошерстить все ваши документы на предмет соответствия map-функции. Плюс к этому, каждый map будет содержать что-то в таком роде:
function(doc) {
if (doc.type == 'photo') {
...
}
}
что напоминает небольшой велосипед.Логика CouchDB такова, что при обновлении одного документа в БД это обновление «затрагивает» все выборки. То есть абсолютно все выборки обновят свои ETag при обновлении всего лишь одного документа. Это еще один минус использования множества документов с различными полями type в одной БД. В то же время обновление одного документа не затрагивает ETag, который будут отдавать другие документы этой БД, поскольку ETag'ами для документов служат их последние ревизии.
Репликация должна происходить в одной локальной сети
Именно репликация считается одним из конкурентных преимуществ CouchDB. Она запускается POST-запросом и может работает в фоне. На живом сервере выснилось, что процесс репликации успешно проходит только в локальной сети. Как только ваши сервера начинают находиться далеко друг от друга, то начинаются совершенно неотлавливаемые глюки, как например: обрыв соединения, невозможность получения изменений и прочее-прочее. При всем этом реплика может выдать сообщение в лог и спокойно делать вид, что все хорошо. Потому совет: реплицируйте данные только в одной локальной сети.
Используйте нативные reduce-функции на Erlang
Не изобретайте велосипедов. В документации в качестве примеров reduce-функций часто используются такие вещи:
function (key, values, rereduce) {
return sum(values);
}
Старайтесь избегать их и используйте нативные reduce, написанные на Erlang: "_count" и "_sum", которые к тому же работают горадо быстрее своих Javascript-аналогов.Трижды подумайте перед тем как использовать сложные reduce-функции
Этот момент не освещен в документации, однако в ней говорится о том, что если вы не используете reduce-функции, то вполне возможно, вы очень много теряете. Reduce может вызывать саму себя при слишком большой выборке, порождая rereduce. Но в жизни все это теряет смысл как только ваша выборка становится чуть более сложной.
В нашем проекте мы имеем базу comments, в которой храним комментарии. Каждый комментарий находится в отдельном документе, также в этом документе хранится город комментария (у нас российский портал, несколько городов), а также его т.н. принадлежность — поле belongs. Задача заключается в том, чтобы вывести N последних обсуждений. Если говорить языком MySQL, задача сводится к чему-то в таком духе:
SELECT * FROM comments GROUP BY (belongs, city) ORDER BY timestamp
Основная проблема выборки в CouchDB заключается в том, что она сортируется по ключу, а вперед нам необходимо выводить самые новые ветки обсуждений. Значит, группировку через group / group_level мы применить уже не сможем. Вот в этом месте мы и обратились к (re)reduce. Функция усечения выборки в конце выглядела так:function(key, values, rereduce) {
if (rereduce) {
var data = [], meta = [], record, tmp, index, total = [];
for (var i in values) {
for (j=0; j<values[i].length; j++) {
record = values[i][j];
tmp = record[2] + '_' + record[3];
index = meta.indexOf(tmp);
if (index === -1) {
meta.push(tmp);
data.push(record);
} else {
data[index][1] = Math.max(data[index][1], record[1]);
}
}
}
data.sort(function(a, b) {
if (a[1] === b[1]) {
return 0;
}
return (a[1] > b[1])
? -1
: 1;
});
return data.slice(0, 7);
} else {
var output = [];
for (var i in values) {
output.push([values[i]._id, values[i].ts, values[i].belongs, values[i].city]);
}
return output;
}
}
И все работало хорошо, но возникла проблема скорости обновления выборки. После занесения одного комментария, обновление этой выборки занимало 2 секунды на сервере с 4Гб памяти и процессором Athlon 64 X2 5600+ (ссылка). А при постоянном потоке комментариев постоянное провисание БД было недопустимо. Сейчас количество документов в БД — 22,000, в выборке — 258,000. Отсюда вывод: используйте мощные reduce-функции только при мощном сервере. В противном случае вся идея становится бессмысленной.Кэшируйте данные через ETag
Получение данных через связку «If-Modified-Since / ETag» действительно быстрее простого получения данных примерно в 3 раза (синтетические тесты). Не забывайте о том, что когда вы используете заголовки If-None-Match, при статусе ответа 304 тело ответа всегда пустое, поскольку сервер подразумевает, что вы храните данные на своей в стороне. В нашем проекте для этих целей мы используем Memcached с небольшой простой оболочкой для работы с CouchDB (ссылка)
Думайте в стиле CouchDB
Thinking in CouchDB — отдельная, требующая вникания вещь. Мало написать парсер из %СУБД% в CouchDB, важно действительно привыкнуть мыслить в стиле CouchDB, и тогда все задачи будут восприниматься вами с совершенно иной точки зрения.
Приведу простой пример. Есть события, которые проходят в какой-то промежуток времени. Если нам надо узнать в MySQL, какие события проходят именно сегодня, то мы пишем такой запрос:
SELECT * FROM table_name WHERE UNIX_TIMESTAMP() BETWEEN start_timestamp AND finish_timestamp
А теперь вернумся к CouchDB и вспомним о том, что в выборках нет такого понятия как текущее время. Все выборки формируются 1 раз, а в дальнейшем при изменении/создании/удалении документов в них они только обновляются. Соответственно мы имеем только документы и ничего больше. Важно понять, что вы должны составить выборку так, чтобы можно было передать в качестве ключа к ней какой-либо параметр. То есть вы можете только ограничить выборку по ключу. Решением этой задачи является составление выборки, в которой для каждого документа в выборку в качестве ключа попадут все дни, в которые проходит событие. А в дальнейшем чтобы получить все события, проходящие в этот день, вам будет достаточно обратиться к виду с ключом "?key=текущий_день"Почти все, что вы делаете на SQL, реализовывается на CouchDB гораздо проще и красивее
Я лишь разбавлю этот псевдожелтый заголовок своим наблюдением 3-летней давности. В свое время мне довелось работать младшим программистом в фирме, штампующей сателлиты. На этих сайтах посещаемость была не больше 30 человек в день, но под каждым из них стоял мощный движок с преобразователем XSL-шаблонов на серверной стороне. Я даже не хочу объяснять, почему это глупо. Общая идея — вы всегда должны выбирать именно то средство, которое наиболее хорошо подходит к решению проблем. В случае саттелитов это простые html-страницы, которые может генерировать ваша CMS; в случае мощных порталов с большой посещаемостью это ни в коем случае не может быть бесплатная Joomla.
Вернемся к заголовку. Не все программисты понимают как работает их код, а особенно как происходит взаимодействие с БД. Зачастую встречаются запросы, в которых есть огромное количество JOIN'ов для выборки простых данных, и даже EXPLAIN не поможет этому человеку определить, какая часть его запроса тормозит, поскольку весь запрос составлен без применения головы. Более того, на живом проекте все сводится к простым выборкам по PRIMARY KEY, все остальные запросы становятся обузой, а знания по составлению сложных SQL-запросов становятся бесполезными.
В настоящий момент я глубоко убежден, что CouchDB позволяет начинающим программистам включать голову и не городить мощнейшие запросы только ради того, чтобы они работали. Удобство reduce-функций позволяет не писать глупые усечения данных, выбрасывая memory overflow. Почти все вещи, которые используются при работе простых сайтов с посещаемостью до 5,000 человек в день, гораздо красивей и проще реализовываются на CouchDB: получение страниц по URL, получение списка новостей, работа с гостевой книгой, фотогалереи и прочее. В то же время единственно возможная используемая кодировка UTF-8 избавит вас от множества вещей, о которых при разработке думать не нужно.
Используйте утилиты для просмотра текущих действий
Все текущие действия в CouchDB можно просмотреть. В MacOS утилита для работы с CouchDB называется CouchDBX. Похожая утилита есть и для Windows. Они запускают CouchDB-сервер на порту 5984 и позволяют смотреть текущие запросы к серверу в реальном времени. В Linux достаточно запустить сервер не в режиме демона (за это отвечает параметр -d в /usr/bin/couchdb) и все запросы будут выводиться в консоль.
Также все текущие действия можно смотреть во вкладке «Status» в «Futon».
Не используйте CouchDB для часто обновляемых данных
У каждой вещи есть свои наиболее лучшие методы применения. У CouchDB к этим сторонам точно не относится работа с часто обновляемыми данными. Выборка же данных в CouchDB — это идеал. Почему так происходит? Когда обновляется один документ в БД, то ETag сбрасываются для всех выборок в БД. Это означает, что все они становятся невалидными, устаревшими. Для выборок это означает обновление и обновление их ETag при следующем вызове (т.е. min +1 запрос для всех выборок в БД). На уровне сервера это означает разрастание БД в размерах, с чем придется бороться с помощью операции Compaction.
Не забывайте про Compaction
Каждое обновление документа ведет к созданию его более новой ревизии. Также это ведет к регенерации выборок, в которых участвует этот документ (на регенерацию также влияют операции добавления и удаления документов) при их следующем вызове. Все старые ревизии сохраняются, и далеко не всегда вам необходимо иметь доступ к 600 ревизии документа, в то время как его нынешняя — тысячная. Размер БД растет, а место на сервере не всегда резиновое, поэтому не забывайте выполнять операцию compaction для видов и документов. Это сэкономит массу свободного места на дисках.
Регенерация видов. Stale=update_after
До релиза CouchDB версии 1.10 небольшой проблемой была выборка данных из несгенерированных видов. Для этого предлагалось использовать параметр «stale=ok» при выборе вида, а саму регенерацию видов повесить, допустим, в crontab. Начиная с версии 1.10 появился параметр «stale=update_after», который действует так же, как и «stale=ok», однако вызывает обновление вида после его получения. Вместе с простым получением данных вида, мы имеем все возможности для быстрой работы с даже сложными design-документами.
Добавление или изменение вида на продакшн сервере влияет на соседние виды design-документа
При добавлении вида в design-документ происходит его сборка. Это значит, что все время пока будет собираться вид (скажем, _design/list/_view/by_name), соседние с ним виды (скажем, _design/list/_view/by_age) будут недоступны. Не забывайте про это, когда добавляете вид на production-сервере.
Устанавливайте из исходных кодов. Обновляйтесь чаще.
Как многие уже привыкли, мэйнтейнеры Ubuntu/Debian не торопятся обновлять пакеты в репозиториях. Это значит, что в Ubuntu Maverick CouchDB имеет версию 1.0.1, а в Lucid так вообще 0.10, в то время как CouchDB давно включен в список приоритетных проектов Apache и все время развивается. Последняя версия на данный момент (1.10) содержит следующие вещи:
- Нативная поддержка SSL
- Список баз данных наконец-то отсортирован по алфавиту
- Более точная поддержка ETag для видов (в обсуждении говорят, что выборки не будут менять свои ETag при обновлении документов, не входящих в них);
- Поддержка CommonJS модулей в map-функциях (вспоминаем про NodeJS)
- Опция «stale=update_after», которая действует так же, как и «stale=ok», однако вызывает обновление вида после его получения
Полнотекстовый поиск
Я говорил о том, что CouchDB подходит для многих задач, но не всех. Полнотекстовый поиск как раз попадает под это исключение. Поскольку мы не можем передать какой-либо параметр прямиком в вид, мы не можем искать что-то точно в БД. Поэтому вы не сможете организовать поиск на сайте, используя CouchDB. Есть различные решения этих проблем, но все это — велосипеды. Скажу честно — это не всегда так плохо: зачастую это позволяет вам понять, что захотят искать ваши посетители. Есть еще один важный момент: на малопосещаемом сайте поиск почти не нужен. А на большом портале поиск должен быть достаточно релевантным, что не позволит вам обойтись простыми LIKE/LOCATE-запросами.
Простым решением данной проблемы является использование Поиска по сайту от Яндекса или Custom Search Engine от Google.
Более сложным и цельным решением этой проблемы может стать использование отдельного поискового сервера. Это может быть Sphinx, Apache Solr, Lucene (есть связка couchdb-lucene, упомянутая в документации). По сути это тема для отдельной статьи, поэтому сейчас заострять внимание на этом не буду.
Помимо этого вы должны четко отделять в голове полнотекстовый поиск и поиск по тэгам, хотя внешне по URL-адресам они похожи.
Геопоиск
Еще одной проблемой в CouchDB является геопоиск, например нахождение всех объектов в радиусе N метров. В SQL-подобных БД данная задача реализуется с помощью небольшой функции, которая позволяет по широте и долготе определить расстояние между двумя точками. В CouchDB мы имеем только одну шкалу сортировки в ключах, поэтому найти все точки, попадающие в квадрат — почти невыполнимо. Однако автор CouchDB в твиттере упомянул, что вы можете реализовать геопоиск точно так же, как он реализован в MongoDB, а именно с использованием идеи Geohash. заключается она в том, что любые координаты могут быть представлены в виде численно-буквенного хэша. При этом чем точнее указаны координаты, тем больше будет длина хэша. Таким образом, вы можете передавать геохэш в качестве ключа и варьировать его длину в параметрах startkey/endkey для уточнения радиуса поиска (конечно, это не совсем радиус). Реализаций geohash существует великое множество, вы всегда можете ознакомиться с ними или же написать свою.
Бэкапы данных
Бэкапы данных — одна из вещей в CouchDB, за который его стоит любить. Бэкапы делаются простым копированием файлов БД из директории /var/lib/couchdb. Помните, что копировать файлы можно только при выключенном сервере CouchDB, иначе все ваши файлы БД будут побитыми. Таким образом, общий порядок действий таков:
- выключаем CouchDB-сервер
- копируем нужные нам БД
- включаем CouchDB-сервер
Не забывайте о том, что все файлы БД и видов должны принадлежать соответствующему пользователю CouchDB, поэтому проверяйте права файлов при копировании и устанавливайте их при необходимости через утилиту chown.
Пост написан хабраюзером 1999 и опубликован по его просьбе.