Booking.com - популярный сервис по онлайн-бронированию отелей. Поиск отеля, отвечающего заданным характеристикам - это неотъемлемая часть бизнес-модели и основной инструмент для клиента.
При постоянном росте компании вопросу производительности и масштабируемости поиска уделяется много внимания. В результате за время своего существования архитектура поиска претерпела несколько глобальных переделок, начиная от простой базы в MySQL до многокомпонентного распределенного сервиса.
В своей текущей реинкарнации поиск в Booking.com состоит их трех подсистем:
1) сервис auto-complete и устранения неоднозначности (disambiguation) в геопозиции;
2) сервис поиска по отелям и проверки их доступности (availability);
3) система предрасчета цен.
Первые две системы - это высокопроизводительные приложения, написанные на Java. Сервис поиска хранит свои индексы в in-memory хранилище, а данные - во встраиваемой базе данных RocksDB. Логика системы предрасчета цен написана на Perl, а в качестве хранилища используется MySQL.
Приходите на мой доклад, и я расскажу вам, как эволюционировал поиск вместе с ростом компании. Мы подробно рассмотрим текущую архитектуру, и почему мы решили ее сделать именно такой. Ну и, конечно, с какими проблемами нам пришлось бороться и как мы это делали.
17. низкие цены
большой выбор
актуальная информация
хороший поиск
удобно
доступно
саппорт говорит на моем языке
мобильный сайт
скорость
мобильное приложение
сайт на родном языке
и др.
наилучшее
впечатление
23. поиск
отбор по атрибутам
group fit
отбор по availability
ранжирование
autocomplete
&
disambiguation
определение
геопозиции
24. поиск
отбор по атрибутам
group fit
отбор по availability
ранжирование
autocomplete
&
disambiguation
определение
геопозиции
деревня Париж, Кигинский район, Республика Башкортостан, Россия ?
25. inventory
гостиница
«Домик с трубой»
1 янв. 2 янв. 3 янв.
2 000 ₽ 1750 ₽
4 янв. 5 янв.
1500 ₽ 1250 ₽
availability
гостиница
«Домик с трубой»
стоит 6500 ₽
с 1 янв. по 5 янв.
35. AV БД
• оптимизируем под чтение
• кластеризация PK по геопозиции (Z-order curve)
• шардинг по check-in
• 1x изменение в inv => 1000x изменений в AV
• SSD
• 4K IOPs reads+writes, 45 MB/s
AV
AV
AV
https://goo.gl/24mFR8
36. • ускорение в 50-100x раз
• быстрый холодный старт
• время материализации
в норме < 1 мин
• метрики + алерты
• quality check
Результаты
поиск
AVinv материализация AVAV
37. 500 000+ (до ~2014 г.)
• uwsgi + nginx + perl + mysql
• рост бизнеса
• новые фичи
• поиск по странам и регионам
• один запрос = один воркер
38. 2014 – 2015 гг.
• Map-Reduce фреймворк
• SOA
• большие запросы – быстрее
• маленькие запросы – медленнее
• IPC overheads
AVinv материализация AVAV
MR
веб-сервер
MR
MR
40. Надо что-то менять!
• что хотелось:
• отойти от устаревших подходов
• сохранить MR и SOA
• быстрый доступ к AV и другим данным
• база данных в которую можно быстро писать
• дешевый параллелизм
• попробовали Tarantool
• будем делать:
• Perl => Java
• multithreading, меньший константный фактор
• данные in-memory
• MySQL => RocksDB
41. координатор
координатор
веб-сервер
координатор
AVпоиск AVпоиск AVпоиск
AVпоиск AVпоиск AVпоиск
AVпоиск AVпоиск AVпоиск
статический шардинг
hotel_id mod N
реплики эквивалентны
shard0
реплика0 реплика1 реплика M
…
…
…
shard1
shardN
… … …
материал.
очередь
availability
материализация
inv
scatter-gather
рандомный выбор
реплики
retry, если необходимо
ping nodes
апдейты за
последние часы
in-memory индексы
AV persisted
42. Paris => [ hotels in Paris ]
has_parking => [ hotels with parking ]
входные данные:
1. геопозиция: Париж
2. атрибуты поиска: парковка, завтрак и т.д.
инвертированные индексы
Paris => [ hotels in Paris ]
has_parking => [ hotels with parking ]
Париж => [ отели в Париже ]
has_parking => [ отели с парковкой ]
отели отели отели
thread 0 thread Nthread 1
…
filter
sort
topn
filter
sort
topn
filter
sort
topn
merge
…
к координатору
AV
входные данные:
3. check-in, check-out
4. состав «команды»
44. Почему встроенная БД?
latency в масштабе
CPU цикл 0,3 нс 1 с
доступ в L1 кэш 0,9 нс 3 с
доступ в L2 кэш 2,8 нс 9 с
доступ в L3 кэш 12,9 нс 43 с
доступ в основную память 120 нс 6 мин
сжатие 1КБ в Snappy 3 000 нс 2,7 час
отправка 1КБ по сети 10 000 нс 9 час
чтение 1МБ из основной памяти 250 000 нс 9 дней
round trip внутри датацентра 500 000 нс 19 дней
ретрансмит TCP пакета 2 000 000 000 нс 200 лет
https://gist.github.com/jboner/2841832
http://talks.godoc.org/github.com/davecheney/high-performance-go-workshop/high-performance-go-workshop.slide#1
45. Почему встроенная БД?
latency в масштабе
CPU цикл 0,3 нс 1 с
доступ в L1 кэш 0,9 нс 3 с
доступ в L2 кэш 2,8 нс 9 с
доступ в L3 кэш 12,9 нс 43 с
доступ в основную память 120 нс 6 мин
сжатие 1КБ в Snappy 3 000 нс 2,7 час
отправка 1КБ по сети 10 000 нс 9 час
чтение 1МБ из основной памяти 250 000 нс 9 дней
round trip внутри датацентра 500 000 нс 19 дней
ретрансмит TCP пакета 2 000 000 000 нс 200 лет
46. Почему RocksDB?
• нужна key-value встроенная БД (store, get, delete)
• попробовали разные варианты:
• MapDB, Tokyo/Kyoto cabinet, leveldb
• «боевые условия»:
• датасет в pagecache
• 80% чтение + 20% запись
• стабильный random read performance при random writes
• HDDs, ~1.5K write IOPs, 6 MB/s
https://goo.gl/dqeBPG
47. Результаты
• время ответа поискового сервиса:
• время ответа странички поиска:
base: 2086ms
variant 1: 1361ms
кол-во отелей до после
Адриатическое побережье ~30 000 13 сек 30 мс
Рим ~6 000 5 сек 20 мс
София ~300 200 мс 10 мс
48. Заключение
• скорость – это не только про
конверсию
• посмотрите на
материализацию
• бизнес-процессы могут
облегчить жизнь