68
Как написать масшабируемую баннерокрутилку Бирюков Денис, компания Каванга

как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

  • Upload
    rit2011

  • View
    2.947

  • Download
    1

Embed Size (px)

DESCRIPTION

 

Citation preview

Page 1: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Как написать масшабируемую баннерокрутилку

Бирюков Денис, компания Каванга

Page 2: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Задачи перед сервисом

• Производительность– сейчас: 1000 баннеров/сек.– хотим: 10 000 баннеров/сек.– время отклика < 200 миллисекунд.

• 365*24*7, обязательно отдать контент (хотя бы заглушку).

• Много площадок (>1.000), много баннеров (>100.000).

Page 3: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Задачи (прод.)

• Таргетинги– Стандартные (UserAgent, geo …).– Стандартные ограничения, скорость, бюджет.– Стандартные уникальные ограничения.– Аудиторные таргетинги (ретагетинг: бумеранг,

поисковый, соцдем).

• Точный подсчёт показов, кликов и событий, начислений и списаний денег.

Page 4: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Резюмируем свойства

• Горизонтально масштабируемый (до 10000 хитов/сек). Перекрутов, в идеале, быть не должно.

• Многопоточный (медленные запросы не должны держать быстрые). Минимизировать блокировки.

• Синхронизация серверов в режиме “реального времени” (уменьшаем перекруты).

Page 5: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Схема сервиса в целомПлощадка Клиент Пользователь Пользователь

MySQL

hadoopPHP nginx

uuserver

front front

Se

arch

Se

rve r

sphinx uuserver

hadoop

соцдем

Page 6: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

UUServer

• Кука всего 4 KB – мало. • Очень близко к хранилищу key/value.• Выдача данных по TCP (свой протокол).• Прием данных по UDP (свой протокол).• Масштабируемый.

• Многопоточный (много блокировок).

Page 7: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

UUServer (прод.)

• Внутри 64 независимых дерева - боремся с локами и балансировками дерева при вставке.

• Раз в 5 мин запускается цикл сохранения пользователей на диск.

• Классический ретаргетинг организован плагинами на стороне uuserver.

• Соединения ‘постоянные’.

Page 8: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Схема uuserver

Выбор mapПоиск user

Increment, Update;

UPD пакет (событие)

UPD пакет (событие)

Выбираем очередь

Выбираем очередь

Выбор mapПоиск user

foreach(libs){Retargeting;}

Выбор mapПоиск user

TCP запрос

Анализ

TCP ответMap.insert(…)

Page 9: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Схема frontnginx

fastcgiexp

fastcgiexp

fastcgievent

fastcgievent fastcgidummy

fastcgidummyUUserver

UUserver

SearchServer

receiversender

receiver sender

Syslog

MySQL

Gearman

hadoop

CounterQueue

cache

Page 10: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Cache• Хранит много объектов, если примитивно, то

std::map(u_int64_t, std::vector<...sort...> *). Значение в каждой записи — это табличка из СУБД.

• Объекты — берутся из базы данных (она отвечает за сортировку и за целостность данных).

• Данные в некоторых 'табличках' меняются редко (площадки, рекламные кампании, цены), или очень редко (гео база) — изменения всегда приходят из СУБД.

Page 11: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Cache (прод.)

• Есть 'таблички', данные в которых меняются часто ('счетчики') — изменения приходят как из СУБД так и от CounterQueue.

• Многопоточный (на каждое соединение — свой поток).

• Соединения 'постоянные'.• Блокировки (чтение/запись) накладываются на

всю таблицу.

Page 12: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Cache: логика обновления

TCP запрос Данные из СУБД CacheInOut { u_int32_t size; u_int32_t func; char data[size];}

Анализ ипостроение ‘таблички’

WaitToWrite()

Swap(std::vector<...>*)

Done()Delete old data

Данные из CacheTCP ответ

Page 13: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Cache: выбор баннеров

TCP запрос

