All streams
Search
Write a publication
Pull to refresh
50
0
Дмитрий @StraNNikk

Python / PHP / JavaScript developer

Send message
Такой вопрос: а при удалении объекта, его версионность теряется? его (удаленный объект) уже более никак не восстановить?
Эх… лучше поздно чем никогда :) наконец-то дошли руки — решил черкнуть пару слов у себя в бложике по поводу прошедшей конференции. По первому дню — посещенные доклады у меня практически совпали с описанными в данной статье, а вот второй день отличается и довольно существенно. Если кому интересно, то вот:
Хранение и доставка контента Вконтакте, NoSQL в Mamba, MySQL в Google
Deploy в Mamba, SPDY в nginx, построение highload-систем в Amazon-е
RabbitMQ плагины, аналитика больших данных в Etsy.com, Percona XtraBackup
MySQL плагины, оптимизация при помощи YSlow, CUBRID
Спасибо за статью — как раз хотелось послушать этот доклад на конференции, но по времени не срослось.
А чем обусловлен выбор ActiveMQ, как промежуточного звена между puppet-ом и базой? В смысле, что рассматривались какие-то другие варианты очередей?
Вот последнее предложение — в рамочку и на стенку… а то некоторые люди поддавшись маркетингу видят в NoSQL решение всех проблем.
P.S. Интересно было бы почитать про Hadoop в более развернутом виде — как вы её используете, how-to, примеры обсчета задач, организация кластера и т.п.
Насколько я понимаю, приведенное в статье решение есть не что иное, как вариация двухфазового коммита. Непонятно о каком ACID идет речь, если Durability (как писали чуть выше) не выполняется при отключенном журналировании. Да и с уровнями изоляций таких вот «транзакций» по моему есть проблемы.
На мой взгляд все эти сложности транзакций Mongo искусственные и притянутые за уши, из-за неправильного использования NoSQL, которое сейчас суют куда ни попадя. Я не отрицаю, что MongoDB это хорошее решение, если схема данных приложения идеально ложится на концепцию слабо связных документов, где в рамках отдельно взятого документа можно хранить достаточно большое количество информации. В этом случае можно отделаться атомарностью update-ов и в принципе не возникнет проблем с транзакциями. Но вот если у вас приложение, которое оперирует с финансами или с другими данными, которые имеют много зависимостей друг от друга и не могут быть представлены в виде единичных документов, то не используйте всякие уродливые хаки NoSQL! Используйте нормальные РСУБД и не парьтесь.
Неправильно выразился. Точнее проблема Phantom Reads при уровне изоляции REPEATABLE READ таки есть, но она не актуальна в случае приведенного в статье примера и не воспроизведется с обычной выборкой через SELECT. А вот в случае SELECT FOR UPDATE очень даже воспроизведется.
Не согласен с автором статьи по следующим пунктам:
При чем внутри транзакции данные тоже будут еще не доступны.
Если рассмотреть транзакцию выше, то первый SELECT ничего не вернет, т.к. таблица у нас еще пустая и транзакция не подтверждена.

делаю:
mysql> SET SESSION tx_isolation='READ-COMMITTED';
Query OK, 0 rows affected (0.00 sec)

mysql> select * from test;
+----+------+
| id | val  |
+----+------+
|  1 |    2 |
+----+------+
1 row in set (0.00 sec)

mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)

mysql> insert into test values (null, 3);
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+----+------+
| id | val  |
+----+------+
|  1 |    2 |
|  2 |    3 |
+----+------+
2 rows in set (0.00 sec)

Внутри транзакции данные доступны в любой момент перед совершением COMMIT. Причем как в READ-COMMTITED, так и в REPEATABLE-READ.
Едем дальше:
Третий REPEATABLE READ
Этот уровень используется по умолчанию в MySQL. Отличается от второго тем, что вновь добавленные данные уже будут доступны внутри транзакции, но не будут доступны до подтверждения извне.
Здесь может возникнуть теоретическая проблема «фантомного чтения». Когда внутри одной транзакции происходит чтение данных, другая транзакция в этот момент вставляет новые данные, а первая транзакция снова читает те-же самые данные.

