Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

193 views

Published on

Выступление на PYCON RUSSIA 2017

Published in: Internet
  • Be the first to comment

  • Be the first to like this

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

  1. 1. Александр Кошелев, PyCon Russia 2017 Ещё один поиск Яндекса
  2. 2. Общее описание Ещё один поиск Яндекса
  3. 3. Поиск по Интранету › Десятки сервисов – Вики, Трекер, Код и т.п. › Сотни миллионов документов Поиск по сервисам внутри Яндекс Коннект › Тысячи организаций Продукты 4
  4. 4. 〉Python 2 〉Django, Tornado, Gunicorn 〉Celery 〉PostgreSQL, MongoDB, Redis 〉Docker Технологии 6
  5. 5. Архитектура 7 APIAdmin Abovemeta Celery Frontend PostgreSQL MongoDB MapReduce SearchBack
  6. 6. Инфраструктура индексации Ещё один поиск Яндекса
  7. 7. 〉Два брокера › MongoDB – глобальные распределенные очереди › Redis – локальные очереди на одной машине 〉Отдельные ноды и очереди для каждой стадии Celery 9
  8. 8. Конвейер индексации 10 setup walk fetch create store
  9. 9. Индексатор 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)
  10. 10. 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')
  11. 11. Инфраструктура поиска Ещё один поиск Яндекса
  12. 12. Tornado › Асинхронный поход в API › Простая агрегация данных Django › Удобное окружение › ORM › REST API Почему Django и Tornado 14
  13. 13. Базовый степ class Step(object): def get_future(self, state, requester): """ Переопределяется в наследниках, возвращает таску с основной логикой степа. Не переопределяется для тех, у кого нет хождений по http """ moment = gen.Future() moment.set_result(None) return moment
  14. 14. @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
  15. 15. 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)
  16. 16. 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)
  17. 17. Использование 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(), ]), ])
  18. 18. Деплой Ещё один поиск Яндекса
  19. 19. 〉Все компоненты в одном образе 〉У компонента свой набор процессов 〉Контроль процессов с помощью supervisord 〉Для разработки docker-compose Docker 21
  20. 20. 22 Александр Кошелев alexkoshelev@yandex-team.ru Спасибо! @alexkoshelev

×