TCP ответ

WaitToRead(),…

Done(),…

Find place, geo

Сортировка РК

foreach(PK){Targets;}

result

Page 14: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Cache: инкрементация (2экз)

TCP запрос

TCP ответ

WaitToWrite()

Done()

foreach(…){ Increment; syslog(...);}

Есть 2 экземпляраСчетчиков (Readers-1)Increment(…)

Call Increment(2)

Swap(1,2)

Call Increment(2)

Page 15: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

FastCgiExp• Сервер – и диспетчер и обработчик.• Есть пулы нитей (nginx (fastcgi), cache, uuserver).• В каждом процессе хранятся тела баннеров,

заглушек и ссылок (доступ к ним производиться через read/write блокировку).

• Настройка количества listen сокетов, размеры пулов, количество процессов производится редактированием файла конфигурации, с последующим перезапуском.

Page 16: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

FastCgiExp: запросFastCgi запрос

FastCgi ответ

Выбрать Нить

CheckReferer

Выделить Нить

Get BannerId

Dummy

PoolThread FastCgi

PoolThread UUServer

PoolThread Cache

BannerUDP to UUserver

mq_send(…)mq_send(…)

UDP to SearchServer

Выделить Нить

Get User Info

Page 17: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

FastCgiEvent: запрос

FastCgi запрос

FastCgi ответ

Выбрать Нить

Выделить Нить

Get User Info

Get Location

204

PoolThread FastCgi

PoolThread UUServer

UDP to UUserver

mq_send(…)mq_send(…)

Page 18: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

FastCgiDummy: запрос

FastCgi запрос

FastCgi ответ

Выделить Нить

Dummy

PoolThread FastCgi

UDP to SearchServer

Page 19: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Что дальше?

• Постоянные изменения логики движка (поддержка).

• Написать антинакрутчик (aio).• Переписать UUserver (aio) ?• Мониторинг серверов (zabbix).

Page 20: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Что дальше? (прод.)

• Новые интерфейсы рекламодателям и владельцам площадок (и поддержка и юзабилити).

• Соцдем.

• Новые отчеты (hadoop).

• Мониторинг серверов (zabbix).

Page 21: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Оптимизация трафика

Трафика много, денег мало?

Возможно мало уников

Возможно сейчас у нас нет рекламы для вас (новые форматы)

Возможно вы хотите много денег, или другие таргетинги.

Опрашивайте рекламные движки каскадом

Делитесь информацией о своих юзерах

Page 22: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Тестирование. Машина.Процессор Intel(R) Xeon(R) CPU E5630 @ 2.53GHz (2527.30-MHz K8-

class CPU), 2x4 core

Память 96 GB

nload Incoming:

Curr: 13.65 MBit/s

Avg: 3.93 MBit/s

Min: 1.02 kBit/s

Max: 16.60 MBit/s

Ttl: 402.25 MByte

Outgoing:

Curr: 57.67 MBit/s

Avg: 16.72 MBit/s

Min: 5.52 kBit/s

Max: 66.14 MBit/s

Ttl: 783.21 MByte

netstat 27 LISTEN 625 SYN_SENT

42 CLOSE_WAIT 971 LAST_ACK

42 FIN_WAIT_2 1928 ESTABLISHED

73 CLOSED 23593 TIME_WAIT

Page 23: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Тестирование. Бенчмарк.

3700

3750

3800

3850

3900

3950

4000

4050

кол-во запросов

в сек

одновременные соединения / кол-во

запросов всего

100/10000

100/50000

1000/10000

1000/50000

0

50

100

150

200

250

300

350

400

450

500

50%

66%

75%

80%

90%

95%

98%

99%

100%

доля запросов

микросек

100/10000

100/50000

10000/10000

10000/50000

denis:/home/bdn# /usr/sbin/ab -r -c100 -n10000 -b2048 -C kui1v=777 "http://10.5.1.50/exp?sid=5&bt=5&bn=1&bc=3&ct=2"

