воскресенье, 4 декабря 2011 г.

Система кеширования для Django ORM

Основные характеристики

  • автоматическое кеширование результата запросов;
  • ручное кеширование результата запросов;
  • автоматическая инвалидация кеша по событию;
  • ручная инвалидация кеша;
  • кеширование результата функции с автоматической инвалидацией;
  • redis в качестве бэкэнда;
  • простота настройки;
Ссылки:

среда, 23 ноября 2011 г.

БЭМ!

От KorWin_SV:

http://bem.github.com/bem-method/pages/beginning/beginning.ru.html

Хотелось бы видеть у нас css именно в таком исполнении, а не каскадным от всея-body до низов.

Наиболее интересный коммент от Johnner:

Статья хорошая (особенно картинки), есть несколько соображений:
  1. БЭМ дает сильную упорядоченность в структуру файлов проекта 
  2. Реализация позволяет легко управлять видом страницы используя серверные шаблоны: по специально сформированному json, клиент строит html (раньше Яндекс использовал xslt, сейчас похоже активно переходят на js-шаблонизаторы). Нужно будет пилить как клиент так и сервер-сайд. 
  3. Одним CSS не отделаемся, придется выделять и строить структуру компонентов используемых на всех страницах (панели, кнопки, табы, формы и т.д), и не совсем понятно, как делать сборку единого css-файла, оторванную от общей технологии БЭМ. 
  4. Для каждой страницы есть контроллер, который смотрит какие компоненты используются на этой странице, строит по этим данными html и подтягивает нужные CSS. 
  5. Не совсем понятно как быть с библиотеками (у нас еще висит Prototype), и как использовать при этом jQuery 
Похоже потребуется глобальная переделка, чтобы воспользоваться этой технологией 

четверг, 3 ноября 2011 г.

Validation::Class - то, что нам нужно!

Господа Perl-разработчики, на CPAN появился замечательный модуль Validation::Class. Прелесть его заключается в его парадигме и хорошей документации:

http://search.cpan.org/~awncorp/Validation-Class-0.110280/lib/Validation/Class.pm

Есть скринкаст, доходчиво объясняющий парадигму этого модуля:

http://b.ana.io/post/12275755157/validation-class-overview-screencast-in-this

Следует внедрить использование этого модуля в нашем перловом коде.
Вопрос про проектирование интерфейса класса
Мне тут недавно приснилось (сам в шоке!), что я хочу к дате прибавлять и отнимать 1 месяц.
Возник интересный вопрос (и тут же пачка следом, привожу в порядке появления)
1) Что будет, если к 3 ноября прибавить 1 месяц? Вроде как 3 декабря.
2) Что будет, если к 28 января прибавить 1 месяц? 28 февраля по идее...
3) Идем дальше, 29 января? Тут есть нюанс ;) Думаю, наилучший выход, если выходим за диапазон дней месяца, ставить 1 число следующего и не париться.
4) Если у нас сложение работает как в п.3, то 29.01, 30.01, 31.01 и 1.02 после прибавления 1 месяца становятся одной датой - 1 марта.
5) А самое интересное начинается при вычитании 1 месяца. Оказывается, что (30.01 + 1 месяц) - 1 месяц = 1 февраля, а (30.01 - 1 месяц) + 1 месяц = 30 января.

Вот такие вот пирожки...

среда, 26 октября 2011 г.

Morgoth - асинхронный драйвер отчетов

В скором времени в бой по линии ПРД пойдет асинхронный драйвер отчетов, разработанный в подпольях техотдела в свободное от работы время.
По просьбе А.М. полное описание перенесено на confluence по адресу https://confluence.rutube.ru/pages/viewpage.action?pageId=6456193
И еще раз, большая просьба задавать вопросы в почту, дабы я смог расширить и углубить знания по описанному, кхм, инструменту, сконцентрированные на жалком клочке экранного пространства в конфе.

вторник, 25 октября 2011 г.

Новая фича в demarshal()

В demarshal() добавлена костыль фича для автоматичекого перекодирования значений свойств в кодировку системы. Для включения у свойства данного функционала, требуется установить атрибут force_encode в карте маршалинга.

За подробностями прошу в http://pod.ezn-dev01.rutube.corp/perldoc/Rutube::Obj::Persistent

пятница, 14 октября 2011 г.

JavaScript++

Вышел новый язык с поддержкой традиционного ООП, и по заявлению разработчиков
поддерживающий возможности Python, Perl, Java/C#, ES4, Harmony, Haskell

Предсказывают борьбу между Google Dart и этим новым чудом.

http://jspp.javascript.am/

