Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
SlideShare a Scribd company logo
«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс
Александр Кошелев, PyCon Russia 2017
Ещё один поиск
Яндекса
Общее описание
Ещё один поиск Яндекса
Поиск по Интранету
› Десятки сервисов – Вики, Трекер, Код и т.п.
› Сотни миллионов документов
Поиск по сервисам внутри Яндекс Коннект
› Тысячи организаций
Продукты
4
«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс
〉Python 2
〉Django, Tornado, Gunicorn
〉Celery
〉PostgreSQL, MongoDB, Redis
〉Docker
Технологии
6
Архитектура
7
APIAdmin
Abovemeta
Celery
Frontend
PostgreSQL MongoDB
MapReduce
SearchBack
Инфраструктура
индексации
Ещё один поиск Яндекса
〉Два брокера
› MongoDB – глобальные распределенные
очереди
› Redis – локальные очереди на одной машине
〉Отдельные ноды и очереди для каждой стадии
Celery
9
Конвейер индексации
10
setup walk fetch create store
Индексатор
class Source(BaseIndexer):
def do_setup(self):
for user in users:
self.next('walk', user=user)
def do_walk(self, user):
for opponent in get_user_opponents(user):
self.next('fetch', user=user, opponent=opponent)
def do_fetch(self, user, opponent):
for messages in get_messages(user, opponent):
self.next('create', message=message)
def do_create(self, message):
doc = self.create_document(...)
doc.emit_snippet(...)
doc.emit_body(..)
doc.emit_facet_attr('date', ...)
doc.emit_search_attr('author', ...)
self.next('store', document=doc, body_format='json')
Инфраструктура
поиска
Ещё один поиск Яндекса
Tornado
› Асинхронный поход в API
› Простая агрегация данных
Django
› Удобное окружение
› ORM
› REST API
Почему Django и Tornado
14
Базовый степ
class Step(object):
def get_future(self, state, requester):
"""
Переопределяется в наследниках,
возвращает таску с основной
логикой степа. Не переопределяется для тех,
у кого нет хождений по http
"""
moment = gen.Future()
moment.set_result(None)
return moment
@gen.coroutine
def execute(self, state, requester):
""" Метод который запускает выполнение таски
из self.get_future """
if not state.errors:
res = yield self.get_future(state, requester)
self.process_response(state, res)
def process_response(self, state, response):
""" Переопределяется в наследниках.
По умолчанию не делает ничего. """
pass
ParallelStep
class ParallelStep(CompoundStep):
@gen.coroutine
def execute(self, state, requester):
steps = self.get_steps(state)
if not state.errors and steps:
responses = yield [step.get_future(state, requester)
for step in steps]
for response, step in zip(responses, steps):
step.process_response(response)]
self.process_response(state, responses)
ChainStep
class ChainStep(CompoundStep):
@gen.coroutine
def execute(self, state, requester):
data = []
steps = self.get_steps(state)
for step in steps:
if state.errors:
break
response = yield step.get_future(state, requester)
data.append(response)
step.process_response(state, response)
self.process_response(state, data)
Использование
class IntraSearchHandler(BaseSearchHandler):
def create_steps(self):
return steps.ChainStep([
steps.AuthStep(),
steps.ParallelStep([
steps.FormulasStep(),
steps.ExternalWizardStep(),
steps.ErrataStep(),
]),
steps.ParallelStep([
steps.FeaturesStep(),
steps.RevisionsStep(),
]),
steps.DeciderStep(),
steps.FullSearchStep(),
steps.ParallelStep([
steps.FacetsStep(),
steps.FullGroupAttrs(),
]),
])
Деплой
Ещё один поиск Яндекса
〉Все компоненты в одном образе
〉У компонента свой набор процессов
〉Контроль процессов с помощью supervisord
〉Для разработки docker-compose
Docker
21
22
Александр Кошелев
alexkoshelev@yandex-team.ru
Спасибо!
@alexkoshelev

More Related Content

«Ещё один Поиск Яндекса» Александр Кошелев, Яндекс