Page 24: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Тестирование. TOP.[root@mega ~]# toplast pid: 10965; load averages: 13.32, 6.52, 3.64 up 1+23:47:28 16:18:52646 processes: 8 running, 638 sleepingCPU: 55.2% user, 0.0% nice, 14.3% system, 7.2% interrupt, 23.3% idleMem: 18G Active, 1610M Inact, 11G Wired, 136K Cache, 9833M Buf, 63G FreeSwap: 4096M Total, 4096M Free

Page 25: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Тестирование. TOP.PID UN THR PRI NICE SIZE RES STATE C TIME WCPU COMMAND2583 kbe 54 47 0 220M 147M CPU7 7 21:25 353.47% cache706 root 1 73 0 6956K 1520K RUN 7 4:29 23.39% syslogd10890 www 1 65 0 50268K 36736K RUN 1 1:01 18.46% nginx10891 www 1 67 0 42076K 30064K RUN 1 0:56 18.16% nginx2615 kbe 49 44 0 76784K 22176K nanslp 0 1:42 11.52% fcgiexp2616 kbe 49 44 0 78832K 22268K nanslp 1 1:43 11.43% fcgiexp2617 кbe 49 44 0 82672K 20876K nanslp 0 1:40 11.33% fcgiexp2613 kbe 49 44 0 78704K 21924K nanslp 0 1:43 11.23% fcgiexp2614 kbe 49 44 0 80752K 22112K nanslp 1 1:42 11.04% fcgiexp1557 kbe 170 44 0 18291M 18159M sbwait 5 100:46 3.52% uuserver2609 kbe 3 44 0 28944K 4052K nanslp 0 0:06 1.07% sender2605 kbe 3 44 0 47372K 4232K nanslp 7 0:08 0.98% counterqueue2626 kbe 73 44 0 62856K 22464K nanslp 5 0:16 0.00% fcgievent2639 kbe 73 44 0 62856K 22472K nanslp 3 0:16 0.00% fcgievent1013 root 1 44 0 12064K 4152K select 3 0:02 0.00% sendmail10889 root 1 76 0 17500K 6024K pause 2 0:00 0.00% nginx

Page 26: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Масшабируемая баннерокрутилка: как это былона Erlang

Артем Гавриченков, Highload Lab

Page 27: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Задача

• Выдача ссылок на новости– База из тысяч новостей – Ссылки выбираются произвольно– Распределение – неравномерное

• Форматирование ссылок перед выдачей– Ссылки должны иметь формат блока– Дополнительные поля: идентификатор блока, …

Page 28: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Ta-da!

• Требования: >= 5000 запросов в секунду– Не справляемся – должны быстро выдавать

пустую страницу, чтобы не «ломать» вёрстку– Никакого кэширования

• Срок выполнения: полтора месяца.– При этом у разработчика баннерокрутилки

есть и другие задачи

Page 29: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Схема решения• Структуры в памяти, хранящие новости

и статистику показов

• Множество потоков, обрабатывающих HTTP-запросы

• Контроллер– добавляющий и удаляющий новости

– собирающий статистику

– на основе TCP-сокетов

Page 30: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Схема решенияСтруктуры в памяти, хранящие новостии статистику показов

Множество потоков, обрабатывающих запросы

Контроллердобавляющий и удаляющий новости

собирающий статистику

на основе TCP-сокетов

Page 31: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Erlang• DSL для многопоточных приложений• Встроенные в язык примитивы для посылки и

приёма сообщений• Встроенные в язык шаблоны поведения• Встроенная в язык in-memory БД

Page 32: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Схема решения• Структуры в памяти, хранящие новости

и статистику показов: mnesia/ets/dict!

• Множество потоков, обрабатывающих HTTP-запросы:gen_server!

• Контроллер: gen_tcp!добавляющий и удаляющий новости

собирающий статистику

на основе TCP-сокетов