четверг, 6 октября 2011 г.

Заметки с highload++


Извините, пока выкладываю без редактирования и комментирования. Может дойдут руки когда нибудь причесать. Если кому будет что-то интересно задавайте наводящие вопросы в комментах, я постараюсь раскрывать темы, если смогу.

3 октября

### Facebook

Mysql tools

1. Для отладки
    - Shadows
    - pmysql
    - Query Comments
    - Общие логи

2. replication

    - better slave prefetch
    - parallel slaves (oracle)


### Design and Implementation Erlang VM

- incremental/concurent garbage collector (BEAM)
- erjang (Stop-The-World GC)

### Почему не стоит использовать MongoDB

1. MapReduce
- медленный
- однопоточный
- BJSON -> JSON - медленно

2. Memory Mapped Files
- плохо если индексы вытесняются из памяти и это не контролируется
- "Дыры" в файлах из-за удаления (физически не удалён до следующей
 дефрагментации). Нужно делать compact коллекции (дефрагментация)

3. Нельзя ограничить достпуной памяти

4. Глобальный write lock
- блокировки при миграции чанков
- во время миграции повисает set_shard_version()
-

5. Оптимизатор запросов
- только один индекс
- выбирает план эмпирически

6. Шардинг
- все шарды равноправны, это плохо, если машинки разные. Хорошо бы задачать
 вес
- нет распределения коллекций

7. Мониторинг
- нет аналогов New Relic RPM
- но есть MMS (MongoDB Monitoring Service)


Удобно использовать когда много мелких udate`ов.

4 октября

### Redis в Stype

1.vbuckets - mapping виртуальных шардов на реальны сервера
2. Распиливание шарда
- фильтрация протоколя репликации
- важно чтобы в командах были ключи по которым можно поределить шард.
-

3. Фильтрация RDB
- RDB добиваются нулями до исходного размера
-

4. Прокси на twisted
- Легко и быстро

5. В Redis используется оптимизации хранения данных.

### Apache Cassandra

1. CAP теорема
- part. tolarance
- availability
- нет consistency

2. NoSQL - много разных

3. Amazone Dynamo
- распределённый hash-map
- get/set
- полная распределённость, нет координатора
- DHT в торрнетах - аналог

4. Архитектура Cassandra
- Token Ring
-

5. Запись
- клиент не знает как распределены ноды
- комманда отправляется на произвольный сервис
- это сервер становится координатором
- далее команда перенапрвляется на нужный сервер
- клиент выбирает критерии успешности (на одну или на все)

5. Чтение
- команда передаётся произвольному серверу
- далее начинаем опрашивать серверы

6. BigTable
` - есть колонки, но они не регламентированы
- есть master, является координатором чтения/запись
- клиент получает от мастера, где взять данные, и сам идёт за ними.
- новые данные сначала memtable, потом сбрасываются в SSTable, к каждой SSTable приделан bloomfilter
- перилдически выполняется SSTable compact

7. Что откуда взяли
- Tocken Ring из касандры
- Хранение из BigTable
- Логическая структура (колонки) из BigTable

8. Распределённая репликация (между ДЦ)
- не понятно

9. Чтение
- Ближайшая реплика - snitch (simple, topology, dinamic)

