Pull to refresh

Comments 49

Я не понял, 36500 добавлений в базу (nosql) положило ее?
Извините, незнаком с особенностями CouchDB
Не добавление положило, и не положило вовсе. После добавления 36500 записей вид (выборка) в базе обновляется, выбирая каждую из 36500 записей в выборку. Обновление выборки не укладывалось в 5 секунд, конкретная база не отвечала, страницы, на которых используются обращения к этой базе (а это 90% страниц сайта) или не открывались, или открывались с существенной задержкой. В итоге — нервотрёпка при выяснении «что происходит и как с этим бороться» плюс потеря пары тысяч уникальных посетителей за день.
Переформулирую: выборка 36500 записей не уложилась в 5 секунд?
Для незнакомых с архитектурой CouchDB, ближайший аналог из мира SQL — обновление индексов при добавлении записи. Представьте себе, что вы создали пару десятков сложных индексов по паре десятков длинных варчар или текст полей, где обычно все поля пустые кроме нескольких. И тут добавили запись, где все поля заполнены данными максимальной длины. И обновление такой записи заняло больше 5 сек.
Так яснее?
С архитектурой CouchDB я действительно не знаком. Но судя по тексту у вас этот «индекс» не по текстовым полям максимальной длины, отсюда и возникающие вопросы.
Ну, во первых, не у меня. Я не имею отношения к автору.
Во-вторых — это аналогия, она, как обычно, хромает, но представление о сути дела — дает.
Вы невнимательно читали пост. «Вид просто не успевал в отведенное ему время обработать документ.». В документе 36500 промежутков, которым нужно было сделать emit, таких документов два. Где-то спотыкалось. После увеличения таймаута всё сработало.
Собственно проблема не в 365к записей (их могло быть и много больше, по 30 штук на каждый нод), а в ноде, который автоматически создается на каждую запись. Собственно я как прочитал про эту систему один день — одна запись, сразу подумал про возможную опечатку, например дата окончания 20012 год.

Мораль: проверяйте входящие значения не только на валидность, но и на «логичность».
Я бы в выводах написал «Не используйте NoSQL ради NoSQL». А то и получается, что в базе, не заточенной на обработку интервалов и времени вцелом, приходится городить костыли, чтобы хоть как-то их поддерживать.
Просто нужно рассматривать возможные workflow и внимательно делать и анализировать тест-кейсы. Подобное могло произойди и не с NoSQL при таком же подходе.
С SQL они бы просто сравнили дату с границами дня, а не вставляли записи на каждый день.
Периодичность + отметка дней недели, например, каждый вторник, каждый четверг, или 3 дня в неделю событие. Уже всё усложняется. Учитывая то, что события бывают ещё не периодичными, а с конкретными датами — всё ещё сильнее усложняется. Поэтому хранение конкретных временных промежутков кажется более удобным в плане организации, на мой взгляд. К тому же в результате на CouchDB всё работает быстрее, чем на MySQL, с которого мы перешли больше года назад.
>> Поэтому хранение конкретных временных промежутков кажется более удобным в плане организации, на мой взгляд.
Лучше сказать проще. Но вы столкнётесь с проблемой когда событие идёт еженедельно в течении 10 лет. Особенно когда таких событий наберётся несколько десятков.

>> К тому же в результате на CouchDB всё работает быстрее, чем на MySQL, с которого мы перешли больше года назад.
Сколько у вас сейчас сумарно записей? И чему равен Update seq?
>>событие идёт еженедельно в течении 10 лет
вы знаете много событий, которые анонсируются на 10 лет вперёд с периодичностью раз/два/… в неделю? Это из области фантастики или совершенно другой предметной области. Мы не анонсируем закаты/рассветы.

>>Сколько у вас сейчас сумарно записей? И чему равен Update seq?
89196 записей. не надо только холивар разводить на тему что быстрее sql или nosql.
Как хотите.
Я просто пытаюсь предотвратить вас от этого.