Page 33: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Схема решения• Структуры в памяти, хранящие новости

и статистику показов: mnesia/ets/dict!

• Множество потоков, обрабатывающих HTTP-запросы:gen_server!– который уже написан за нас! mochiweb/misultin

• Контроллер: gen_tcp!добавляющий и удаляющий новости

собирающий статистику

на основе TCP-сокетовBatteries included

Page 34: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Batteries included, though not all

Page 35: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Костяк решения

• HTTP-сервер Mochiweb получает запрос, создаёт поток

• Поток забирает из Mnesia данные

• Поток производит выборку, сортирует данные, форматирует строки, выдаёт, умирает.Все счастливы.

«In theory, there's no difference between

theory and practice. In practice, there is».L. A. van der Snepscheut.

Page 36: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Факап #1

У каждой новости есть коэффициент важности. В соответствии с этим коэффициентом необходимо выдавать новость чаще или реже остальных.

• Перед выдачей нужно назначать взвешенные произвольные числа каждой новости и делать по ним выборку.

• Новостей много.

Page 37: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Факап #1

• Mnesia построена на основе ETS• http://www.erlang.org/doc/man/ets.html:

«In the current implementation, every object insert and look-up operation results in a copy of the object.»

• Т. е. в копировании сотен новостей из потока в поток. Slow as hell.

Page 38: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Эврика:

• Вместо ETS напишем собственную структуру данных на основе gen_server, dict, queue, blackjack и hookers.

• Повесим её в виде отдельного потока• Будем делать там грубую предвыборку

новостей, которые потом быстро скопируются в рабочий поток

Page 39: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Результат:рост производительности в 3 раза

Вывод:– всегда думай, что копируешь!– профилируй!

Page 40: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Костяк решения v0.2

• HTTP-сервер Mochiweb получает запрос, создаёт поток

• Поток отправляет запрос в gen_server

• gen_server производит предвыборку новостей и присылает результат

• Поток производит выборку, сортирует данные, форматирует строки, выдаёт, умирает.Все счастливы.

Page 41: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Факап #2

Новости – это текст.

Текст – это строки.

• Строки в Erlang – это связные списки символов

• IO в Erlang – это очень медленно

Page 42: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Эврика:

• Если вы пишете на Erlang,то строка символов записывается так:

"Hello world!~n"

• Конкатенация записывается так:

"Hello " ++ Username ++ "!~n"

Page 43: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Эврика:

• Если вы пишете на Erlang веб-приложения,то строка символов записывается так:

<<"Hello world!~n">>

• Конкатенация записывается так:

[<<"Hello ">>, Username, <<"!~n">>]

Page 44: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Почему:

• <<>> – встроенный бинарный тип• <<"">> – бинарная строка• Списки символов нужно обрабатывать

перед выдачей• Вывод бинарных данных – это просто

вызов writev(2)– Blazingly Fast

Page 45: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Почему:

• "Hello" ++ "!\n" => "Hello!\n" => строка– Конкатенация списков – O(n)– Вывод строки => цикл по списку из 7 символов

• [<<"Hello">>, <<"!\n">>] – тип iolist()– Добавление в начало списка – O(1)– Вывод => цикл по списку из 2 элементов– Built-in функциям I/O всё равно, что выводить

Page 46: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Кроме того:

• Строковые операции, наподобие обработки регулярных выражений, всё равно дорогие

• Впрочем, они вообще не очень дешевы.

Надо делать предобработку• Кэширование конструируемых URL новостей

и т. п. позволило отыграть 15%

Page 47: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Результат:рост производительности в 10 (десять) раз

Вывод:– всегда думай, как обрабатывать строки!– профилируй!

Page 48: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Костяк решения v0.3

• HTTP-сервер Mochiweb получает запрос, создаёт поток

• Поток отправляет запрос в gen_server

• gen_server производит предвыборку новостей и присылает результат