10. Преимущества
- Очень быстрое чтение
- Легкость администрирования (один деммо

11. Недостаток
- Плохо реализован range scan
-

Thrift - использовать нельзя!!!

handoff - что будет? неконсистенси -
< > по колонкам

### Базы для аналитики (Авсеянко)

- Infobright !!!!!
- InfiniDB ( SQL, но компрессия только в Enterprize)
- MonetDB (Xquery, SQL)
- LicidDB

- C-Store
-
https://jira.rutube.ru/browse/DEV-632

### Одноклассники. Архитектура хранилища бинарных данных

- 1.6 млрд x 4 размер фотографий
- 200 Тбт

1. Было BerkleyDB + Remote Interface
- Всё плохо и медленно


2. Что хочется
- высокое чтение
- отсутствие spof
- резервирование
- гибкое расширение

3. рассматривали
- DFS
- HDFS
- Cassandar и пр

4. Что получилось
- Zookeeper
- Дисковое хранилище

5. Устройство сервера
- Работа с дисками а не с серсверами
- Мелкие файлы хранятся в сегментах, индекс хранится в памяти.
- NIO Server (Mina)

6. Сегменты
- Всегда одинаковые
- Место резервируется
- На одном диске запись всегда в один сегмент
- Данные в сегменте иногда пережимаются
- данные в памяти и на диске один-в-один

7. Индекс
- Собственная реализация
- Сбрасывается на диск
- Между снапшотами бинарный лог

8. Как работает?
- Уникальный ИД диска
- Фактор репликации 3, по разным дискам и серверам
- При записи используется "кворум"\
- Чтение 1 + 1 (на всякий случая идём на второй, есл ина первом нетЗ)

9. Маршрутизация
- Таблица с регионами
- даёт возможность не двигать данные


10. Zookeeper
- Хряняться IP серверов и ID дисков
- Хранится таблица маршрутизации
- Распределённая блокировка, при изменении таблицы маршрутизации


Александр Христофоров (odnoklassniki.ru/ah)

### CLodo

1. Ресурсы облака
- Load balance cluster
- Dynamic content cluster
- Database
- Cloud Storage (cache)
- Cloud Stojrage (storage)

2. Цели хранилища
- Надёжно хранить
- Удобно управлять, в том числе API
- ...

3. Выбран Swift
-

4. Перед swift поставили патченный nginx

- Что я должен сделать если хочу отдать файлы по FMS?
- А как устроен билинг в купе с кешированием?
- Как устроена инвалидация кеша на nginx?


5. Инвалидацию кеша nginx осуществляет перловый демон "Кеша".

SQL Shard + sphinx = NoSQL Fuck Off


Такой подход всё чаще встречается в описание систем.


Шардинг MySQL на Yii Framework / Yii — php-фреймворк / Хабрахабр

Sphinx — не только для поиска!

среда, 28 сентября 2011 г.

Управление тикетами Jira из Svn

Описание системы команд, помещая которые в комментарии коммитов, можно управлять состоянием тикетов Jira. ИМХО, очень удобно!

http://confluence.atlassian.com/display/JIRASTUDIO/Actioning+Issues+via+Commit+Messages

Ура, Fisheye!

понедельник, 19 сентября 2011 г.

Merge со скоростью мысли

Если не знакомы с тулзой svnmerge, очень рекомендую познакомиться. Она позволяет получать удовольствие от сихронизаций и мержей. Незаменимый помощник любого релиз-менеджера, работающего с svn. ;)
Идёт в стандартной комплектации любой современно сборки svn. Но может быть в отдельном пакете в зависимости от дистрибутива.

http://www.orcaware.com/svn/wiki/Svnmerge.py

пятница, 2 сентября 2011 г.

Django Custom Fields: сквозь тернии к звездам

В процесс фикса одного бага выяснилась интересная вещь, хочу вот поделиться...
Как написано
В официальной документации написано, что если вдруг захочется создать кастомное поле, необходимо сделать следующие шаги:
1) создать класс CustomObject(object), представляющего значение этого поля
2) создать класс поля CustomField(django.db.models.Field)
3) определить в классе поля метод to_python(), который из значения, полученного из БД или из пользовательского ввода, конструирует тот самый CustomObject
4) определить в классе поля метод get_prep_value(), противоположный по функции методу to_python()
И все, но этого мало.
Как надо
Во-первых, CustomField может получить на вход to_python строковое представление объекта CustomObject, т.е. результат вызова CustomObject.__unicode__() - который, по умолчанию, выведет только полное имя типа объекта.
Во-вторых, django при попытке сохранения модели проверяет, изменились ли значения ее полей. На практике, происходит сжатие методом zip значения этого поля (мы еще помним, что значением CustomField является CustomObject?). Метод zip требует наличия у сжимаемого объекта итератора, в придачу к которому нужен еще и метод len().
Ну и факультативно...
Если итератор для объекта "ходит" по его текстовому представлению, то стоит его закэшировать и обновлять при изменении полей CustomObject, участвующих в создании текстового представления. Для этого поля объекта превращаем в свойства, в сеттерах которых выполняем обновление текстового представления.

вторник, 30 августа 2011 г.

Оптимизация сайта (RLib)

С недавним обновлением RLib был оптимизирован поиск служебных классов "rload_controllers" во всех элементах страницы.
Приведу немножко статистики и результаты профилирования.
Чуть раньше поиск спец. классов "rload_controllers" выполнялось через проход по словарю известных rload_классов и поиском совпадений в DOM-е через jQuery('.rload_somecontroller') для каждого элемента словаря. Десятки раз вызывалась функция-обертка jQuery() и десятки тысяч jQuery.hasClass().
По результатам профилирования в Firebug на главной странице боевой rutube.ru, среднее число вызовов всех функций на сайте составляло 120-130 тыс. и среднее время выполнения скриптов 1.1-1.2 секунды.
После рефакторинга RLib в части метода dynamicLoad (в котором производится основная часть проходов по DOM), цикл проходов по словарю был заменен одни проходом по DOM посредством метода document.getElementsByTagName('*') и сравнением классов каждого элемента с элементами rload-словаря.
По результатам профилирования в бою, число вызовов функций составило 60-70 тыс.и время выполнения 470-550 мс.
Таким образом:
- суммарное число вызовов функции hasClass() сейчас 20-40 тыс вызовов, время работы 30-60мс;
- суммарное время функции dynamicLoad = 70-80мс.

