Ноябрь 2008

ATTO vs Areca

atto-stripe.png

Соблазнившись невиданной дешевизной: $217 за 8-портовый SAS RAID controller ATTO R348 приобрел себе такой (увы, помочь с привозом еще таких - не могу). Собственно, помимо дешевизны, преследовались три цели:

  • Отказаться от PCI-X. Еще несколько лет назад выбора не было: PCIe контроллеры отсутствовали, а RAID-контроллер в PCI-слоте - странный выбор. Но требование PCI-X - разорительно, только Asus наладил выпуск приемлемых 'Workstation'-материнских плат, а на серверные процессоры дома я уже не готов.
  • Иметь возможность поставить быстрый SAS-диск (скажем, Savvio 15.2K) на свап/TMP
  • Пишуть, что 1TB SAS-барракуды быстрее SATA на линейном чтении-записи и это хочется попробовать.

Опробованная год назад 3Ware-3650 меня совершенно не порадовала, производительность была так себе. В результате, я вяло обдумывал покупку ARC-1220 (SATA) или ARC-1222 (SAS), 750 баксов было очень жалко, а тут подвернулся deal на ATTO. По $27 за порт было невозможно удержаться.

Поддержка ICC в браузерах

Увидел замечательную страничку, которая позволяет быстро проверить наличие ICC-поддержки в браузере (ну и не только в нем, там и PDF-версия есть)

Is your system ICC Version 4 ready?

Результат ожидаемый: Firefox 3 'ready' (поддерживет и ICC v2 и v4), MS IE7 вообще не в теме.

Надо попробовать картинки для веба в YCC-RGB готовить. Или в GBR. Чтобы неповадно было.

Update В Firefox3 - надо не забыть включить Color Management. А юниксовый - собирать с lcms (виндовый бинарь собран с CMS)

Оптимальная запись в BTree (Живительная сортировка-2)

Интересным следствием из оптимальной записи в BTree является то, что кэш практически перестает быть нужен.

Действительно, нам локально-моментно нужно иметь в кэше по одной странице с каждого уровня дерева плюс место под пару страниц на сплит. Всего получается 4-6 страниц или меньше 50 килобайт для стандартных 8k-страниц.

Эксперименты подтверждают: уменьшение размера кэша с 100 мегабайт до 128k никак не ухудшают производительность. Даже нет смысла приводить результаты замеров, цифры просто такие же (плюс-минус разумный разброс в пару процентов).

Естественно, это относится и к чтению. Если вы собрались читать из BTree (а это не только Berkeley DB, но и большинство индексов в базах данных) много данных и ваше дерево не в памяти - отсортируйте ключи в том же порядке, в котором они в индексе/базе и вам за это воздастся.

Живительная сортировка

Я нижеописанную технику знаю и применяю уже больше восьми лет (с первой "моей" версии Top100), но тут представился прекрасный случай ее побенчмаркать в рафинированном виде.

Задача

Некий код производит записи фиксированной длины:

  • 8-байт ключа
  • 20 байт данных на запись
Эти записи надо сложить в простую базу данных к которой другой код будет доступаться по ключу. Если несколько записей имеют один ключ, то в одну кучку надо сложить все эти записи.

В качестве хранилища используется BerkeleyDB, формат Btree. Исторически сложилось, не обсуждается, впрочем любые базы данных себя поведут примерно одинаково.

Кто виноват

  1. Ключей - много. В моем тестовом примере их 18 миллионов, а вообще может быть несколько сотен миллионов (на бОльшие размеры пока рассчитывать не надо).
  2. Ключ - это хороший хэш от строки, поэтому некий код практически является генератором случайных чисел.
  3. Дублирующих ключей (требующих аппенда записи) относительно мало, около 10%, правда есть ключи-рекордсмены, которые повторяются примерно в 0.3% случаев (60 тыс. повторов на 18M).

В результате, если не делать кэша размером хотя бы с половину базы данных (а делать его разумным, процентов 10-15) и просто писать данные в базу по мере образования, то все происходит довольно медленно: тестовые 18 млн. ключей пишутся в базу на моей тестовой машине около трех часов при размере кэша в 300 мегабайт и базе, дорастающей до 800M. Нет, 1800 транзакций в секунду - это неплохо, но хочется гораздо больше, ибо генерация тестовых данных занимает примерно 3 минуты.

