ERP X5
Сейчас Х5 управляет более чем 13 000 магазинов. Большинство бизнес-процессов каждого из них проходит через единую ERP-систему. В каждом магазине может быть от 3 000 до 30 000 товаров, это создает проблемы с нагрузкой на систему, т.к. через неё проходят процессы регулярного пересчёта цен в соответствии с промо-акциями и требованиями законодательства и расчёта пополнения товарных запасов. Всё это критично, и если вовремя не будет посчитано, какие товары в каком количестве должны быть завтра доставлены в магазин либо какая цена должна быть на товары, покупатели не найдут на полках то, что искали, либо не смогут приобрести товар по цене действующей промо-акции. В общем, кроме учёта финансовых операций, ERP-система отвечает за многое в повседневной жизни каждого магазина.
Немного ТТХ ERP-системы. Её архитектура классическая, трехуровневая с сервисно-ориентированными элементами: сверху у нас более 5 000 толстых клиентов и терабайты информационных потоков от магазинов и распределительных центров, в слое приложений – SAP ABAP c более чем 10 000 процессами и, наконец, Oracle Database c более чем 100 Тб данных. Каждый процесс ABAP – это условно виртуальная машина, выполняющая бизнес-логику на языке ABAP, со своим DBSL и диалектом SQL, кэшированием, memory management, ORM и т.д. В день мы получаем больше 15 Тб изменений в логе базы. Уровень нагрузки – 500 000 запросов в секунду.
Эта архитектура – гетерогенная среда. Каждый из компонентов кроссплатформенный, мы можем перемещать его на разные платформы, выбирать оптимальные и т.д.
Масла в огонь добавляет то, что ERP-система находится под нагрузкой 24 часа в сутки 365 дней в году. Доступность — 99,9% времени в течение года. Нагрузка при этом разделена на дневной, ночной профили и house keeping в свободное время.
Но и это не всё. У системы жесткий и плотный релизный цикл. В год она переносит больше 2 000 пакетных изменений. Это может быть и одна новая кнопочка, и серьезные изменения в логике работы бизнес-приложений.
В итоге это большая и высоконагруженная, но при этом стабильная, прогнозируемая и готовая к росту система, способная «хостить» десятки тысяч магазинов. Но так было не всегда.
2014. Точка бифуркации
Для погружения в практический материал нужно перенестись в 2014 год. Тогда были самые сложные задачи по оптимизации системы. Магазинов было около 5 000.
Система в то время находилась в таком состоянии, что большинство критичных процессов были немасштабируемы и неадекватно отвечали на рост нагрузки (то есть на появление новых магазинов и товаров). Кроме того, за два года до этого был закуплен дорогой Hi-End, и на какое-то время апгрейд не входил в наши планы. При этом процессы в ERP были уже на грани нарушения SLA. Вендор дал заключение, что нагрузка на систему немасштабируема. Никто не знал, выдержит ли она еще хотя бы +10% прироста нагрузки. А магазинов планировалось открыть в два раза больше в течение трех лет.
Просто накормить ERP-систему новым железом было невозможно, да и не помогло бы. Поэтому в первую очередь мы решили включить в релизный цикл методику оптимизации ПО и следовать правилу: линейный рост нагрузки пропорционально росту драйверов нагрузки – залог прогнозируемости и масштабируемости.
В чем заключалась методика оптимизации? Это цикличный процесс, разбитый на несколько этапов:
- мониторинг (выявить узкие места в системе и определить топовых потребителей ресурсов)
- анализ (профилирование процессов-потребителей, выявление в них конструкций с наибольшим и нелинейным влиянием на нагрузку)
- разработка (снижение влияния конструкций на нагрузку, достижение линейной нагрузки)
- тестирование в среде оценке качества или внедрение на продуктивной среде
Далее цикл повторялся.
В процессе мы поняли, что текущие инструменты мониторинга не позволяют нам быстро определять топовых потребителей, выявлять узкие места и голодающие по ресурсам процессы. Поэтому для ускорения попробовали инструменты elastic search и Grafana. Для этого самостоятельно разработали коллекторы, которые из стандартных инструментов мониторинга в Oracle/SAP/AIX/Linux передавали метрики в elastic search и позволяли в режиме реального времени отслеживать здоровье системы. Кроме того, обогатили мониторинг своими custom-метриками, например время отклика и пропускная способность специфичных компонентов SAP или раскладки профилей нагрузки по бизнес-процессам.
Оптимизация кода и процессов
В первую очередь для меньшего влияния узких мест на быстродействие обеспечили более плавную подачу нагрузки на систему.
Большинство бизнес-процессов в нашей ERP-системе, например, такие как регулярный расчёт цен или планирование пополнения товарных запасов, представляют собой последовательную поэтапную обработку большого объёма данных (по всем товарам и всем магазинам). Для реализации обработки в рамках таких тяжёлых задач в своё время мы разработали собственный диспетчер пакетно-параллельной обработки (далее – планировщик нагрузки). В данном случае в виде пакета представляется обособленно выполняемый этап обработки по отдельному магазину.
Изначально логика планировщика была такова, что сначала выполнялись пакеты первого этапа обработки по всем магазинам, затем пакеты второго этапа и т.д. То есть в системе одновременно выполнялись процессы, создававшие однотипную нагрузку и вызывавшие деградацию определенных ресурсов (ввод-вывод на БД или CPU на серверах приложений, и т.д.).
Мы переписали логику планировщика таким образом, чтобы цепочка пакетов формировалась отдельно по каждому магазину и приоритет запуска новых пакетов выстраивался не по этапам, а по магазинам.
За счёт различной длительности выполнения пакетов по разным магазинам и регулируемого большого количества одновременно выполняемых процессов в рамках задач планировщика нагрузки мы достигли одновременного выполнения разнородных процессов, более плавной подачи нагрузки и устранения части узких мест.
Затем занялись оптимизацией отдельных конструкций. Каждый отдельный пакет рассматривали, профилировали и собирали неоптимальные конструкции и применяли подходы для их оптимизации. В дальнейшем эти подходы включили в регламент разработчика с целью предотвращения нежелательного роста нагрузки при развитии системы. Некоторые из них:
- избыточная нагрузка на ЦПУ серверов приложений (Часто порождалась нелинейными алгоритмами в коде программы, например, старый добрый линейный поиск в циклах либо нелинейные алгоритмы поиска пересечений множеств неупорядоченных элементов и т.п… Лечилось заменой на линейные алгоритмы: линейный поиск в циклах заменяем на двоичный; для поиска пересечений множеств используем линейные алгоритмы, предварительно упорядочив элементы и т.д.)
- идентичные обращения к БД с одними и теми же условиями в рамках одного процесса нередко приводят к избыточной утилизации CPU БД (лечится кешированием результатов первой выборки в памяти программы или на уровне сервера приложения и использованием закэшированных данных при последующих выборках)
- частые join-запросы (лучше их, конечно, выполнять на уровне БД, но иногда мы позволяли себе расщепить их на простые выборки, результат которых кэшируется, и перенести логику склеивания в приклад. Те случаи, когда лучше греть сервера приложений, а не БД.)
- тяжелые join-запросы, приводящие к большому количеству операций ввода/вывода
О последнем подробнее. В этом случае переводили модель данных в менее нормальную форму. Классический пример – выборка бухгалтерских документов за конкретную дату для отдельного магазина. Её запрашивают многие сотрудники. В master-таблице (таблице заголовков) хранятся даты документов, в таблице позиций — магазин и товар. Наиболее частые запросы – выборка всех документов по конкретному магазину за определённую дату. При таком запросе фильтр по дате по таблице заголовков выдаёт 500 тыс. записей, фильтр по магазину – аналогичный объём. При этом после склеивания по отдельному магазину за нужную дату мы имеем 3 тыс срок. Независимо от того, с какой таблицы мы начинаем фильтрацию и склеивание данных – всегда получаем много нежелательных операций ввода-вывода.
Этого можно избежать, если представить данные в менее нормальной форме. В одном случае поле даты дублировали в таблице позиций, обеспечили его заполнение при создании документов, собрали индексы для быстрого поиска и фильтровали уже по таблице позиций. Таким образом, пожертвовав незначительными накладными расходами на хранение нового поля и индексов, мы в несколько раз сократили число операций ввода/вывода, порождаемых проблемными запросами.
2015. Проблема одного сервиса
За полтора года мы проделали большую работу по оптимизации системы, она стала более прогнозируемой. Тем не менее, планы по удвоению числа магазинов оставались актуальны, поэтому вызовы все еще стояли перед нами.
По пути «вверх» мы столкнулись с разными узкими местами. Например, в конце 2015 года осознали, что уперлись в производительность одного core-сервиса платформы. Речь идет о сервисе логических блокировок SAP ABAP. Из-за него система явно не выдержала бы роста нагрузки. На горизонте замаячили потери больших денег.
Уточним, задача сервиса – выносить логическую транзакционность на уровень сервера приложений. В ABAP одна транзакция может пройти в виде нескольких шагов на разных рабочих процессах. Для того чтобы транзакция была целостной, есть сервис блокировок и сопутствующие механизмы. Операции по блокировке и разблокировке в нем происходят быстро, но они атомарные, их нельзя разделять. При этом была проблема синхронного ввода-вывода.
Сервис немного ускорился после того, как разработчики SAP выпустили специальный патч, мы перевели сервис на другое железо и поработали над системными настройками, но этого по-прежнему было мало. Потолок сервиса по паспорту составлял примерно 7 тыс операций в секунду, а нам уже давно требовалось 10 тыс.
После синтетического нагрузочного теста выяснили, что деградация происходит нелинейно и мы все-таки находимся у границы производительности сервиса выше которой проявляется неприемлемая деградация всей ERP системы. Повторные обращения к разработчикам дали лишь неутешительный вердикт — сервис работает правильно, просто мы требуем слишком многого в текущей архитектуре решения. Даже если бы мы немедленно взялись переделывать всю архитектуру решения, нам потребовалось бы несколько месяцев поддерживать работоспособность текущей системы.
Один из первых вариантов действий в попытке продлить жизнь сервису блокировок – ускорить операции ввода-вывода и их запись в файловой системе. Чем? Экспериментами с альтернативой AIX. Перенесли сервис на Linux на самой мощной Power-машине, и выиграли очень много по времени отклика. Сервис с включенной работой с файловой системой вел себя так же, как на Aix с отключенной. Далее перенесли на один из x86_64 блейдов этот код и получили еще более фантастически пологую кривую производительности, чем раньше. Выглядело это забавно.
Можно было бы предположить, что разработчики на AIX и Linux в прошлом тесте кое-что делали по-разному, но здесь уже влияние оказывала и архитектура процессора.
Какой был вывод? Какая-то платформа идеально подходит для многопоточных баз данных, обеспечивая и производительность, и отказоустойчивость, но со специфичными задачами процессор на другой архитектуре вполне может справиться лучше. Если на старте построения решения отказаться от кроссплатформенности, можно потерять пространство для маневров в будущем.
Тем не менее, с этой проблемой мы разобрались и сервис стал работать в 3-4 раза быстрее, что хватит на очень долгий рост.
2016. DB CPU Bottleneck
Буквально через полгода стали ощущаться экзотические проблемы с ЦПУ на БД. Вроде бы понятно, что с ростом нагрузки растет потребление ресурсов процессора. Но все большую часть его стал занимать SysTime, и явно была проблема в ядре. Стали разбираться, делать синтетические нагрузочные тесты и поняли, что наша пропускная способность – 300 тыс операций в секунду, т.е. миллиард запросов в час, а дальше – деградация.
В итоге мы пришли к выводу, что идеальный запрос – тот, которого нет. Расширили свою методику оптимизации новыми подходами и провели ревизию ERP-системы: стали искать запросы, например, с низким КПД (100 тыс селектов – в результате 100 строк или вообще 0) — переделывать. Если «пустые» запросы не получается убрать, то пусть они уходят в «negative cache», если уместно. Если параллельно обрабатывается много запросов одних и тех же данных о товарах, то пусть они мучают сервер приложений, а не базу — кэшируем. Также большое количество частых единичных запросов по ключу в рамках одного процесса “укрупняем”, заменяя на более редкие выборки по части ключа. Или, например, для распределения нагрузки в цепочке обработки разные шаги могли выполняться на разных серверах приложений. Это хорошо, но на разных этапах они могут спрашивать одно и то же у базы. Тогда пусть первый шаг после старта на application кэширует часть запросов, и остается там доделывать всю остальную цепочку.
С помощью таких приемов мы выигрывали везде понемногу, но в итоге серьезно разгрузили базу. Система ожила. А мы тем временем занялись Aix.
В ходе других экспериментов выяснили, что есть потолок производительности – уже упомянутые 300 000 DataBase-коллов в секунду. Корни проблемы были в производительности сетевого интерфейса, у которого был потолок – около 300 тыс пакетов в секунду в одну сторону. Как только потолок становился ближе, время системных вызовов росло. Как потом выяснилось, это также было наследие сетевого стека ядра ОС AIX.
В целом у нас никогда не было проблем с latency, ядро сети было производительным, все шнуры были собраны в большой неубиваемый канал на одном интерфейсе. Мы сделали обходное решение: разбили всю сеть между серверами приложений и базой данных на группы по разным интерфейсам. В итоге каждая группа серверов приложений общалась с БД по своему отдельному интерфейсу. Максимальная производительность каждого интерфейса немного снижалась, но суммарно мы разогнали сеть до 1 млн пакетов в секунду в одну сторону.
А принцип «Лучший запрос — тот, которого нет» был добавлен в талмуд для разработчиков, чтобы это учитывалось при написании кода.
2017. Дожить до апгрейда
Ну и последний этап оздоровления нашей системы, пройденный в 2017 году. Оставалось дожить совсем немного до апгрейда и нужно было продержать SLA всего-то ничего. Код был оптимизирован, но мы видели, что чем выше нагрузка на ЦПУ базы данных, тем медленнее работают процессы, хотя запас утилизации составлял 10-20%. Изначально рассчитывали, что 100% — это в два раза больше, чем 50%. И когда есть запас 10-20%, это и есть 10-20%. На самом деле при нагрузке выше 67-80% длительность задач нелинейно росла, т.е. срабатывал закон Амдала. У системы был лимит параллелизации и при его превышении, при вовлечении всё большего числа процессоров в работу снижалась производительность каждого отдельно взятого процессора.
На тот момент мы использовали 125 физических процессоров, или 500 логических с учётом multithreading на уровне AIX. Что бы вы предложили? Апгрейд? Даже до окончания его согласования нужно было продержаться несколько месяцев и не уронить SLA.
В какой-то момент поняли, что традиционные метрики утилизации процессора не показательны для нас – они не показывают фактическое начало деградации. Для реалистичной оценки здоровья системы мы начали использовать интегральную метрику – результат выполнения синтетического теста как метрики производительности процессора БД. Раз в минуту делали синтетический тест, замеряли его длительность и эту метрику выводили на наши мониторы. И реагировали, если метрика поднималась выше заявленной критической отметки. Мы немного придерживали нагрузку наших планировщиков нагрузки, чтобы она оставалась в зоне «максимального крутящего момента» базы данных.
Однако ручной контроль был неэффективным, да и просыпаться по ночам нам надоело. Тогда мы переписали планировщик нагрузки так, что у него появилась обратная связь по текущим метрикам производительности. Если метрики выходили за рамки желтого порога (см. картинку), планирование низкоприоритетных пакетов замораживалось и приоритет получали только бизнес-критичные процессы. Таким образом автоматически мы смогли управлять интенсивностью подачи нагрузки и ресурсы использовались эффективно. И самое интересное, что удерживая систему в пределах 80% нагрузки, в той самой зоне максимального крутящего момента, мы в итоге получили сокращение суммарного времени выполнения бизнес-процессов, т.к. каждый поток стал работать значительно быстрее.
Пара советов тем, кто работает с высоконагруженной ERP
- Очень важно вести мониторинг производительности систем на старте проекта, особенно с собственными метриками.
- Обеспечьте линейный рост нагрузки пропорционально росту количества драйверов нагрузки (в нашем случае ими были товары и магазины).
- Устраняйте нелинейные конструкции в коде, используйте кэширование для устранения идентичных запросов к БД.
- Если нужно перенести нагрузку с ЦПУ БД на ЦПУ серверов приложений, то можно и прибегнуть к расщеплению join-запросов на простые выборки.
- При всех оптимизациях помните, что быстрый запрос – хорошо, а быстрый и частый запрос – иногда плохо.
- Старайтесь всегда прощупывать и использовать возможности гетерогенной среды решения.
- Наряду с традиционными метриками производительности используйте интегральную метрику, однозначно идентифицирующую наличие деградации; с помощью этой метрики определите зону “максимального крутящего момента” своей системы.
- Обеспечьте инструменты планирования нагрузки наличием механизмов контроля текущих показаний метрик производительности и управления интенсивностью подачи нагрузки с целью эффективного использования ресурсов системы
Благодарим организаторов Highload за возможность поделиться этим опытом не только на Хабре, но и на сцене крупнейшего мероприятия по высоконагруженным системам.
Дмитрий Цветков, Александр Лищук, эксперты по SAP в #ITX5
Кстати, #ITX5 ищет консультантов SAP.
Комментарии (27)
Fragster
07.12.2018 22:57У нас на полусотне магазинов мы просто сделали двухуровневый РИБ на 1с, никаких особых проблем не было.
Ast95NG
08.12.2018 09:47Тоже в шоке, четырехуровневая (федеральный-областной-районный-магазин) база Центросоюза на 1С держит сопоставимое количество (тысячи) торговых объектов и не кашляет. SAP не может в иерархию? Обязательно цены пересчитывать по всей сети на одном железе?
pfihr
09.12.2018 11:48У вас «иллюзия одинесника». Функционал не сопоставим. Понятно, что если передавать просто регистр сведений с остатками и реестр проданных товаров, то тут даже просто одна база MS SQL справится. SAP у них делает не то же самое.
epishman
08.12.2018 09:48Денормализация дело знакомое, делали такое в Axapta, например переносили финансовые поля (счет, корсчет и финаналитики) прямо в таблицу складских проводок, в итоге было удобно отчеты получать. Огребли случайно, когда возникла необходимость разделения одного складского лота на 2 финансовых. Кроме того после такого вмешательства в структуру таблиц патчи без бубна не встают.
chikipibarum
08.12.2018 17:49Денормализацию в этой истории применяли в единичных случаях. Варианты реализации были следующие:
1. Добавление поля в detail-таблицу. В результате чего фильтровали сразу по detail-таблице.
2. Создание custom-таблицы с уникальным ключом из detail-таблицы и полями из master- и detail- таблиц, используемыми для фильтра (по сути кластерный индекс). В результате фильтруем по custom-таблице и соединяем с master- и detail- таблицами по ключу.
По поводу рисков при обновлении/установке патча:
В SAP эти проблемы решаются при корректной имплементации изменений. В подобных таблицах зачастую в словаре на уровне приложения предусмотрен инклюд для custom-полей. В функциональных модулях обновления предусмотрены так называемые user-exit'ы — фрагменты для custom-кода, в которых мы и обеспечиваем заполнение новых полей. Если custom-доработки стандарта реализованы в предназначенных для этого местах, то они не воспринимаются, как модификация («подлом») стандартных объектов и при апгрейде/установке патча можно избежать «танцев с бубнами».
В прочих же системах — да, стоит учитывать риски, которые могут возникнуть при обновлении, если они существуют.
DenisTrunin
08.12.2018 17:49А как происходит установка обновлений и тестирование нового функционала? т.е. как выявляются случаи, когда допустим небольшая доработка механизма расчета цен при умножении на 5000 магазинов приводит к перегрузке сервера БД
chikipibarum
08.12.2018 18:22Разработка нового функционала и установка обновлений у нас проводятся в рамках релизных циклов. Длительность одного цикла в среднем один месяц. В течение одного цикла выполняется две-три итерации накатки релизных изменений и тестирования.
Нагрузочное тестирование состоит из двух этапов:
1. Запуск полного профиля нагрузки, приблизительно как в продуктиве. Профиль включает в себя критичные бизнес-процессы (те самые расчёты на тысячах магазинов, по которым есть строгий SLA), TOP 80% потребителей ресурсов (по результатам анализа почасовой раскладки продуктивной нагрузки в разрезе программ/бизнес-процессов), новый функционал (если в релизе есть не только доработка существующих процессов, но и внедрение новых).
2. Профилирование единичных запусков расчётов по избранным магазинам (single thread тест).
На каждом из этапов выполняются тесты до внесения изменений и после (по сути эталонное тестирование).
На этапе полномасштабного теста после тестирования анализируется почасовая раскладка потребителей ресурсов в разрезе программ/бизнес-процессов, выявляются новые участники в TOP 80% источниках нагрузки и фиксируется необходимость выполнения их профилировки.
На этапе single thread теста по результатам профилировки программ анализируется TOP 80% конструкций отдельно по каждому запуску, выявляются новые конструкции в TOP 80%, влияющие на нагрузку, определяются дальнейшие меры по их оптимизации.
Описанные выше тесты выполняются в тестовой системе, по мощности равной продуктивной.
Наряду с этими тестами обязательным является профилирование меняемых/разрабатываемых программ в системе оценки качества до того, как они переносятся в тестовую систему. Т.е. в менее производительной системе выполняются single thread тесты на ограниченном объёме данных и по результатам профилировки ещё на этапе разработки выявляются неоптимальные конструкции и типовые ошибки, методы борьбы с которыми мы описали в применяемом у нас кодексе разработчика. Каждое изменение проходит через так называемый чек-лист.DenisTrunin
08.12.2018 18:42Спасибо за ответ. я так понял для п.1 требуется восстановление копии БД с какими-то настроенными данными. Сколько вообще оно занимает по времени при таком объеме(в 100ТБ)? это часы или дни?
chikipibarum
08.12.2018 19:46Регулярно, раз в месяц мы проводим копирование продуктивной системы в тестовую путём восстановления копии системы из бэкапа. Непосредственно восстановление БД занимает порядка 12-14 часов. Дополнительно после восстановления выполняются технические операции по подготовке тестовой среды, которые занимают ещё несколько часов (смена имени логической системы, настройка соединений с тестовыми средами и т.д. и т.п.); большинство этих операций у нас автоматизировано. После копирования системы, в основном, все необходимые данные для тестирования есть — мастер-данные по товарам, промо-акциям и т.д. В дополнение к этим данным перед каждым тестом генерируются данные по продажам за день для обеспечения нагрузочного тестирования функционала планирования пополнения товарных запасов (эти данные генерируются по запросу программой не дольше часа).
maxim_ge
08.12.2018 19:47Очень интересная статья, но кое-что непонятно.
>Даже до окончания его согласования нужно было продержаться несколько месяцев и не уронить SLA.
Можно пару слов про это, что такое «уронить SLA» и чем это чревато?
>Уровень нагрузки – 500 000 запросов в секунду
Получается около сорока запросов в секунду с магазина, можете поподробнее рассказать про эти запросы, что в них «запрашивается» с такой скоростью?chikipibarum
08.12.2018 20:11Спасибо за комментарий.
Про SLA:
Есть SLA по ряду процессов (например, расчёт цен или планирование пополнения запасов): к открытию каждого магазина расчёты должны быть завершены и их результаты должны дойти через систему интеграции до магазина. В последнем разделе статьи описывается период развития системы, в котором запас по времени выполнения процессов до нарушения SLA был невелик и бездействие привело бы в скором к срывам сроков завершения ежедневных регулярных процессов. Чем чревато — описано в первом разделе статьи: «если вовремя не будет посчитано, какие товары в каком количестве должны быть завтра доставлены в магазин либо какая цена должна быть на товары, покупатели не найдут на полках то, что искали, либо не смогут приобрести товар по цене действующей промо-акции»
Про уровень нагрузки:
500.000 запросов — это интенсивность обращений с серверов приложений к БД. Они порождаются разнородными процессами:
— регулярные расчёты, некоторые из которых описаны выше (например, в ходе расчётов по каждому товару, которых тысячи в ассортименте, запрашиваются мастер-данные с настройками, используемыми при прогнозировании, данные о действующих промо-акциях, данные по продажам и т.д.);
— интеграционные процессы (например, обращения к БД, выполняемые при отправке заказов в магазины или получении ответов от магазинов с подтверждением заказов)
— пользовательские процессы (например, запуск программ, формирующих налоговые декларации на основе первичных финансовых документов и т.п.)
— процессы обновления мастер-данных и т.д.
An_02
08.12.2018 22:26-1Недавно были опубликованы планы по переходу X5 на SAP HANA. Делали ли расчет, как изменится производительность в этом случае?
chikipibarum
09.12.2018 08:27Уточните, пожалуйста, о какой публикации идёт речь. Вероятно, это давняя публикация о переходе на SAP HANA системы BW, не имеющая отношения к системе ERP, о которой рассказано в данной истории.
Относительно расчётов при миграции на HANA: расчёты могут достаточно точно показать размер БД после миграции (такие расчёты выполняются скриптами, поставляемыми вендором), но оценить прирост производительности наиболее точно помогут тесты на стенде, методики таких расчётов нет. Расчёты помогут лишь оценить ту долю нагрузки, на которую повлияет миграция (без рефакторинга процессов): например, если процесс проводит 30% времени в БД, а 70% — на сервере приложений, то не стоит ожидать кратного ускорения его выполнения после миграции на другую СУБД.
laoleesch
09.12.2018 11:43Мы перевели BW на HANA, и это хорошая тема для отдельной статьи. Она прекрасно проявляет себя в OLAP'е, хотя есть и свои нюансы и слабые места.
По ERP таких планов пока нет. Scale-out OLTP очень скользкий вопрос, а на наших объемах у нас выйдет немало нод. Субъективно, пока наш ERP не готов к HANA, да и HANA, скорее всего, не готова конкретно к нему.
NitroJunkie
09.12.2018 11:42+1А почему СУБД хотя бы на master-slave не пробовали кластеризовать (на мастер только UPDATE/INSERT отправлять, а SELECT'ы на слэйвы)? А тем более RAC раз у вас Oracle для master-master попробовать? Так и отказоустойчивость бы повысилась…
Ну и выбор ERP-решения/framework'а с логическими блокировками на уровне сервера приложений для Highload'а это конечно такое себе решение… То есть что вы будете в следующий раз когда нагрузка дорастет до критического объема с сервером блокировок делать? Не говоря уже о том что это опять таки дополнительная точка отказа.laoleesch
09.12.2018 14:02Очень хорошие вопросы, спасибо.
Есть стоп-факторы, кроющиеся в объеме данных и интенсивности изменений, а также в самой платформе приложения. SAP ABAP позволяет выполнять достаточно глубокую интервенцию в логику и архитектуру, но с определенного уровня она ограничена технически и, так сказать, лицензионно.
Например, развертывание того же active standby было бы удобным, если бы не итоговая стоимость инфраструктуры и ограниченность применения из-за задержки накатки изменений, а также необходимости «костылей» в приложении.
К проработке RAC возвращаемся регулярно. Пока это оказывалось спорным решением, несмотря на киллер-фичу с потенциальным zero-DT. Например, на текущих объемах и интенсивности нужно далеко не 2 ноды, и на нагрузочных тестах того же ночного профиля наблюдали очень большие потери на sync. В итоге, как бы это странно не звучало, дешевле, стабильнее и эффективнее оказывался scale-up. Но мы продолжаем думать о RAC.
История с резким повышением интенсивности роста компании, превращением системы в highload, и вылезшим лимитом enqueue server здорово нас «взбодрила». Сейчас он достаточно мощный и в отказоустойчивой конфигурации, но мы осознаем «тупик» с ним в будущем.
Сейчас мы активно работаем над уменьшением объема горячих данных, прорабатываем вынос части функционала в отдельные системы, ETL и эффективный sync мастер-данных, чтобы сделать решение гибким и горизонтально масштабируемым, как в целом, так и в слое СУБД.NitroJunkie
09.12.2018 14:52Не совсем понял в чем заключается проблема лицензионности, если только там привязки к железу СУБД нет конечно. Я конечно слышал легенды, что САП лицензии даже к прокаченной нефти привязывает, но в данном случае это было бы выстрелом себе в ногу.
С технической точки зрения, да есть проблема с задержкой наката изменений, но это решается не так сложно — процесс запоминает последнюю проведенную транзакцию и какое то время остается на мастере, пока какой-нибудь из слэйвов не получит эту транзакцию, после чего этот процесс отправляется туда. Но это да, вопрос к тому, что SAP как платформа из этого умеет делать из коробки, потому как иначе все решение будет в костылях. Но если учесть, что чтения идут обычно гораздо чаще записи запас масштабируемости в такой архитектуре получается огромный (даже возможно оптимизаций не надо было делать).
Кстати раз уж пошла такая пьянка, что-то у меня цифры не сходятся, вы говорите что на 13000 магазинов у вас 5000 одновременных подключений (или вы что-то другое имеете ввиду под 5000 толстых клиентов), хотя по идее должно быть минимум 50000. Правда если учесть
— интеграционные процессы (например, обращения к БД, выполняемые при отправке заказов в магазины или получении ответов от магазинов с подтверждением заказов)
получается у вас сами магазины не в этой ERP системе работают? И если так, то как вы ограничения (и вообще операции которые должны приводить к отмене транзакции) обрабатываете? Самый тупой пример — 2 магазина заказывают один и тот же товар с распредцентра и им обоим его не хватает?chikipibarum
09.12.2018 17:20По вопросам:
5000 — примерное количество пользователей, одновременно работающих через толстый клиент SAPGUI. Это пользователи центрального и региональных офисов (логистика, транспорт, бухгалтерия и т.д.)
Магазины и распределительные центры напрямую в ERP не работают. Специализированные системы, используемые в магазинах и РЦ, общаются с ERP через шину интеграции.
Как обрабатываются ограничения: в процессе пополнения обработка таких ограничений обеспечивается статусной схемой заказов — ERP получает от систем РЦ и магазинов сообщения со статусами и корректировками заказов, в результате обработки которых меняет соответствующим образом заказы.
О примере про 2 магазина, которые заказывают один и тот же товар с РЦ и обоим его не хватает: это исключительно редкая ситуация, т.к. пополнение запасов РЦ рассчитывается на основе прогноза пополнения магазинов на несколько дней вперёд и, кроме того, на РЦ присутствует страховой запас на случай открытия магазинов или повышенного спроса. Обработка ситуаций нехватки товара на РЦ зависит от стратегии комплектации на конкретном РЦ (например, в случае нехватки распределить товар равномерно между магазинами / отгрузить товар на магазин с минимальным запасом и т.п.).NitroJunkie
09.12.2018 18:52Магазины и распределительные центры напрямую в ERP не работают. Специализированные системы, используемые в магазинах и РЦ, общаются с ERP через шину интеграции.
А они в одной базе работают или в разных, потому как если в одной — то там кейс с 50к одновременных подключений возможно даже интересней, чем кейс этой статьи с 5к подключений. Если в разных — то еще интересней, как вы администрируете / обновляете / хостите 13к баз, учитывая что у вас каждую неделю по новому релизу?
Под нехваткой товаров я имел ввиду процесс, когда скажем магазин заказывает с распредцентра, жмет сохранить и его заказ должен сразу либо подтвердиться либо программа должна выдать ошибку, после чего он сможет заказать что-то другое взамен, опять сохранить и т.д. Или у вас таких процессов (в смысле с борьбой за общий ресурс) принципиально нет?
Но вообще с нехваткой остатка это один из примеров. Ведь во многом смысл борьбы за одну базу и заключается в возможности создавать глобальные «гарантированные» ограничения, которые не могут быть нарушены из-за задержек в интеграционных процессах.chikipibarum
09.12.2018 19:20Про работу магазинов/РЦ:
Магазины и РЦ работают в разных базах (у каждого объекта своя система — т.е. да, у нас более 13000 систем со своей базой, которые являются клиентами в интеграционных процессах с ERP), асинхронно общаясь с ERP через шину интеграции. Релизы у нас в среднем раз в месяц (об этом мы писали ранее в комментариях). Описание процессов обновления/администрирования такого количества систем — это хорошая тема для отдельной статьи.
Про решение ограничений при изменении заказов и борьбу за общие ресурсы:
Интеграция магазинов с центральной системой (ERP) асинхронная, борьбы за общий ресурс в интеграционных процессах нет, изменения статусов и корректировки заказов доходят не моментально, а с гарантированной доставкой в течение короткого промежутка времени в соответствии с SLA, который обеспечен отказоустойчивой конфигурацией системы интеграции. И это тоже хороший материал для отдельной статьи.NitroJunkie
09.12.2018 20:39Спасибо за ответ, тогда все встало на свои места, а то мне было непонятно, как такая крупная компания могла жить три года в режиме, что в течении следующего условного месяца-двух, весь ее бизнес может тупо встать. А тут получается речь шла не о «втором» уровне — бэке («первый» — фронт), а о «третьем» — управленческом уровне. Конечно при его клинче, приятного тоже мало было бы, но запасной план можно было придумать.
В любом случае было реально интересно, буду ждать ваши следующие статьи.
Madmess
10.12.2018 11:28У вас Oracle сейчас на POWER работает?
Переход на Exadata рассматривается как альтернатива?laoleesch
10.12.2018 13:48Да, сейчас БД на POWER. Exadata полноценно тестировали 3 года назад, показала хорошую производительность на нашем профиле, но сопоставимую с single x86_64 на «флешах». Регулярно, как говорил выше в комментариях, возвращаемся к мыслям и просчетам RAC, как на кастомной инфраструктуре, так и appliance от вендора. Но пока остаемся в текущей архитектуре после оценок рисков, например, таких как смена профиля нагрузки вместе с архитектурой/ОС, усложнение инфраструктуры, высокие расходы на sync нод под высоконагруженый OLTP на текущем объеме и потенциальные проблемы, и прочих прочих плюсов-минусов, нюансов миграции и т.п.
DenisTrunin
10.12.2018 15:39А классический вопрос — вы в ЦО остатки по магазинам видите? с какой задержкой?
chikipibarum
10.12.2018 16:06В ERP в процессе пополнения запасов при составлении прогноза учитываются текущие остатки товаров и продажи за предыдущие дни. Данные об отгрузках или возвратах товаров приходят в течение дня в систему POS DM, в которой уже агрегируются (в разрезе магазинов по товарам) и передаются в ERP. Основная часть данных по продажам приходит в POS DM и в агрегированном виде передаётся в ERP после закрытия кассового дня (в конце рабочего дня), обрабатывается и приводит к обновлению остатков перед запуском процесса расчёта пополнения запасов. Таким образом, актуальные данные по остаткам на конкретную дату в ERP мы видим с задержкой не более суток.
alvin777
Интересно, что highload'у есть место и в «кровавом энтерпрайзе»