У меня появилась идейка как можно еще больше оптимизировать это достаточно узкое место.
Например, если вынести спец. метки контроллеров в верстке (rload_controllers) из атрибута class в специальный атрибут например data-rload, тогда можно будет в одном проходе по всем элементам сразу ловить метки для подгрузки контроллеров, и избавиться от вызовов достаточно медленной функции hasClass в этом критичном месте.
Так как doctype документа XHTML, это не противоречит стандарту.
Плюсы:
1) избавляемся от вызовов hasClass и выигрывает 20-40 тысяч вызовов, и соответственно время загрузки.
2) перестаем быть сильно чувствительны к разрастанию DOM, т.к. сейчас чем больше элементов на странице, тем больше вызовов достаточно медленной hasClass()
Я подготовил тест производительности, который подтверждает что реализация с getAttribute() почти в 20 раз быстрее hasClass() который реализован у нас сейчас: http://jsperf.com/getattrvshasclass

Чем грозит:
1) переделка всех шаблонов, где подключение контроллеров выполняется в атрибутах class="" и страшный мердж в svn :)
2) соглашение в дальнейшем подключать js-контроллеры через атрибут data-rload

Скорее всего выигрыш составит не больше 80-100 мс, но так по крупицам сможем суммарно увеличить время загрузки.
Коллеги, интересно ваше мнение по этому поводу.

Вывод XML на сайте.


У базового приложения в сайте появился метод output_xml(). Enjoy!

пятница, 12 августа 2011 г.

Интерфейс балансера

  1. В транке появился клиент балансера - Rutube::VideoBalancer2. Из полезного функционала на текущий момент позволяет выполнять RPC-вызовы API балансера.
  2. После короткого обсжудения, пакет RPC::XML принят дефакто стандартом для использования в перловом коде. С его помощью можно создавать как клиентов, так и серверы XML-RPC.

среда, 10 августа 2011 г.

Думай, прежде чем начнёшь программировать!

Очень кстати под руку подвернулась старая статья

Before coding… Think! | Making Good Software

Если кратко, то она раскрывает смысл известной пословицы "Одна голова хорошо, а две лучше!". Но советую прочитать целиком, так как вся соль в деталях.

Всем хорошего дня.

понедельник, 8 августа 2011 г.

Бессмертная статья Кента Бека

Сегодня снова увидел а своём ридере и с удовольствием перечитал. Великолепный конспект!

Учись Работать / Иллюстрированный конспект лекции Кента Бека «Четыре стратегии отзывчивого дизайна» (с комментариями)

Версионная миграция cron-таблиц и БД

Коллеги, я накидал пару описаний

Версионная миграция cron-таблиц

Версионная миграция БД

и создал соотвествующие структуры в SVN в транке.

Это очень сырой вариант процедур, но мы их начнём обкатывать  на DRM и ПРД. Очень надеюсь, что все примут активное участие в их улучшении.

Лёша Л. тебе нужно это внедрить в свой процесс релиз менеджмента и возможно автоматизировать рутинные операции.

Прошу конкретные замечания и предложения кидать в конфлюенс. А флудить лучше в блог.

среда, 3 августа 2011 г.

Баг с memcached

Всем хеллоу!

    Во время тестирования trackinfo обнаружили баг связанный с тем что обрывается соединение с сервером. Причина, предположительно, модуль Cache::Memcached::Fast считает что во время первого соединения произошла ошибка и лочит сервер на failure_timeout секунд. Лочить или нет устанавливает свойство max_failures.  Эта ошибка воспроизводится только во время работы в окружении fastcgi. Сейчас из конфига мемкешей убрали опцию


max_failures (если это значение не указано либа ставит его в 0). 