Причина торможения понятна: если ходить в кэш с random-ключом, то вероятность cache hit примерно равна отношению размера кэша к размеру базы. Пока база маленькая - мы попадаем почти всегда, как только перерастаем кэш, так сразу начинаем изучать время HDD seek вместо более полезного занятия.

Решение, впрочем, довольно тривиальное.

safari.oreilly.com

Довольно случайно (разглядывая обложку свежекупленной книжки) обнаружил платный интернет-сервис, который окупился в течение 10 минут:

O'Reilly Safari Books Online

За $10 в месяц или $110 в год (есть и более продвинутые режимы) можно получить полнотекстовый доступ к довольно большой библиотеке (кроме O'Reilly, там еще десяток издательств имеется). В этой библиотеке можно "брать книжки" в ограниченном объеме (за десятку получится 3-5 книг) и читать (и главами скачивать в PDF, объем скачивания еще более ограничен).

За 10 минут я пролистал три книжки, которые лежали в Wishlist на Амазоне и две из них решил не покупать, про третью пока еще думаю (но может оказаться выгоднее скачать PDF-ку). Экономический эффект - примерно $50.

Посмотреть, есть ли нужные книжки в библиотеке можно и на бесплатном аккаунте, там же от них верхушки страниц показываются.

UPDATE В 10-баксовую регистрацию я попал следуюшим способом: Visa eCard от ВТБ24 данный сервис изблевал (не смог пробиллить), но аккаунт создался. При попытке что-то почитать мне предложили таки заплатить - и тут уже появилась 10-баксовая опция с пятью поинтами в месяц. Mastercard Банка Москвы оно сожрало.

noindex-патч для Drupal 6.x, вторая попытка

В духе нового патча для Movable Type сделал новый nofollow-noindex патч для Drupal 6,x

  1. Сначала надо установить новый вариант предыдущего патча: drupal-noindex-patch2.gz
    После его применения, все страницы, для которых включена фильтрация внешних ссылок, будут иметь ссылки замененными на a href="#link" onClick="return URL-ссылки"
  2. Далее в шаблон страницы, где-то ниже текста комментариев (мы же боремся с ссылками в комментариях, правильно) нужно разместить такой вот javascript-код:
    var links = document.getElementsByTagName('A');
    for(var i=0; i < links.length; i++)
    {
       if(links[i].href.match(/\#link/) && typeof links[i].onclick == 'function'){
            links[i].href=links[i].onclick();        
        }
    }

    После этого наступает счастье: пользователи ничего не замечают (ну, кроме тех, у кого выключен Javascript, у тех после каждой ссылки появляется слово [link]), а поисковые машины индексируют только текст ссылки, но не учитывают ее как ссылку. Чего мы и добивались.

noindex-патч для MovableType, 4-я попытка

По совету Николая Сиварева удалось избавиться от главного недостатка моего предыдущего noindex-патча для Movable Type: неудобства при открытии ссылки по правой кнопке.

Правда патч усложнился и теперь состоит из двух частей.

  1. На Movable Type нужно наложить вот этот вот патч: patch-nofollow-img-js2.gz.
    В результате все внешние ссылки получат вид <a href="#link" onClick="return 'http://link-target';">
  2. В темплейт, где-то в районе footer нужно добавить следующий Javascript-код:
     
    var links
  3. ...

читаю тут книжку

In many ways I feel we've gone full-circle. The disciplines needed to extract the maximum from the options avaliable to us with digital capture, are in many ways similar to those of the pioneering days of black and white photography.
David Noton

О сортировке (Ужасы Программирования - 2)

В комментариях к предыдущей записи Влад Шабанов предложил, казалось бы, отличное решение для лексикографической сортировки 8-байтных ключей (функция сравнения для qsort()):

 
#include "sys/endian.h";
int cmp(const void *d1,const void *d2)
{
    uint64_t a1 = be64toh(* (
...

Ужасы программирования

Сортирую записи по 8-байтным ключам в byte order (не в numeric). Записей много (сотни миллионов). Оказывается, сравнивать ключи надо так:

 
    unsigned char *p1 = (unsigned char *)d1;
    unsigned char *p2 = (unsigned char
...

Pages