>> не надо только холивар разводить на тему что быстрее sql или nosql.
Важна не быстрота, а то, что подходит лучше для расчётов. CouchDB не подходит для работы с датами.
Спасибо, читал эту статью, проблемы при удалении документов в CouchDB не пересекается с ситуацией, описанной в посте :)
> Я просто пытаюсь предотвратить вас от этого.

Как я уже писал, там архитектурный был у вас в голове^W приложении. Локи и сессии даже в MySQL то не хранят нормальные люди.
Вы же статью, согласно вашему коментарию, не прочитали. А если бы прочитали, то смогли бы взглянуть на проблему шире. А именно точно такую же ситуацию вы можете получить храня в базе коментарии или записи форума.
К сожалению прочитал до конца. Как такую ситуацию можно получить? Комментарии на форуме не так часто удаляются и изменяются как локи и сессии. Добавляются да, часто, но с добавлением новых документов проблем нет. А вы все так и не поняли, что проблема была в вас?
Да проблема не в удалённых документах, а в том, что когда в B+ дереве около 2 млн. записей, производительность неожиданно начинает сильно хромать на ЛЮБЫЕ операции. Удалённые документы просто дали мне ниточку, чтобы это понять.

>> Как такую ситуацию можно получить?
Когда достигнете нескольких млн. записей не надо будет ничего понимать, просто всё будет дико тормозить.

>> А вы все так и не поняли, что проблема была в вас?
Проблема не во мне, а в том человеке, который начитавших восхваленных отзывов про NoSQL выбрал CouchDB, реализовал приложение, запустил, а потом свалил. А я знаете ли, просто работник аутсорса, который теперь вынужден это поддерживать. И поскольку у нас уже 10000 клиентов, я не имею право вносить координальные изменения в архитектуру, не согласовав это по корпоративной политике заказчика в течении полугода. И вынужден пока поддерживать то, что есть.
Если у вас всегда есть выбор в выборе инструмента и последуйщей его смене, я рад за вас. Желаю вам, что он у вас всегда был.
Я пожалуй спрошу здесь, потому что кому-то это может быть полезно.

В проекте, над которым я работал около трех лет (сейчас с ним работает как раз Makaveli), у нас максимальное количество документов в одной БД — около 112К, видов из них строится достаточно много. Во всяком случае я не совру, если скажу, что есть несколько видов >1М записей в каждом.

Конечно же у нас есть небольшой допинг в виде простой прослойки memcached (https://github.com/1999/couchdb-php), но это разумеется лишь уменьшает количество SELECT-запросов к CouchDB, хоть и радикально. Но я точно помню, что проблем с производительностью выборок у нас не было даже когда количество документов в виде превышало 1М. Другой вопрос — разумеется мы столкнулись с провисанием производительности при INSERT и дальнейшем перестроении выборки при сложном reduce, о чем я написал в своей статье. Но это и логично, страшного в этом ничего не было. Небольшая оптимизация reduce, изменение логики и все встало на места. Во всяком случае потом, когда в нашу БД добавлялся документ и перестраивалась выборка, провисания я никогда не замечал. Ведь в этом же и суть видов CouchDB, что один документ не должен влиять на другие, то есть при внесении одного документа (или же его обновлении), map-функция будет запускаться для него одного.

Если то, о чем вы говорите, правда (кол-во документов >2М затормаживает работу), то о таком бы трубили на каждом шагу, БД была бы попросту не production-ready. Это даже ведь не хайлоад (это немножко не то понятие, но суть понятна). Но вот наш пример — у нас на таких количествах в выборках (не в БД) все было ок. Может быть просто вы говорите несколько о других кейсах? Приведу пару примеров из вашей статьи:

> Порой у нас около 2 млн. обновлений базы (около 1 млн. документов в дереве) и работает вполне сносно, но появляется ещё 100 тысяч, и производительность вылетает в трубу
> Например, вы используете CouchDB, чтобы хранить документы с низкой продолжительностью жизни (сессии, lock-файлы, очереди)
> работая с CouchDB 2 года, я могу сказать, что я до сих пор не знаю, есть ли такая ситуация, где нужно использовать именно CouchDB, а не другие базы.
Мне кажется ваши тесты немного не на ту тему. CouchDB — потрясающе простые выборки и потрясающе медленные (конечно же по сравнению с SELECT) внесения и обновления. Именно поэтому сессии, очереди и пр. — ни в коем случае нельзя хранить в CouchDB. И график из той же статьи — он может возникать, когда происходит массовое обновление документов в БД. Живой пример, который приходит мне в голову — nested sets, которые берут программисты при реализации веток комментариев на SQL. Но при работе в CouchDB занесение одного комментария не должно влиять на другие документы, ведь в этом и суть. Потому в нашем проекте мы написали собственную древовидную структуру, которая работала (и работает) на ура при достаточно большом количестве документов и объеме выборок.

> производительность неожиданно начинает сильно хромать на ЛЮБЫЕ операции
Главный вопрос: вы в этом уверены? Если соотношение выборок к записям составляет 100 и выше, то такого не должно быть.
>>>> производительность неожиданно начинает сильно хромать на ЛЮБЫЕ операции
>> Главный вопрос: вы в этом уверены? Если соотношение выборок к записям составляет 100 и выше, то такого не должно быть.

Да, извините, я имел ввиду на любые операции WRITE. И я в этом уверен, ибо видел резкое затормаживание с 20 мс. до 3 с.

>> Но при работе в CouchDB занесение одного комментария не должно влиять на другие документы, ведь в этом и суть.
На другие не влияет, но дерево может перестраивать.

>> У нас максимальное количество документов в одной БД — около 112К, видов из них строится достаточно много. Во всяком случае я не совру, если скажу, что есть несколько видов >1М записей в каждом.

У меня проблемы начинались с 2.2 млн документов.

>> Если то, о чем вы говорите, правда (кол-во документов >2М затормаживает работу), то о таком бы трубили на каждом шагу, БД была бы попросту не production-ready.

Я понял, что мне придётся на выходных написать синтетический тест, чтобы доказать или опровергнуть свои слова.
Тесты, тесты, ура! :)

Если серьзёзно — если будет возможность — обязательно напишите, очень интересно на результаты взглянуть.
>>что добавлять события будут только пользователи с платным аккаунтом, а они должны быть сознательными.
По моему, это как-то совсем наивно :)
Не очень понял: если выборка отваливается по тайм-ауту, то скрипт должен получить ошибку и обработать ее.
Почему тогда сервер отвечал 504?
В связке nginx->php-fpm->couchdb php-fpm ждал данные из базы, nginx ждал ответ от php-fpm, не дождавшись ответа, nginx выдал 504 Gateway Timeout.
Т.е. в Couch, когда возникает тайм аут обработки запроса, клиент все равно висит и ждет у моря погоды? :)
Да. Также, как когда вы выбираете данные из MySQL, или как когда у вас кэшируются данные в Memcache — клиент ждёт ответа до тайм-аута.
Во-первых, пользователь хотел выставить периодичность «всегда» и поэтому выставил такую дату. Называть его пакостником поспешно.

Во-вторых, проверка введеных данных, которой нет. Т.е. юзер может просто опечатавшись на одну цифру положить систему.

И главное, что я хочу сказать. Почему эти повторяющиеся события нельзя хранить в виде дня недели, например, и временного интервала, засовывать это в ключ и по нему искать?

Мне тоже показалось, что это как-то неправильно так вот хранить события.
Не знаю как у там внутри все устроено, но думаю подобный подход на небольших промежутках вполне имеет право на жизнь.
Во-вторых, проверка введеных данных, которой нет. Т.е. юзер может просто опечатавшись на одну цифру положить систему.</
Рассказал коллегам, представили, посмеялись :)
Добрый день, я к сожалению не до конца помню структуру БД, но суть в том, что события могли быть двух типов:
1. те, которые происходят в определенные дни недели с N1 числ по N1 число
2. вобще точечные, например во вторник, четверг на этой неделе и через 2 месяца еще в среду 4 июня.