К сожалению у этой библиотеки нет debug режима =(. Ещё одно замечание, если поменять базовый класс в Rutube::Memcached c Cache::Memcached::Fast на Cache::Memcached то всё отлично! WTF? Oo

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

Воспроизвести подобное поведение в скрипте не удалось =(

use Perl or die(); гы-гы =)

вторник, 2 августа 2011 г.

Атомарная операция test-and-set на мемкеше

Из доки на мемкеш-клиент:
  # Do atomic test-and-set operations.   my $cas_val = $memd->gets('nkey');   $$cas_val[1] = 0 if $$cas_val[1] == 12;   if ($memd->cas('nkey', @$cas_val)) {       print "OK, value updated\n";   } else {       print "Update failed, probably another client"           . " has updated the value\n";   }

Баг ОРМ'а

Вкратце, баг касается переиспользования объекта, созданного с использованием параметра obj_new =1. Актуально при маппинге на таблицы с первичным ключом без auto_inctement. В этом случае после использования $obj->save(), значение ключа "убивается" и $obj->getID() выдает значение 0. Соответственно, при следующей попытке сохранения, в базе создается новая запись, соответствующая данному значению ключа (id=0), вместо ожидаемого апдейта существующей.

Ниже приведен пример, позволяющий убедиться в данной неприятности.

1) Таблица в БД:

CREATE TABLE `test` (
`id` int(11) NOT NULL,
`some_value` varchar(255),
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=koi8r;

2) ОРМ:

package Rutube::Obj::Test;

use warnings;
use strict;

use Rutube::Object;
use base qw[Rutube::Object];


mapper( '-table' => 'test', '-key' => 'id' );
set_property_type('db');

property('id');
property('some_value');


1;

__END__

3) Тестовый скрипт:

#!/usr/bin/perl -w

use strict;
use warnings;

use lib qw|../lib|;
use Rutube::Config;
use Rutube::ObjectRegistry;

use Rutube::Obj::Track;

my $conf = Rutube::Config->new('../conf/.config');
Rutube::ObjectRegistry->setNamespace('offline');

use Rutube::Obj::Test;

my $obj = Rutube::Obj::Test->new({id => 123, some_value => 'asdf'}, {obj_new => 1});
printf "[id=%3d|some_value=%s]\n", $obj->getID(), $obj->getSomeValue();
# [id=123|some_value=asdf]

$obj->save();
printf "[id=%3d|some_value=%s]\n", $obj->getID(), $obj->getSomeValue();
# [id= 0|some_value=asdf]

$obj->setSomeValue("qwerty");
$obj->save();
printf "[id=%3d|some_value=%s]\n", $obj->getID(), $obj->getSomeValue();
# [id= 0|some_value=qwerty]

exit 1;

4) Имеем в результате:

idsome_value
0qwerty
123asdf

воскресенье, 31 июля 2011 г.

Modern Perl

Кто ещё не читал, рекомендую просмотреть книгу

http://www.onyxneon.com/books/modern_perl/index.html

Там нет ничего особенного, но кратко описываются современные тенденции и накопленная мудрость в Perl. Распространяется под лицензией creative.

У книги есть блог

http://www.modernperlbooks.com/mt/index.html

вторник, 12 июля 2011 г.

FileHeap

Коллеги, я начал описывать некую штуку под названием FileHeap, призванную стать заменой FileCluster. Многим я уже показывал наброски и со многими обсуждал. С кем не успел, прошу сюда

FileHeap

Эта страничка в ближайшие дни будет активно наполняться (надеюсь, с вашей помощью), так что кому интересно, могут подписаться на обновления. Прошу всю свою критику, пожелания, мысли и идеи вываливать в комменты на эту страницу.

История компьютеров в фотографиях

Если вдруг на работе станет скучно, можно поднять себе настроение, прочитав статью http://www.3dnews.ru/offsyanka/613751/ про Немецкий Технический Музей и, в частности, выставку, посвященную истории развития компьютеров.

пятница, 8 июля 2011 г.

CITForum

На всякий случай, для тех кто ещё не знаком с этим ресурсом


http://citforum.ru/


Огромное, хорошо структурированное, постоянно пополняющееся хранилище качественной информации по различным отраслям IT.

вторник, 5 июля 2011 г.

Для затравки про зависимости и слои в сайте.

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

Слои сайта и зависимости между ними

P.S. Серёга, спасибо за вдохновение, ты буквально стал моей музой! :) Надеюсь после прочтения ты посмотришь критически на архитектуру компонента ACL и связи внутри него. ;)

At the begining ...

Товарищи, друзья, коллеги и просто читатели!

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

Также мы хотим, чтобы любой, кто имеет отношение к разработке РуТьюб мог размещать свои мысли и идеи, обсуждать возникающие проблемы, анносирвовать новые разработки и освещать общественно полезные вещи.

Давайте перестанем рыться в своих песочницах и начнём эффективно использовать коллективный разум. Этот инструмент должен нам помочь в этом. Но главное зависит от нашей инициативы и усилий.