• Поток производит выборку, сортирует данные, форматирует iolist()'ы, выдаёт, умирает.

Page 49: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Результат:рост производительности в 10 (десять) раз

Вывод:всегда думай, как обрабатывать строки!профилируй!

Page 50: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Костяк решения v0.4

• HTTP-сервер Misultin получает запрос, создаёт поток

• Поток отправляет запрос в gen_server

• gen_server производит предвыборку новостей и присылает результат

• Поток производит выборку, сортирует данные, форматирует iolist()'ы, выдаёт, умирает.

Page 51: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Misultin

• Реализация gen_server, как и Mochiweb• Интерфейс, аналогичный Mochiweb• Стабильно на 10-15% быстрее

Page 52: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Результат

• Один человекомесяц• Быстрое веб-приложение

# ab -qc 7200 -n 450000 http://localhost/block/35237| grep Requests\ per\ secRequests per second: 7693.35 [#/sec] (mean)#

Page 53: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Killing feature!

Начиная со второй недели разработки (как только был написан каркас), приложение было готово к работе.

• Ни отладки• Ни непредусмотренного поведения• Только фичи и профилирование

Page 54: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Killing feature!

• Ни отладки• Ни непредусмотренного поведения

В Erlang есть концепция «Let it crash».Близкий перевод – «Ну и хрен с ним».

Page 55: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Let it crash

• На обычном языке программирования:

res = web_server.start_link(callback = F)

if res == web_server.port_in_use: raise Exception("Port in use")elif res == web_server.socket_error: raise Exception("Socket error")elif res == errno.EACCES: raise Exception("Not enough privileges")

Page 56: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Let it crash

• На Erlang

{ok, Pid} = misultin:start_link([{loop, F}]).

if res == web_server.port_in_use: raise Exception("Port in use")elif res == web_server.socket_error: raise Exception("Socket error")elif res == errno.EACCES: raise Exception("Not enough privileges")

Page 57: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Let it crash

• На Erlang

{ok, Pid} = misultin:start_link([{loop, F}]).

if res == web_server.port_in_use: raise Exception("Port in use")Not ok? {badmatch, {error, eacces}} raise Exception("Socket error")elif res == errno.EACCES: raise Exception("Not enough privileges")

Page 58: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Результат

• Один человекомесяц

• Быстрое веб-приложение

• Стабильное веб-приложение– eunit и «Let it crash»

• Минимум кода– множество встроенных примитивов и «Let it crash»

• Минимум требуемого опыта

Page 59: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Уровень кодера

• С одной стороны, Erlang учится за 2 недели• С другой стороны, нужно иметь навыки

программирования. Not all batteries included

Page 60: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Напутствие

• Предобрабатывай данные, пока это дёшево!• Не выполняй одни и те же операции дважды!• Используй «Let it crash» в интерфейсах• Профилируй!• Переписывай медленные операции на C,

PHP, OCaml, whatever

Page 61: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Блокировки. (опц.)

pthread_rwlock_t rwlock; // 1pthread_rwlock_rdlock(&rwlock);//pthread_rwlock_wrlock(&rwlock);...do something...pthread_rwlock_unlock(&rwlock);

pthread_mutex_t mtx; // 2pthread_mutex_lock(&mtx);...do something...pthread_mutex_unlock(&mtx);

• Блокировки нужны многопоточным серверам (время отклика клиентам очень отличается от запроса к запросу)

• Возможно вы кроме функции блокировки вызовете еще и планировщик (если поток будет заблокирован)

Page 62: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Блокировки. (прод.) (опц.)

volatile int lock = 0; // 3 (0-unlock, 1-lock)while (__sync_bool_compare_and_swap(&lock, 0, 1)){usleep(10);}...do something...lock = 0;

• Если вы уверенны что блокировки потоков 'ПОЧТИ' не будет — используйте 3-й тип

• Если обработка запроса ВСЕГДА БЫСТРАЯ — а почему не aio?

Page 63: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