В MySQL проблема Phantom reads не актуальна. Подробнее см:
stackoverflow.com/questions/5444915/how-to-produce-phantom-reads
forums.mysql.com/read.php?97,189781,189781
dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read
This is the default isolation level for InnoDB. For consistent reads, there is an important difference from the READ COMMITTED isolation level: All consistent reads within the same transaction read the snapshot established by the first read. This convention means that if you issue several plain (nonlocking) SELECT statements within the same transaction, these SELECT statements are consistent also with respect to each other.
Прочитав заголовок сначала было подумал про webpy (http://webpy.org/) — ещё один web-фреймворк со схожим названием
нууу допустим, что даже простецкий VPS с рутовым доступом (где можно настроить все что угодно) стоит не так уж и дорого (за пару евро в месяц) :-) но вообще согласен, что подход, предложенный в статье, имеет право на жизнь… сам использовал нечто подобное в одном своем проекте в прошлом. Правда я не использовал переменные MySQL, а делал SELECT и потом нагонял UPDATE для фиксации задачи воркером, и иногда (особенное при разрастании очереди до 50k задач) воркеры работали вхолостую по несколько раз…
Не, ну в данном случае стоит сразу определиться какая целевая аудитория у приведенного в статье решения. В статье написано, что «при росте нагрузки со временем начинает приводить к проблемам с блокировкой» и мол по этому SELECT FOR UPDATE череват deadlock-ами, и при большом количестве воркеров/тасков не эффективен — это подразумевает, что решение ориентировано на проекты с приличной нагрузкой. Но при таком раскладе люди, занимающиеся такими проектами, обычно не запариваются на тему «чорт побери, у нас shared-хостинг, мы не можем поставить so-шку для rabbitmq/zeromq». Обычно в случаях маломальской нагрузки и сервера-то соответствующие. С другой стороны если на проекте посещаемость — полтора землекопа, то возникает вопрос «а нужна ли очередь?»
Оу, точно, извиняюсь с persistent — упустил этот момент в статье
Сдается мне в данной реализации есть один минус — если использовать mysql_pconnect(), то коннекты к MySQL после создания будут сохраняться в pool-e до следующего вызова, и соответственно вместе с ними будет сохраняться весь «мусор», в том числе и локально установленные переменные. А при большом количестве воркеров может произойти ситуация, когда между операцией UPDATE и инициализацией в коде PHP переменных, установленных в MySQL (аля ID и т.п.), может вклиниться другой процесс и изменить локально установленные переменные.
ИМХО предложенный вариант с использованием сессионных переменными MySQL не True way, лучше уж сделать предварительный SELECT, а потом UPDATE. С другой стороны, в этом случае при большом количестве воркеров схема будет работать вхолостую.
На самом деле про грабли реализации очереди на MySQL писал ещё Котеров, например вот тут: xpoint.ru/forums/computers/dbms/mysql/thread/43203.xhtml Так что лучше использовать специализированные средства, типо rabbitMQ и не извращаться
Даже если у них что-то долго не выходит, сама прелесть в том, что наступает момент, когда они осмысленно или чудом находят решение проблемы.

Вот это прям аццки верно подмечено!
Самый true-way — в settings.py указать другой уровень изоляции транзакций при коннекте к БД, а именно READ COMMITTED
Ммм… по поводу внешних связей — не могу сказать ничего плохого, т.к. багов на этом не ловил и сильно далеко в код Django не вкапывался на эту тему. Лично у меня syncdb при создании базы проставлял верно все внешние ключи. Но если у вас были с этим какие-то трабблы, то было бы интересно послушать.
Второе чтение в последнем блоке try-except происходит только в случае если не удалось прочитать и создать данные, на случай если данные были уже созданы во временном промежутке между первоначальным чтением-созданием. В этом случае второй get будет всегда завершаться эррором, т.к. из-за AUTOCOMMIT=0 и REPEATABLE-READ новые данные не будут считаны из БД.
Ммм… Это принято за аксиому в PEP 249 — Python Database API Specification v2.0:
Commit any pending transaction to the database. Note that if the database supports an auto-commit feature, this must be initially off. An interface method may be provided to turn it back on.

А вот почему — для меня тоже загадка.
С ручным автокоммитом — в смысле с AUTOCOMMIT=1 по умолчанию?
На мой взгляд транзакции нужны далеко не всегда — там где нужны, проще самому взять на себя управлением коммитами/роллбеками, а во всех остальных случаях использовать коммит по-умолчанию. Ошибочных ситуаций будет меньше — на подобии «забыл сделать коммит после какого-то select-а» и т.п.
Но это лишь мое мнение и оно не претендует на истину.
Зачем весь код метода? Doc-тест задается в комментарии. Получить комментарий можно просто:
<?php
class A {
    /**
     * Inline test example
     * @assert (2,2) == 4
     */
     private function _add($a,$b) {
          return $a + $b;
     }
}

$refl    = new ReflectionClass('A');
$comment = $refl->getMethod('_add')->getDocComment();
echo $comment;
Да хотя бы в официальной документации: docs.python.org/library/doctest.html

Information

Rating
Does not participate
Location
Нижний Новгород, Нижегородская обл., Россия
Date of birth
Registered
Activity