Skip to content

Homework. Task 8. #14

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions case-study.md
Original file line number Diff line number Diff line change
@@ -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.

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

2. Наш проект должен предоставлять определённые данные по `API`. В виду большого объёма обрабатываемых данных, обработка `JSON`-ответов на запросы происходит не на лету, а с помощью кэширования. `Resque` раз в 15 минут запускает задачу, из которой происходит обращение к рассматриваемому контроллеру. В экшене этого контроллера происходит проверка наличие файлов с закэшированными данными. Если файла с соответствующим названием нет или данные в нём устарели, происходит генерация нового файла. Если файл есть и он актуален, то происходит отдача этого файла. В итоге клиенты при запросах на этот эндпоинт мгновенно начинают получать подготовленные данные (обновляемые раз в 15 минут). `Resque` воркеры при создании файлов потребляют много ресурсов (как по памяти, так и по `CPU`), задача заключалась в оптимизации именно этой ступени технологической цепочки.
3. Фидбэк построил с помощью `rake`-задачи, из которой запускал выполнение `resque`-работы на ограниченном (для вменяемого времени обратной связи) объёме данных. В теле этой же задачи замерял время выполнения и потребление памяти до и после выполнения задачи. Попробовал сначала делать это в `development` окружении -- задача выполнялась `650` секунд. Создал `local_production` -- ускорение почти в 4 раза:
```bash
# 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` -- переписал рендерер по принципу, изложенному в [этой статье](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.

👍

```bash
# 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

Choose a reason for hiding this comment

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

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