SearchServer (java) (опц.)• Поисковые РК: трафика и пользователей нужно

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

• Интересных поисковых фраз много (сейчас пару тысяч).

• Запросов пользователей много – мы примерно 100 пользователей в сек добавляем в различные поисковые аудитории.

Page 64: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

SearchServer (java) (прод.)• Сервер хочется сделать независимым

(манипуляции с ним не должны влиять на основной движок).

• Перебор Regexp.match() перестал работать уже на паре сотен поисковых фраз.

• Хочется учесть семантику русского языка и не заставлять менеджеров вводить все возможные сочетания слов в фразе (стемминг).

Page 65: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

SearchServer: схема (опц.)

Аудитория1

Дом за КАД Дома

Аудитория2

Домашний уют В доме… …

РК2

РК8 РК3

РК5

дом дом… …домашн уютдом кад

{230} {230}… …{389 501}{230 5589}

230 ……

“у дома”дом{230}230UDP: PK2,РК8,РК3,РК5

После стемминга и lowcast

После применения hash

Обратный индекс Пользователь ввел:

Page 66: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Тестирование. Конфиг (опц.)[root@mega /usr/local/kbe]# cat etc/kbe.conf

########################################################################### Counters from different process's come in this queue, and than sended to cache process ###########################################################################

# Maximum messages in system queue, numbercounter_queue_circ_buff_capacity=60000# Name for system queue. path (string) - only small sibols in root foldercounter_queue=/cache_counter_queue# Maximum messages in system queue, numbermax_msg_in_queue=200# Maximum messages in internal queue (if it more, they'll send to cache), numbermax_internal_queuq_len=5# Period time when thread send counters to cache, microsecondstime_for_periodic_counters_send=1000000# Time for limit wait data from system queue, (for reaction on TERM), nanosecondstime_for_max_queue_wait=110000000# Time for limit wait data from read process, (for reaction on TERM), nanosecondstime_for_max_condition_wait=220000000

Page 67: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Тестирование. Конфиг (опц.)# Delay to connect "dead" UUserver (in microseconds)repeat_time_to_uuserver=1000000# Thread count in cache pool, numberthread_count_in_pool_cache=10# Thread count in pool unique user, numberthread_count_in_pool_unique_user_exp=10# Time out for request for wait cache in cache queue, microsecondstime_out_in_pool_cache_queue=200000# Time out for request for wait unique user in unique user queue,in microsecondstime_out_in_pool_unique_user_queue=200000# Number of main fast cgi exposure processfast_cgi_exp_process_number=5# Ports for fastcgiexp, string - divided by ',' ## For main process (check nginx nginx.conf)fast_cgi_1_exp_ports=:9000,:9200,:9201fast_cgi_2_exp_ports=:9040,:9300,:9301fast_cgi_3_exp_ports=:9010,:9400,:9401fast_cgi_4_exp_ports=:9020,:9500,:9501fast_cgi_5_exp_ports=:9030,:9600,:9601# Number of threads processing the request on one socketfast_cgi_exp_concurency_for_port=5

Page 68: как написать масштабируемую баннерокрутилку. денис бирюков, артем гавриченков. зал 3

Тестирование. Конфиг (опц.)# Maximum possible clients connected through Unix socketmax_internal_clients=110# Maximum possible clients connected through TCP socketmax_external_clients=10cache_external_port=1030cache_external_addr=127.0.0.1cache_internal_port=1031cache_internal_addr=/tmp/InternalSocketName

#################################################### Parameters for pool initialised in fastcgidummy ##################################################### Number of main fast cgi exposure processfast_cgi_dummy_process_number=2# Ports for fastcgilight, string - divided by ',' ## For main process (check nginx nginx.conf)fast_cgi_1_dummy_ports=:9010,:9700fast_cgi_2_dummy_ports=:9020,:9800# Number of threads processing the request on one socketfast_cgi_dummy_concurency_for_port=10