Выборка событий необходима по сути за день, то есть в качестве ключа неделю передать — это мало. События не просто периодические и идут сами по себе — они еще имеют дату начала (+ время) и дату окончания (+ время). Поэтому было принято решение создавать документ события с датами его проведения (даты — поле, массив), то есть генерация дат по факту создания документа. Чтобы прояснить: под генерацией дат я имею в виду вид, который обходит документы и emit-ит в итоговую выборку данные с ключами равными дате проведения события.
1. вы неправы, к тому же по тексту было описания ясно, что это было не конкретное событие, а баловство, как раз.

2. Я, в общем-то, указал это в посте, как FAIL.

По событиям вам 1999 ответил.
1. Мне не ясно совершенно. Я привел более реалистичный сценарий, чем членовредительство. То, что пользователь после неудачной попытки решил изменить зачение и попробовать еще раз, ничего не доказывает. Я бы поступил аналогично. Я же не могу знать, что у вас там вселенная при этом встает и рушится.
Вы привели более реалистичный сценарий, имеющий мало общего с тем, что произошло в конкретном случае, ибо всё уже выяснили, но пофантазировать можно, конечно.

>>ничего не доказывает
а ваш пример всё доказывает :)
По второму пункту я ответил, но мимо (ниже). Надеюсь, 1999 прочитает.
Если эмитить ключ вида [day, start_date, end_date], то оба типа событий покрываются. Для точечного события второй и третий элемент ключа будет совпадать, для интервала будет интервал. Если, конечно, уметь использовать startkey/endkey для дат. Про это можно почитать в доках самого кауча.
Чем ваш метод отличается от нашего? Вы передаете тот же day в качестве первого элемента ключа, соответственно смысла в startKey / endKey нет никакого, кроме того, что по нему идет сортировка.

у нас написан вид — ключ эмитится следующего вида:
[город, дата (например 2012/12/12), время_начала]
Соответственно мы и выбираем события по startKey=[городN, дата]&endKey=[городN, дата, {}]
UFO just landed and posted this here
Статья относится к тому, что делать, если вы впервые столкнулись с описанными проблемами в CouchDB, не более.
Ну, сударь, это не «пользователь-пакостник» называется, это называется «на QA сэкономили».
Видимо зря я включил в пост описание действий, приведших к ситуации, видимо никто дальше не читает и не видит, для чего написан пост.
Вот я прочитал весь ваш пост и тем не менее согласен со Slang — «пользователь-пакостник» здесь совершенно неуместен.
А зачем добавлять 365*100 событий? Что мешало добавить одно и в функции map уже эмитить кучу? Насколько я помню, проблем в таких ситуациях не особо много…
Ответ в комментах уже дан, и сделанно именно так, как вы написали — 1 документ события, временные промежутки эмитятся map-функцией.
view генерился на лету? FAIL! в доке где то было написано, что тяжелые view лучше в фоне инициировать.
PHP: история одной аварии
Как-то раз мы решили использовать php в продакшене и вроде все было хорошо. Но однажды на пике посещаемости сайт стал работать очень медленно и почти всегда выдавал 504 ошибку. Мы долго думали, в чем же дело, но нашли в логах заметку о timeout operation. Много гуглили — ничего не нашли. Полезли в конфиг — а там оказывается можно выставлять время выполнения скрипта! Увеличив значение поумолчанию до 600 мы решили проблему и теперь сайт работает. Не повторяйте наши ошибки.

А если серьезно, то не серьезно — раз уж использовали в продакшене, то хотя бы раз в конфиг стоило бы заглянуть и узнать, что там вообще настраивается.
Only those users with full accounts are able to leave comments. Log in, please.

Articles