Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Homework. Task 8. #14

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

metacorn
Copy link

  1. Я работаю в одном из учреждений Минкомсвязи, проект, которым занимаюсь в основном -- система мониторинга цифровизации регионов РФ. Проект существует несколько лет. На некоторых эндпоинтах видны "просадки" перфоманса той или иной степени. По одному из них руководство поставило мне задачу по оптимизации, которую и использую для 8-го ДЗ по данному курсу.
  2. Наш проект должен предоставлять определённые данные по API. В виду большого объёма обрабатываемых данных, обработка JSON-ответов на запросы происходит не на лету, а с помощью кэширования. Resque раз в 15 минут запускает задачу, из которой происходит обращение к рассматриваемому контроллеру. В экшене этого контроллера происходит проверка наличие файлов с закэшированными данными. Если файла с соответствующим названием нет или данные в нём устарели, происходит генерация нового файла. Если файл есть и он актуален, то происходит отдача этого файла. В итоге клиенты при запросах на этот эндпоинт мгновенно начинают получать подготовленные данные (обновляемые раз в 15 минут). Resque воркеры при создании файлов потребляют много ресурсов (как по памяти, так и по CPU), задача заключалась в оптимизации именно этой ступени технологической цепочки.
  3. Фидбэк построил с помощью rake-задачи, из которой запускал выполнение resque-работы на ограниченном (для вменяемого времени обратной связи) объёме данных. В теле этой же задачи замерял время выполнения и потребление памяти до и после выполнения задачи. Попробовал сначала делать это в development окружении -- задача выполнялась 650 секунд. Создал local_production -- ускорение почти в 4 раза:
# RACK_ENV=local_production RAILS_ENV=local_production bundle exec rails test_generate:run         
        
Cleaning public/system/budget/ directory...
Running TestGenerateEventsApiJob task...
Run time: 174.28 sec.
Memory increase equals 1923 Mb.

Соответственно, продолжил работу на local_production. Защиту на соответствие данных в генерируемых файлах решил сделать в той же rake-задаче -- сравнивал предварительно созданный заведомо верный JSON с тем, что получался при выполнении задачи. Делал это не с помощью тестов, т.к. хотел проверять работу на реальных данных, а не сфабрикованных в изначально пустой тестовой базе.
4. Первым делом завернул задачу в stackprof. Ничего бросающегося в глаза не обнаружил -- в топе были гемы, код самого приложения встречался где-то на 15-ом месте и ничего криминального на первый взгляд не нёс.
5. Запрофилировал задачу в ruby-prof -- чуть более многословно. Видно, что много времени (66%) проводится в Jbuilder, из которого идут вызовы различных методов ActiveRecord. Но по коду самого приложения по-прежнему никаких намёков на неоптимальность.
6. Сделал вывод, что упор надо делать на профилирование памяти и работу с ней. Воспользовался memory_profiler. В топе -- ActiveRecord и Jbuilder (обращающийся к первому, как показывают предыдущие отчёты). Изучил гугл. Убрал Jbuilder -- переписал рендерер по принципу, изложенному в этой статье. Также, там, где было можно, перешёл на Oj. Итого:

# RACK_ENV=local_production RAILS_ENV=local_production bundle exec rails test_generate:run         
        
Cleaning public/system/budget/ directory...
Running TestGenerateEventsApiJob task...
Run time: 133.63 sec.
Memory increase equals 844 Mb.

По памяти х2.27, по времени -- х1.3.

Copy link
Collaborator

@spajic spajic left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 спасибо за кейс!

@@ -0,0 +1,24 @@
1. Я работаю в одном из учреждений Минкомсвязи, проект, которым занимаюсь в основном -- система мониторинга цифровизации регионов РФ. Проект существует несколько лет. На некоторых эндпоинтах видны "просадки" перфоманса той или иной степени. По одному из них руководство поставило мне задачу по оптимизации, которую и использую для 8-го ДЗ по данному курсу.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Работа государственного уровня 👍

Соответственно, продолжил работу на `local_production`. Защиту на соответствие данных в генерируемых файлах решил сделать в той же `rake`-задаче -- сравнивал предварительно созданный заведомо верный `JSON` с тем, что получался при выполнении задачи. Делал это не с помощью тестов, т.к. хотел проверять работу на реальных данных, а не сфабрикованных в изначально пустой тестовой базе.
4. Первым делом завернул задачу в `stackprof`. Ничего бросающегося в глаза не обнаружил -- в топе были гемы, код самого приложения встречался где-то на 15-ом месте и ничего криминального на первый взгляд не нёс.
5. Запрофилировал задачу в `ruby-prof` -- чуть более многословно. Видно, что много времени (66%) проводится в `Jbuilder`, из которого идут вызовы различных методов `ActiveRecord`. Но по коду самого приложения по-прежнему никаких намёков на неоптимальность.
6. Сделал вывод, что упор надо делать на профилирование памяти и работу с ней. Воспользовался `memory_profiler`. В топе -- `ActiveRecord` и `Jbuilder` (обращающийся к первому, как показывают предыдущие отчёты). Изучил гугл. Убрал `Jbuilder` -- переписал рендерер по принципу, изложенному в [этой статье](https://medium.com/neuronio/performance-comparison-for-json-generation-in-ruby-cc2cce55cf0b). Также, там, где было можно, перешёл на `Oj`. Итого:
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

Run time: 133.63 sec.
Memory increase equals 844 Mb.
```
По памяти `х2.27`, по времени -- `х1.3`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Эх, хотелось бы конечно побольше, но всё равно хорошо 👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants