-
Notifications
You must be signed in to change notification settings - Fork 44
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
base: master
Are you sure you want to change the base?
Conversation
There was a problem hiding this 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-го ДЗ по данному курсу. |
There was a problem hiding this comment.
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`. Итого: |
There was a problem hiding this comment.
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`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Эх, хотелось бы конечно побольше, но всё равно хорошо 👍
API
. В виду большого объёма обрабатываемых данных, обработкаJSON
-ответов на запросы происходит не на лету, а с помощью кэширования.Resque
раз в 15 минут запускает задачу, из которой происходит обращение к рассматриваемому контроллеру. В экшене этого контроллера происходит проверка наличие файлов с закэшированными данными. Если файла с соответствующим названием нет или данные в нём устарели, происходит генерация нового файла. Если файл есть и он актуален, то происходит отдача этого файла. В итоге клиенты при запросах на этот эндпоинт мгновенно начинают получать подготовленные данные (обновляемые раз в 15 минут).Resque
воркеры при создании файлов потребляют много ресурсов (как по памяти, так и поCPU
), задача заключалась в оптимизации именно этой ступени технологической цепочки.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
.