Райффайзенбанк нашел оригинальный способ резко повысить надежность ИТ-системы
Рост количества клиентов, проникновение мобильного банка с одной стороны, рост объема данных, а также вариаций их использования – с другой, неизбежно приводят к повышению нагрузки на системы и, как следствие, необходимости масштабирования банковской ИТ-инфраструктуры. Про развитие банковских платформ, методы снижения нагрузки и повышения надежности рассказал Михаил Антонов, руководитель направления развития прикладных платформ Core Banking Райффайзенбанка.
Содержание |
Централизованная автоматизированная банковская система (АБС) банка помещается в серверной стойке вы выше человеческого роста. Сервер и банковские системы должны быть производительными, надежными и отказоустойчивыми. Это одно из главных условий существования банка на рынке. Поэтому снижение нагрузки и масштабирование систем – наша постоянная и первоочередная задача. Но чтобы понять, как защитить систему, сначала нужно разобраться в природе наиболее частых причин сбоев.
Виды нагрузок и что бывает, если их неправильно сочетать
Мы возьмем для примера одну из банковских систем, входящих в комплекс АБС, которая позволяет банку работать 24/7, создавать транзакции, рассчитывать балансы по счетам, обрабатывать операции по дебетовым картам в режиме реального времени и многое другое.
Но прежде чем начать разговор про систему, нужно сделать шаг назад – к основам. Существует два основных типа нагрузки на базы данных: OLTP (online transaction processing) и OLAP (online analytical processing).
OLTP – это обработка транзакций в реальном времени, для нее характерно большое количество транзакций, их быстрая обработка с быстрой записью в базу данных. Типичные примеры OLTP-активностей: запрос баланса счета, авторизация по карте, создание движения по счету. Для примера, рассматриваемая нами OLTP-система может обрабатывать 1,5 тыс. запросов баланса и 1,7 тыс. карточных авторизаций в секунду.
OLAP – интерактивная аналитическая обработка — технология обработки данных, которая подразумевает суммарную (агрегированную) информацию на основе больших массивов данных. Это медленные, сложные запросы с обращением к большому количеству данных.
Признак плохого дизайна приложений – это совмещение разных видов нагрузок на одном сервере, потому что аналитические запросы легко приводят к повышенному потреблению процессора и дисков, а зачастую к их полной утилизации. При этом сервер должен всегда иметь запас мощности, время ответа должно быть предсказуемым и минимальным, ведь от этого зависит, насколько быстро клиент сможет совершить операцию или получить нужную информацию из банковской системы.
Типичный случай: готовится какой-нибудь несрочный аналитический отчет, существенно повышая нагрузку на систему. Из-за этого база данных не отвечает на OLTP-запросы за определенный промежуток времени. В результате мобильный банк, например, может не дождаться ответа и начать отправлять повторные запросы, еще больше нагружая систему, или некорректно обработать информацию, и информация на экране мобильного приложения отобразится неверно. Таким образом, сервисы могут стать на какое-то время недоступны клиентам.
Нужно учитывать, что с переходом пользователей в цифровые каналы нагрузка на системы банка постоянно растет. К примеру, только с начала 2020 года количество запросов в подсистемы АБС от «Райффайзен-Онлайн» выросло на треть. Поэтому снижение нагрузки и масштабирование систем – наша постоянная и первоочередная задача.
Что же делать?
Существует несколько путей повышения производительности и снижения нагрузки на системы или платформы
1. Купить больше ресурсов, больше процессоров. Это самый простой путь, но его сложно назвать оптимальным, если компания использует только его. Стоимость каждого сервера исчисляется сотнями тысяч долларов.
2. Оптимизировать код.
3. Перенести OLTP-нагрузки на другие, более дешевые серверы.
4. Вынести OLAP на отдельный сервер.
Мы в Райффайзенбанке, конечно, движемся во всех четырех направлениях, но наибольший интерес представляют второе и третье, так как для них банк не несет существенных затрат, как в случае с покупкой новых мощных процессоров, при этом эффективность работы существующих повышается в разы.
Два принципа оптимизации кода
В вопросе повышения производительности систем работает принцип Парето: 20% усилий дают 80% результата, а остальные 80% усилий – всего 20% результата. Постоянный поиск и устранение недостатков в процессах и работе систем с помощью оптимизации кода – крайне эффективный метод, это и есть те 20% усилий. Прирост аппаратной части, то есть покупка новых серверов, далеко не всегда дает даже прямо пропорциональное увеличение производительности, поэтому оптимизация кода очень важна.
Так, мы заметили, что в нашей системе возникали неожиданные задержки при обработке запросов баланса по картам. Эти задержки впоследствии отражались на использовании ресурсов, заметно увеличивая их потребление. Поиск решения совместно с вендором, с профессиональным сообществом не помогли нам справиться с проблемой, а часто даже приводили к ухудшению производительности или другим ошибкам. Однажды мы попробовали переписать 20% кода, перейдя c использования языка SQL в наших программах на проприетарный язык системы. Новая версия системы позволила сразу же сократить нагрузку на процессор от запросов мобильного банка в два раза.
Есть и второе правило, которое должно работать, если вы решите оптимизировать код: прежде, чем класть все яйца в одну корзину, убедись, что вы построили действительно надежную корзину. Другими словами, нужно обязательно иметь надежно работающий неоптимизированный вариант кода, который застрахует вас от коллапса в случае, если в ваших доработках вы что-то не учли. Он должен быть всегда наготове и включаться простым изменением конфигурации. Наша программа работала гарантированно хорошо, поэтому мы могли смело экспериментировать.
Быстрее, надежнее, дешевле: как кэшировать OLTP-запросы
Решение, о котором пойдет речь, напрямую связано с техническими задержками, таблицу значений которых обязан знать каждый программист.
Чтение из кэша процессора | 7 наносекунд |
Чтение 1 Мбайт данных из оперативной памяти | 250 микросекунд ( 0.25 миллисекунд) |
Чтение 1 Мбайт данных SSD | 1 миллисекунда |
Чтение 1 Мбайт с жесткого диска | 20 миллисекунд |
Не стоит забывать и о сетевых задержках: пакет данных, отправленный по сети из Москвы во Владивосток и обратно будет путешествовать еще дольше, около 150-200 миллисекунд.
Когда-то «Райффайзен-Онлайн» отправлял все запросы баланса напрямую в подсистемы АБС для расчета балансов, они рассчитывали баланс, хранящийся на жестких и SSD-дисках и возвращали результат. При этом клиент может несколько раз за день открыть мобильное приложение, в котором каждый раз должен отобразиться актуальный баланс по картам и счетам. Количество таких запросов быстро растет, потому что стабильно растет количество клиентов и проникновение мобильного банка.
Мы провели анализ нагрузки и поняли, что больше половины запросов, приходящих из онлайн-банка к нам, приходят повторно. Связано это с моделью поведения клиента в системе. Активные клиенты заходят в онлайн-банк по нескольку раз в день и часто переключатся между экранными формами со списками счетов.
Чтобы помочь росту бизнеса и снизить нагрузку на диски и процессор АБС, мы создали новый кэширующий слой и разместили его между «Райффайзен-Онлайн» и системой. Кэш – это промежуточный буфер с быстрым доступом к данным, которые располагаются в оперативной памяти, содержащий информацию, которая может быть запрошена с наибольшей вероятностью.
При разработке кеширующего слоя мы использовали бесплатные Open Source технологии, распределенную базу данных с открытым исходным кодом Apache Ignite, и недорогое железо. Решение было спроектировано так, чтобы в дальнейшем его можно было масштабировать. Как же оно работает?
Когда клиент банка открывает мобильное приложение в первый раз за день, «Райффайзен-Онлайн» формирует запрос баланса по всем доступным счетам и картам. Запрос попадает в кэш, который проверяет, нет ли в быстрой оперативной памяти этого баланса. Убеждается, что нет, и отправляет запрос в систему. Та рассчитывает баланс, кэш сохраняет его в памяти и возвращает клиенту. На весь этот путь тратится всего около 10 миллисекунд.
Когда клиент заходит в приложение повторно, запрос баланса приходит в кэш, система находит его в оперативной памяти и сразу возвращает его клиенту. На такой маршрут тратится всего 1 миллисекунда. Одновременно с этим система следит, не произошло ли движение по счету, и если такое происходит, то старый баланс удаляется из памяти, а запрос баланса снова направляется на бэкенд. Мы посчитали и убедились, что количество запросов, которые ходят по длинному маршруту, всего 15%, остальные 85% попадают в кэш. При запуске этого решения нагрузка на подсистемы АБС от «Райффайзен-Онлайн» упала примерно на треть.
От системы к пользовательскому опыту
Таким образом, создав дополнительный слой для OLTP-нагрузки, мы снизили нагрузку на систему и получили возможность горизонтально масштабировать новый сервис. Скорость отклика увеличилась примерно в 15 раз, а стоимость решения, если сравнивать с простым наращиванием инфраструктуры на бэкенде, оказалась ниже в несколько раз. Что немаловажно, мы повысили надежность всего решения, так как снижение нагрузки на бэкенд дает дополнительный запас прочности.
Снижая нагрузку на банковские приложения, оптимизируя код и перенося часть данных в оперативную память, мы можем быстрее обрабатывать запросы, а это значит, что клиенты банка сразу видят результаты запросов и их пользовательский опыт улучшается. Конечно, мы не планируем на этом останавливаться, и в наших планах – дальнейшее расширение функциональности кэширующего слоя, вынесение OLAP-нагрузки на отдельный сервер, обновление железа на более современное и непрерывная оптимизация наших приложений.