Skip to content

Курсовая работа по дисциплине "Проектирование высоконагруженных систем". Технопарк. 2025. Осень

Notifications You must be signed in to change notification settings

abdullShah/TP_Highload

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

34 Commits
 
 
 
 
 
 
 
 

Repository files navigation

Сбербанк как highload-система в финтехе

ЗаданиеМетодические указания

ВедомостьТаблица отчетности

ЗащитаПрезентация

Содержание

1. Тема и целевая аудитория

2. Расчет нагрузки

3. Глобальная балансировка нагрузки

4. Локальная балансировка нагрузки

5. Логическая схема БД

6. Физическая схема БД

7. Алгоритмы

8. Технологии

9. Обеспечение надёжности

10. Схема проекта

11. Список серверов

Источники

Приложения

1. Тема и целевая аудитория

Тема

Сервис: Сбербанк Онлайн

Аналоги: Тбанк, ВТБ, Альфа-банк, Райффайзенбанк

Целевая аудитория

Каждый 100-ый взрослый человек на Земле использует Сбербанк Онлайн [2].

Соотношение мужской аудитории к женской - 45% на 55% [2].

Рост аудитории на 2019 г. [2]:

  • +61% - среди клиентов старше 45 лет;
  • +41% - младше 20 лет;
  • +29% - 20 до 45 лет.

За пределами России услугами Сбербанка пользовались около 675 тыс. клиентов. [7]

Страна Число клиентов
Казахстан >1 млн. [8]
Беларусь 700 тыс. [8]
Украина 120 тыс. [8]
Сербия 150 тыс. [7]
Чехия 125 тыс. [7]
Европейские страны >700 тыс. [8]

Доля Сбербанка на рынке в России [1]:

  • Активы: 30.1%
  • Депозиты физических лиц: 44.6%
  • Кредиты физическим лицам: 41.4%
  • Корпоративные кредиты: 32.8%
  • Зарплатные клиенты: 56.6%
  • Остатки на кредитных картах: 45.2%
  • Ипотечные кредиты: 55.8%

Вклады чаще всего открывают 20 - 29-летние - 33% [2].

Кредиты больше всех оформляют 30 - 39-летние - 47% [2].

Женщины оформляют почти 60 % всех кредитов и вкладов [2].

Функциональность системы

Функции, характеризующие сервис:

  • Просмотр баланса и истории операций
  • Денежные переводы :между своими счетами, другим клиентам Сбера, по номеру телефона
  • Оплата услуг: ЖКХ, штрафы, налоги, мобильная связь
  • Открытие вкладов и оформление кредитов
  • Пуш-уведомления о транзакциях
  • Антифрод, проверка безопасности

Ключевой функционал сервиса - проведение платежей и переводов

2. Расчет нагрузки

Продуктовые метрики

Метрика Значение
Активные клиенты, 2025 г. >110 млн (+0,5 млн с начала года) [6]
Monthly Active Users (приложение + веб), 2025 84.3 млн [6], [5], [3]
Daily Active Users (приложение + веб), 2025 42.5 млн [6], [5]
Соотношение DAU/MAU, 2025 >50% [6]
Новые сессии в минуту, 2023 г. 110 тыс./мин. [4]
Активные сессии одновременно, 2023 г. >550 тыс. [4]
Длительность активной сессии, 2023 г. ~5 мин. [4]
Частота входов на одного клиента, 2019 25 раз в месяц [2]

Технические метрики

Объем хранилища

В месяц человек пользуется сервисом 25 раз, а средняя продолжительность одной сессии - 5 минут.
Совокупное время пребывания пользователя в приложении в месяц:
25 * 5 мин. = 125 мин.

При условии совершения 1 транзакции в минуту в спокойном режиме, среднее количество транзакций на одного пользователя в месяц составляет:
125 транзакций.

Средний размер одного электронного чека: 60 КБ (максимум 100 КБ).
Тогда объём данных на одного пользователя в месяц:
125 транзакций * 60 КБ = 7500 КБ ≈ 7.32 МБ.

Ежемесячная аудитория приложения - 84.3 млн пользователей.
Значит, ежемесячный объём данных для всей аудитории:
84.3 млн * 7.32 МБ ≈ 588.5 ТБ.

Годовой объём:
12 месяцев * 588.5 ТБ ≈ 7.1 ПБ.

ПАО Сбербанк функционирует с 1991 года, то есть на момент 2025 года - 34 года.
Совокупный объём данных за весь период (при условии стабильной ежемесячной аудитории и активности):
34 года * 7.1 ПБ ≈ 241.4 ПБ.

RPS (Requests Per Second)

Суммарное кол. запросов в секунду (RPS) составляет >120 тыс./сек. [4].

Предположим, что за 5-минутную сессию типичный пользователь совершает:

Действие Раз за сессию Раз в сутки *
Авторизация 1/30 ≈ 0.033 [9] 1,4 тыс
Получение баланса 2-3 106.25 млн
Получение чека 0.3–0.6 19.13 млн
История платежей 2/7 ≈ 0.3 12.7 млн
Открытие вкладов - 1.5 тыс [15]
Открытие кредит - 50 тыс [16]
Открытие ипотек - 3.1 тыс [17]
Перевод по СБП - 50.5 млн [13]
Перевод по QR - 11 млн [10], [11]
Оплата по биометрии - 660 тыс [10], [11]
Оплата банковскими картами - 163 млн [12]
Перевод международный - 4.7 тысяч [14]

* Рассчитано на основе DAU = 42.5 млн и 1 сессии на активного пользователя в день.

Тип запроса Средний RPS (Операций в сутки / 86 400) Пиковый RPS (тройной средний RPS)
Авторизация 16 48
Получение баланса 1230 3689
Получение чека 221 664
История платежей 147 441
Открытие вкладов 0.02 0.06
Открытие кредит 0.6 1.8
Открытие ипотек 0.04 0.12
Перевод по СБП 584 1752
Перевод по QR 127 381
Оплата по биометрии 8 24
Оплата банковскими картами 1887 5661
Перевод международный 0.05 0.15
ИТОГО 4221 12662

Сетевой трафик

Запросов в секунду (RPS) составляет 221. Также средний размер одного чека — 60 КБ = 61440 байт.

Тогда объём данных в секунду:
221 запросов/сек * 61440 байт = 13 578 240 байт/с ≈ 108.6 Мбит/с — пиковое потребление.

Суммарный суточный объём данных:
13 578 240 байт/с * 86 400 сек = 1 173 159 936 000 байт ≈ 1 173 ГБ/сутки ≈ 1.17 ТБ/сутки.

3. Глобальная балансировка нагрузки

Функциональное разбиение по доменам

Домен Функционал Средний RPS Пиковый RPS Распределение нагрузки, %
wallet Получение баланса, чела и истории платежей 1598 4794 37,9
transaction Открытие вкладов, кредитов, вкладов; оплата по СБП, QR, биометрии, банковскими картами, международные 2607 7818 62,1
api Весь остальной функционал, в частности, авторизация

* Составлено на основе таблицы из раздела "Расчет нагрузки".

Расположение ДЦ

Группировка ДЦ по регионам (приложение B). Рассматривались города-миллионники.

Центральный регион

Город Население Доля от РФ DAU (общий DAU * доля от РФ)
Москва ~13.1 млн 9.0% 3 825 000
Нижний Новгород ~1.2 млн 0.8% 340 000
Воронеж ~1.0 млн 0.7% 297 500
Волгоград ~1.0 млн 0.7% 297 500
Итого ~16.4 млн 11.2% 4 760 000

Северо-Западный регион

Город Население Доля от РФ DAU
Санкт-Петербург ~5.6 млн 3.8% 1 615 000
Итого ~5.6 млн 3.8% 1 615 000

Уральский регион

Город Население Доля от РФ DAU
Екатеринбург ~1.5 млн 1.1% 467 500
Челябинск ~1.2 млн 0.8% 340 000
Уфа ~1.2 млн 0.8% 340 000
Пермь ~1.0 млн 0.7% 297 500
Итого ~4.9 млн 3.4% 1 445 000

Сибирский регион

Город Население Доля от РФ DAU
Новосибирск ~1.6 млн 1.1% 467 500
Красноярск ~1.2 млн 0.8% 340 000
Омск ~1.1 млн 0.8% 340 000
Итого ~3.9 млн 2.7% 1 147 500

Приволжский регион

Город Население Доля от РФ DAU
Казань ~1.3 млн 0.9% 382 500
Самара ~1.2 млн 0.8% 340 000
Итого ~2.5 млн 1.7% 722 500

Южный регион

Город Население Доля от РФ DAU
Ростов-на-Дону ~1.1 млн 0.8% 340 000
Краснодар ~1.1 млн 0.8% 340 000
Итого ~2.3 млн 1.6% 680 000

Сводка по всем регионам

Регион Население DAU Доля от общего DAU
Центральный ~16.4 млн 4 760 000 11.2%
Северо-Западный ~5.6 млн 1 615 000 3.8%
Уральский ~4.9 млн 1 445 000 3.4%
Сибирский ~3.9 млн 1 147 500 2.7%
Приволжский ~2.5 млн 722 500 1.7%
Южный ~2.3 млн 680 000 1.6%

Сводка по всем рассмотренным городам для размещения ДЦ (по DAU)

Город Регион DAU Доля от общего DAU Приоритет
Москва Центральный 3 825 000 9.0% Критический
Санкт-Петербург Северо-Западный 1 615 000 3.8% Высокий
Екатеринбург Уральский 467 500 1.1% Высокий
Новосибирск Сибирский 467 500 1.1% Высокий
Казань Приволжский 382 500 0.9% Средний
Нижний Новгород Центральный 340 000 0.8% Средний
Челябинск Уральский 340 000 0.8% Средний
Уфа Уральский 340 000 0.8% Средний
Красноярск Сибирский 340 000 0.8% Средний
Омск Сибирский 340 000 0.8% Средний
Самара Приволжский 340 000 0.8% Средний
Ростов-на-Дону Южный 340 000 0.8% Средний
Краснодар Южный 340 000 0.8% Средний
Воронеж Центральный 297 500 0.7% Низкий
Волгоград Центральный 297 500 0.7% Низкий
Пермь Уральский 297 500 0.7% Низкий

Сводная таблица RPS доменов по ДЦ

RPS домена в городе = (DAU города / общий DAU) * Общий RPS домена

ДЦ DAU RPS wallet RPS transaction Сумма пред. RPS
Москва 3 825 000 144 235 379
Санкт-Петербург 1 615 000 61 99 160
Екатеринбург 467 500 18 29 47
Новосибирск 467 500 18 29 47
Казань 382 500 14 23 37
Ростов-на-Дону 340 000 13 21 34

Таблица расстояний между городами (км)

Город Москва Санкт-Петербург Екатеринбург Новосибирск Казань Ростов-на-Дону
Москва - 710 1 420 3 360 820 1 090
Санкт-Петербург 710 - 2 130 3 380 1 530 1 800
Екатеринбург 1 420 2 130 - 1 460 1 140 2 080
Новосибирск 3 360 3 380 1 460 - 2 350 3 540
Казань 820 1 530 1 140 2 350 - 1 530
Ростов-на-Дону 1 090 1 800 2 080 3 540 1 530 -

Расчет примерной задержки связи между ДЦ (мс)

По примеру приложения A.

Формула: Задержка = (Расстояние * 1.7) / 200 + 10 мс, где:

  • 1.7 - коэффициент увеличения пути (оптоволокно не идет по прямой),
  • 200 - скорость распространения сигнала в оптоволокне (км/мс) [18],
  • 10 мс - запас на сетевое оборудование и маршрутизацию.
Город Москва Санкт-Петербург Екатеринбург Новосибирск Казань Ростов-на-Дону
Москва - 11 [0] 22 39 17 19
Санкт-Петербург 11 [0] - 28 39 23 25
Екатеринбург 22 28 - 22 20 28
Новосибирск 39 39 22 - 30 40
Казань 17 23 20 30 - 23
Ростов-на-Дону 19 25 28 40 23 -

Схемы балансировки

DNS - самый простой механизм балансировки, и балансировать таким образом можно любые системы, в которых доступ к сервису происходит по имени [19].

Суть балансировки на базе Anycast: мы из разных географических участков анонсируем один и тот же префикс сети. Таким образом, каждый запрос клиента будет маршрутизироваться на ближайший к нему сервер, который будет его обрабатывать [19].

Вывод: глобальная балансировка нагрузки не требуется. Все пользователи могут быть направлены в единый московский ДЦ по следующим причинам:

  • 95% трафика генерируется в пределах России,
  • максимальная задержка до Москвы (таблица связи между ДЦ) не превышает 40 мс даже для Дальнего Востока.

4. Локальная балансировка нагрузки

Схема балансировки нагрузки

Схема балансировки нагрузки

Локальная балансировка нагрузки состоит из нескольких уровней:

1. Клиентский

Инициирует HTTP/HTTPS запросы.

2. L7 Балансировщики

Разделим балансировщики по доменам, так как на L7-уровне создаётся наибольшая нагрузка на CPU.

Функции:

  • SSL Termination вынесен на отдельные L7 серверы
  • Маршрутизация по хостам, соответствующим доменам
Показатель Значение
Пиковый RPS 12662
CPS (connections per second) 1-ого CPUs (ядра) для HTTPS 428 [22]
Требуется ядер 12662 / 428 = 29.6 ≈ 30 ядер
Резервные ядра, чтобы нагружать не более 60% ресурсов CPU в пике 30 ядер / 60% = 50 ядер
Ядра на один домен 50 ядер / 3 = 16.7 ≈ 17 ядер на сервер
NGINX-сервера на домен, 8-ядерные 17 ядер на сервер / 8 = 2.1 ≈ 3 машины
Схема резервирования для одного домена N+1 (2 рабочих + 1 резервный)
Всего машин 3 домена * 3 машины = 9 машин

Размещение:

  • Все L7-балансировщики размещаются в едином дата-центре в Москве с latancy равном 1.5 мс
  • Балансировщики каждого домена распределяются по разным availability-зонам в рамках ДЦ

Балансировка трафика на L7-уровне с использованием Anycast BGP:

  • Каждому домену назначен единый публичный IP-адрес, который анонсируется через BGP из всех availability-зон, где размещены его L7-серверы
  • Маршрутизаторы дата-центра получают одинаковые BGP-анонсы, но направляют трафик к ближайшей (по метрикам) availability-зоне
  • Внутри availability-зоны трафик принимается активными NGINX-серверами. В случае отказа одного из серверов, BGP-анонс остаётся активным (так как другие серверы в зоне работают), а локальный L4-балансировщик перераспределяет нагрузку между оставшимися узлами
  • При полном отказе availability-зоны BGP-маршруты из этой зоны автоматически отзываются (withdrawn), и весь трафик перенаправляется на оставшиеся

4. Application Servers

Разделение по доменам:

  • сервер Wallet
  • сервер Transaction
  • сервер API

5. Database Layer

  • Master DB - для операций записи (Transaction)
  • 2 реплики Replica DB - для операций чтения (Wallet, API)

Ограничители производительности:

Пропускная способность сети:

  • Пиковый трафик: 108.6 Мбит/с * 3 = 326 Мбит/с
  • 1 x 10G порт: 10 Гбит/с полезной нагрузки [20] [21]
  • Требуется: 326 / 10000 Мбит/с = 0.0326 порта ≈ 1 порт

Пиковый трафик составляет менее 35% от пропускной способности 1G Ethernet и менее 4% от 10G. Следовательно, сетевой интерфейс не ограничивает производительность, и даже 1G порт будет более чем достаточен.

5. Логическая схема БД

Схема таблиц

Ссылка: Схема таблиц в dbdiagram.io

Описание таблиц

Название таблицы Назначение
users Хранит профиль пользователя: контактные данные (телефон, email), хэш пароля, ФИО, дату рождения и временные метки создания/обновления.
accounts Представляет банковские счета пользователей: баланс, валюта, статус (active, blocked, closed) и привязка к пользователю (user_id).
transactions Фиксирует все денежные операции между счетами: отправитель (from_account), получатель (to_account), сумма, валюта, категория (еда, транспорт), статус, описание и тип (перевод, оплата и тп.).
receipts Хранит информацию о чеках или сканах, прикреплённых к транзакциям: путь к файлу, размер и временная метка. Связан с transactions.
user_cards Содержит данные банковских карт: зашифрованный номер, срок действия, хэш CVV, статус и привязку к пользователю.
deposits Отслеживает вклады (депозиты): сумма, процентная ставка, срок в месяцах, дата открытия и дата окончания. Привязан к счёту (account_id).
session_cache Используется для временного хранения пользовательских сессий: данные в формате JSONB и время истечения сессии.

Требования к консистентности

Современные системы работают со следующими моделями консистентности [24]:

  • Строгая консистентность (Strong Consistency) — все операции чтения возвращают значение самой последней успешной операции записи
  • Последовательная консистентность (Sequential Consistency) — операции выполняются в том порядке, в котором они были запущены в каждом узле
  • Причинная консистентность (Causal Consistency) — если операция A логически предшествует операции B, то все узлы увидят их в этом порядке
  • Итоговая консистентность (Eventual Consistency) — при отсутствии обновлений все узлы системы в конечном итоге сходятся к одному значению
Таблица Модель консистентности Обоснование, пример
users Строгая После смены email или пароля все последующие запросы должны немедленно видеть новое значение
accounts Строгая При переводе средств чтение баланса должно отражать самую последнюю успешную транзакцию
transactions Строгая После успешного завершения операции все последующие чтения должны возвращать её как существующую
receipts Итоговая Чек — подтверждающий документ, не участвующий в логике списания
user_cards Строгая Активная карта без привязки к пользователю — угроза безопасности
deposits Строгая Данные должны быть точными и синхронизированы с accounts
session_cache Итоговая Сессии временные, могут быть утеряны без ущерба для данных

Размеры таблиц

Таблица Размер таблицы, байт Расчеты
users 165 user_id(4) + phone(16) + email(30) + password_hash(60) + first_name(15) + last_name(20) + birth_date(4) + created_at(8) + updated_at(8)
accounts 40 account_id(4) + user_id(4) + balance(8) + currency(4) + status(4) + timestamps(16)
transactions 150 ids(12) + amount(8) + currency(4) + category(15) + status(10) + description(50) + type(10) + merchant(30) + timestamp(8)
receipts 120 ids(8) + file_path(100) + file_size(4) + timestamp(8)
user_cards 141 card_id(4) + user_id(4) + card_number_encrypted(50) + expiry(5) + cvv_hash(60) + status(10) + timestamp(8)
deposits 37 ids(8) + amount(8) + rate(5) + term(4) + timestamps(12)
session_cache 216 session_id(4) + user_id(4) + data(jsonb, 200) + expires(8)
Таблица Размер данных
users 110 млн * 165 байт = 17 ГБ
accounts Пусть минимум один счет у клиента: 110 млн * 40 байт = 4 ГБ
transactions На основе расчетов объема хранилища: 125 транзакций в месяц * 12 месяцев * 34 года * 84.4 млн * 150 байт = 587 ТБ
receipts Если не создавать для каждой транзакции чек, то пусть коэфф. создания будет равен 1 раз к 14 дням, то объем равен: 2 чека месяц * 12 месяцев * 34 года * 84.4 млн * 120 байт = 7.6 ТБ
user_cards Пусть минимум одна карта у клиента: 110 млн * 141 байт = 14 ГБ
deposits (2025 г. - 1981 г.) * (530 тыс (8 месяцев [15]) / 8 * 12) * 37 байт = 1.2 ГБ
session_cache Активные сессии одновременно 550 тыс * 216 байт = 113 МБ
Таблица Средняя нагрузка (QPS) на запись * Средняя нагрузка (QPS) на чтение *
users 1/182 дней / 86400 ≈ 7 2606 (оплата) + ~1 (открытие услуг) = 2607
accounts ~2606 (оплата = изменение счета) 1230 (получение баланса)
transactions 2606 (изменение status'а y оплаты) 2606 (оплата) + 147 (история платежей)
receipts 1 221 (получения чека)
user_cards 1 2606 (оплата)
deposits 1 2/30 дней / 86400 ≈ 8
session_cache 1 16 (авторизация)

* Значения основаны на таблице RPS действий.

6. Физическая схема БД

Физическая схема таблиц

Ссылка: Физическая схема таблиц в dbdiagram.io

Сводная таблица структуры базы данных

Таблица Денормализация Индексы Шардирование СУБД Резервное копирование, тип и частота
users total_balance (decimal) phone, email Нет PostgreSQL Полный + WAL
Ежемесячно + непрерывно
accounts user_phone, user_full_name (text) user_id, status, user_phone, user_full_name Нет PostgreSQL Полный + WAL
Ежедневно + непрерывно
transactions_credit to_user_name, from_user_name (text) (to_account, created_at), status, category Вертикальное + горизонтальное PostgreSQL Полный + консистентные снепшоты + WAL
Ежедневно + непрерывно
transactions_debit from_user_name, to_user_name (text) (from_account, created_at), status, category Вертикальное + горизонтальное PostgreSQL Полный + консистентные снепшоты + WAL
Ежедневно + непрерывно
transactions_global_index Нет created_at, account_id, (shard_type, account_id) Нет PostgreSQL Полный + WAL
Ежедневно + непрерывно
receipts transaction_amount, transaction_date transaction_id, transaction_date Нет PostgreSQL Полный
Ежемесячно
user_cards user_phone, user_full_name (text) user_id, status, user_phone Нет PostgreSQL Полный + WAL
Еженедельно + непрерывно
deposits current_balance (decimal) account_id Нет PostgreSQL Полный
Ежемесячно
session_cache Нет user_id Нет Redis RDB снепшоты + AOF лог
Ежечасно + непрерывно

Описание таблиц

1. users

Денормализация:

  • total_balance типа decimal(15,2) — быстрый доступ к общему балансу без JOIN с accounts

Индексы:

  • phone — для авторизации по телефону
  • email — для авторизации по email

Шардирование: отсутствует

СУБД: PostgreSQL

Схема резервного копирования:

  • Тип бэкапа: Полный + WAL
  • Частота: Ежемесячно + непрерывно

2. accounts

Денормализация:

  • user_phone типа text — данные пользователя для отчетов без JOIN с users
  • user_full_name типа text — —//—

Индексы:

  • user_id — поиск всех счетов пользователя
  • status — фильтрация по статусу счета: active, blocked, closed
  • user_phone — быстрый поиск владельца по телефону
  • user_full_name — —//— по имени

Шардирование: отсутствует

СУБД: PostgreSQL

Схема резервного копирования:

  • Тип бэкапа: Полный + WAL
  • Частота: Ежедневно + непрерывно

3. transactions_credit

Денормализация:

  • to_user_name типа text — данные для отчетов без JOIN с users
  • from_user_name типа text — —//—

Индексы:

  • (to_account, created_at) — история операций по счету
  • status — фильтрация по статусу операций: pending, completed, failed
  • category — аналитика по категориям пополнений

Шардирование:

  • вертикальный (доменный): transactions шардируется по типу операций — все зачисления на счет находятся в одном домене
  • горизонтальный: максимальный размер таблицы 32 ТБ [25], однако в шарде оптимально хранить около 1 ТБ, но не более 2 ТБ [0], поэтому таблицу разнесем на 587 ТБ / 1 ТБ = 587 частей по ключу to_account

СУБД: PostgreSQL

Схема резервного копирования:

  • Тип бэкапа: Полный + консистентные снепшоты* через WAL
  • Частота: Ежедневно + непрерывно

* Чтобы избежать случая когда:

  • В t времени первый шард бэкапится, когда, например, операция снятия уже в бэкапе
  • В t+n времени второй шард бэкапится, когда, например, операция пополнения еще не в бэкапе
  • Получаем, что при восстановлении сняли деньги, но другой не получил

Поэтому алгоритм:

  1. Фиксируем точку консистентности
  2. Бэкапим каждый шард независимо
  3. При восстановлении применяем WAL до зафиксированной точки

4. transactions_debit

Денормализация:

  • from_user_name типа text — данные для отчетов без JOIN с users
  • to_user_name типа text — —//—

Индексы:

  • (from_account, created_at) — история операций по счету
  • status — фильтрация по статусу операций
  • category — аналитика по категориям расходов

Шардирование:

  • вертикальное (доменное): transactions шардируется по типу операций — все списания со счета находятся в одном домене
  • горизонтальное: максимальный размер таблицы 32 ТБ [25], однако в шарде оптимально хранить около 1 ТБ, но не более 2 ТБ [0], поэтому таблицу разнесем на 587 ТБ / 1 ТБ = 587 частей по ключу from_account

СУБД: PostgreSQL

Схема резервного копирования: аналогично transactions_credit


5. transactions_global_index Глобальный индекс для поиска транзакций в нужной шарде. shard_type типа text: 'credit' или 'debit' — указывает в какой таблице искать.

Денормализация: отсутствует

Индексы:

  • created_at — поиск транзакций за период
  • account_id — поиск всех транзакций пользователя
  • (shard_type, account_id) — поиск транзакций определенного типа

Шардирование: отсутствует

СУБД: PostgreSQL

Схема резервного копирования:

  • Тип бэкапа: Полный + WAL
  • Частота: Ежедневно + непрерывно

6. receipts

Денормализация:

  • transaction_amount типа decimal(15,2) — данные для отображения без JOIN с transactions
  • transaction_date типа timestamp — —//—

Индексы:

  • transaction_id — поиск чека по транзакции
  • transaction_date — поиск чеков за период

Шардирование: отсутствует

СУБД: PostgreSQL

Схема резервного копирования:

  • Тип бэкапа: Полный
  • Частота: Ежемесячно
  • Хранилище: облачный S3

7. user_cards

Денормализация:

  • user_phone типа text — для быстрого отображения без JOIN с users
  • user_full_name типа text — —//—

Индексы:

  • user_id — поиск всех карт пользователя
  • status — фильтрация по статусу карты: active, blocked, expired
  • user_phone — быстрый поиск по телефону владельца

Шардирование: отсутствует

СУБД: PostgreSQL

Схема резервного копирования:

  • Тип бэкапа: Полный + WAL
  • Частота: Еженедельно + непрерывно

8. deposits

Денормализация:

  • current_balance типа decimal(15,2) — данные для отображения без JOIN с accounts

Индексы:

  • account_id — поиск депозитов по счету

Шардирование: отсутствует

СУБД: PostgreSQL

Схема резервного копирования:

  • Тип бэкапа: Полный
  • Частота: Ежемесячно

9. session_cache

Денормализация: отсутствует

Индексы:

  • user_id — поиск сессии по пользователю

Шардирование: отсутствует

СУБД: Redis

Схема резервного копирования:

  • Тип бэкапа: RDB снепшоты + AOF лог
  • Частота: Ежечасно + непрерывный

7. Алгоритмы

Таблица алгоритмов

Алгоритм Область применения Мотивация
Ключ идемпотентности:

1. Клиент генерирует уникальный ключ для каждой операции
2. При первом запросе в поле БД устанавливается в поле idempotency_key ключ, переданных клиентом
3. При повторном запросе с тем же ключом возвращается существующий результат, новый не создается
Любые финансовые операции списания/зачисления: начисление процентов по вкладам deposits, переводы transactions Гарантия, что операция выполнится ровно один раз даже при повторных вызовах
Двусвязные коммиты (2PC) Операции в рамках одной СУБД, затрагивающие несколько таблиц.

Например, при переводе денег между клиентами: изменение баланса в accounts у обоих клиентов + добавление строки списывания и пополнения в transactions соответственно
Обеспечение согласованности данных в транзакциях, выходящих за пределы одной системы, сохранить семантику единой атомарной транзакции [26]

8. Технологии

Таблица технологий

Технология Область применения Мотивационная часть
Go микросервисы Backend'а wallet, transaction, api Высокая производительность при 12 662 RPS, эффективное управление памятью, асинхронность (встроенные горутины для параллельной обработки транзакций)
Kotlin Мобильные приложения (Android) Стабильность, богатая экосистема библиотек
Swift Мобильные приложения (iOS) Интеграция с iOS экосистемой
TypeScript Web-интерфейс Статическая типизация, интеграция с React и Next.js
PostgreSQL Данные users, accounts, transactions, deposits ACID-транзакции для финансовых операций, поддержка шардинга и 2PC
Redis Кэш сессий session_cache In-memory хранение для горячих данных (550 тыс активных сессий), автоматическое удаление просроченных сессий (TTL)
NGINX L7 балансировка SSL Termination для HTTPS, маршрутизация по доменам
Kubernetes Оркестрация микросервисов Автомасштабирование под нагрузкой, управление серверами балансировки
Prometheus Мониторинг Сбор метрик с балансировщиков и микросервисов
Grafana Визуализация метрик Дашборды для мониторинга RPS, задержек, ошибок транзакций
ClickHouse Аналитика и отчетность Реалтайм-аналитика транзакций, отчеты ЦБ РФ, ML-модели для выявления мошенничества
HashiCorp Vault Управление секретами Безопасное хранение ключей шифрования, токенов API, паролей БД

9. Обеспечение надёжности

Таблица обеспечения надёжности

Компонент системы Способы резервирования
L7 Балансировщики (NGINX) - Распределение: Active-Active кластер с N+1 репликами по трём availability-зонам с Anycast BGP балансировкой трафика [27]
- Отказоустойчивость: Автоматическое переключение трафика при отказе зоны
- Защита: Rate limiting для предотвращения перегрузки
- Мониторинг: Health checks с автоматическим исключением и рестартом неработающих нод
Сервера приложений (микросервисы) - Оркестрация: Kubernetes ReplicaSet с N+1 по трём availability-зонам репликами на сервис
- Управление нагрузкой: Автомасштабирование по метрикам CPU и памяти
- Безопасное завершение: Graceful Shutdown для сохранения целостности данных
- Деградация: Graceful Degradation при частичных отказах
- Самовосстановление: Health checks с автоматическим рестартом контейнеров
Базы данных PostgreSQL - Оркестрация: Patroni для автоматического управления кластером
- Доступность: реверс-проксёй Odyssey обслуживать много клиентов, используя небольшой пул соединений к БД
- Репликация: Master + 2 реплики
- Резервное копирование: WAL + полные снепшоты
Кэш Redis (сессии) - Оркестрация: Redis Sentinel для мониторинга и автоматического failover
- Кластеризация: Redis Cluster с архитектурой master-slave
- Синхронизация: Репликация в реальном времени между узлами
- Персистентность: Комбинирование RDB и AOF для сохранения данных
Дата-центры - Инфраструктура: Tier-4 архитектура
- Сети: Избыточная схема сети
- Энергоснабжение: Схема подачи питания
- Охлаждение: Избыточная система охлаждения (приложение D)
- География: Стратегическое физическое положение для минимизации рисков

Дополнительные механизмы обеспечения надежности:

  • Мониторинг: Комплексный сбор метрик через Prometheus с визуализацией в Grafana и настройка Alert Manager в случае аварий
  • Аналитика: Централизованное логирование с помощью сквозной трассировки Trace ID для выявления и анализа инцидентов
  • Тестирование: Регулярные chaos-тесты для проверки отказоустойчивости и учения команды по аварийным ситуациям

10. Схема проекта

Схема проекта

11. Список серверов

Расчёт для сервисов

Микросервисы на Go

Для Go сервисов используем оценку: 1000 RPS на 1 ядро CPU [28].

Компонент Средний RPS Пиковый RPS (×3) Требуется ядер CPU RAM на экземпляр Назначение
Микросервис Transaction 2 607 7 818 ⌈7818 / 1000⌉ = 8 2 ГБ Обработка финансовых транзакций, требует строгой консистентности
Микросервис Wallet 1 598 4 794 ⌈4794 / 1000⌉ = 5 2 ГБ Получение баланса, истории платежей, умеренная нагрузка
Микросервис API 16 48 ⌈48 / 1000⌉ = 1 1 ГБ Авторизация и вспомогательные операции, низкая нагрузка

NGINX L7 Балансировщики

Для NGINX используем оценку: 428 CPS (connections per second) на 1 ядро CPU для HTTPS [22].

Компонент Пиковый RPS Требуется ядер CPU RAM на экземпляр Назначение
NGINX L7 (всего) 12 662 ⌈12662 / 428⌉ = 30 ядер
С учетом 60% загрузки: 50 ядер
4 ГБ SSL Termination, маршрутизация по доменам
NGINX на домен ~4 221 17 ядер на домен 4 ГБ Распределение по 3 доменам (wallet, transaction, api)

PostgreSQL

Для PostgreSQL используем оценку: 200 операций/сек на 1 ядро CPU.

Исходные данные [см. раздел 5]:

  • Объём данных на диске: 594 ТБ
  • Нагрузка на чтение: 9 425 QPS
  • Нагрузка на запись: 5 222 QPS
  • Суммарная нагрузка: 14 647 QPS

Рекомендации:

  • Если размер данных на диске >1 ТБ, то рекомендуемый размер RAM >256 ГБ [30]
Компонент Нагрузка QPS Требуется ядер CPU RAM Назначение
PostgreSQL Master 5 222 (запись) ⌈5222 / 200⌉ = 27 ядер32 ядра 512 ГБ Операции записи, требуется высокая производительность
PostgreSQL Replica 1 4 712 (чтение) ⌈4712 / 200⌉ = 24 ядра 512 ГБ Чтение для домена wallet
PostgreSQL Replica 2 4 713 (чтение) ⌈4713 / 200⌉ = 24 ядра 512 ГБ Чтение для домена api и резерв

PostgreSQL Шарды (хранилище исторических данных)

Исходные данные [см. раздел 5 и 6]:

  • transactions_credit: 587 ТБ, разбито на 587 шардов по 1 ТБ каждый
  • transactions_debit: 587 ТБ, разбито на 587 шардов по 1 ТБ каждый
  • receipts: 7.6 ТБ
  • Итого: 1181.6 ТБ данных, 1174 шарда + receipts

Расчёт серверов для хранения шардов:

  • Каждый шард содержит ~1 ТБ данных (с учетом индексов и служебных данных ~1.2 ТБ)
  • На одном сервере размещаем до 8 шардов (8 ТБ данных + запас для WAL, индексов, временных файлов = ~10 ТБ на сервер)
  • Требуется серверов: ⌈1174 / 8⌉ = 147 серверов для шардов
  • Для receipts требуется: ⌈7.6 / 8⌉ = 1 сервер
  • Итого: 148 серверов для хранения исторических данных

Рекомендации для архивных серверов:

  • Исторические данные редко запрашиваются, поэтому можно использовать менее производительные, но более ёмкие сервера
  • Для отказоустойчивости требуется репликация: каждая реплика хранит копию шардов
  • Используем конфигурацию с большим объёмом дисков, но меньшим количеством CPU и RAM
Компонент Объём данных Количество шардов Серверов (основных) Серверов (реплик) CPU на сервер RAM на сервер Назначение
PostgreSQL Shards (credit) 587 ТБ 587 74 74 32 ядра 128 ГБ Хранение исторических транзакций зачислений, низкая нагрузка
PostgreSQL Shards (debit) 587 ТБ 587 74 74 32 ядра 128 ГБ Хранение исторических транзакций списаний, низкая нагрузка
PostgreSQL Receipts 7.6 ТБ 1 1 1 32 ядра 128 ГБ Хранение исторических чеков, низкая нагрузка
ИТОГО 1181.6 ТБ 1175 149 149 - - -

Redis

Исходные данные [см. раздел 5]:

  • Объём данных: 113 МБ (550 тыс активных сессий × 216 байт)
  • Нагрузка на чтение: 16 QPS
  • Нагрузка на запись: 1 QPS
  • Суммарная нагрузка: 17 QPS

Допущения:

  • RPS Redis равен 35 600 единицам [29]
Компонент Нагрузка QPS Требуется ядер CPU RAM Назначение
Redis Cluster 17 1 ядро (с большим запасом) 2 ГБ Кэш сессий, низкая нагрузка, но требуется отказоустойчивость

Prometheus + Grafana

Компонент Нагрузка Требуется ядер CPU RAM Назначение
Prometheus Сбор метрик со всех сервисов 4 ядра 16 ГБ Постоянная запись временных рядов, агрегация данных
Grafana Визуализация метрик 2 ядра 8 ГБ Рендеринг дашбордов, запросы к Prometheus

ClickHouse

Компонент Нагрузка Требуется ядер CPU RAM Назначение
ClickHouse Аналитика транзакций, отчеты ЦБ РФ 8 ядер 64 ГБ Реалтайм-аналитика, ML-модели для антифрода

HashiCorp Vault

Компонент Нагрузка Требуется ядер CPU RAM Назначение
HashiCorp Vault Управление секретами 2 ядра 8 ГБ Хранение ключей шифрования, токенов API, паролей БД

Сводная таблица ресурсов

Сервис Пиковая нагрузка CPU (ядер) RAM Сеть
NGINX L7 (всего) 12 662 RPS 50 36 ГБ 326 Мбит/с
Микросервис Transaction 7 818 RPS 8 6 ГБ -
Микросервис Wallet 4 794 RPS 5 6 ГБ -
Микросервис API 48 RPS 1 2 ГБ -
PostgreSQL Master 5 222 QPS 32 512 ГБ -
PostgreSQL Replica × 2 9 425 QPS 48 (24×2) 1024 ГБ (512×2) -
PostgreSQL Shards (основные) Низкая (архив) 4 768 (32×149) 19 ТБ (128×149) -
PostgreSQL Shards (реплики) Низкая (архив) 4 768 (32×149) 19 ТБ (128×149) -
Redis Cluster 17 QPS 1 2 ГБ -
Prometheus Сбор метрик 4 16 ГБ -
Grafana Визуализация 2 8 ГБ -
ClickHouse Аналитика 8 64 ГБ -
HashiCorp Vault Секреты 2 8 ГБ -
ИТОГО - 9 646 38.7 ТБ 326 Мбит/с

Как мы видим наши сервисы не умещаются в физические сервера и требуют горизонтального масштабирования.

Выбор модели развертывания и хостинга

Был выбран гибридный подход поскольку:

  • Полностью собственное железо было бы избыточно дорогим для некритичных сервисов (ClickHouse, Vault, CI/CD), которые не требуют максимальной производительности и могут работать на виртуальных машинах
  • Полностью облачное решение не обеспечивает необходимую производительность для критически важных компонентов (PostgreSQL, NGINX, Redis), которые требуют минимального overhead и максимальной производительности bare-metal серверов
  • Гибридный подход позволяет оптимизировать затраты: размещать критичные высоконагруженные сервисы на собственном железе для максимальной производительности, а некритичные сервисы — на арендованных виртуальных машинах для экономии средств

1. Stateless сервисы в Kubernetes (на собственном железе):

  • Микросервисы (Transaction, Wallet, API) - запускаются в Kubernetes для автомасштабирования и отказоустойчивости
  • Prometheus, Grafana - мониторинг в Kubernetes
  • Kubernetes Worker Nodes - размещаются на собственном железе для обеспечения производительности

2. Stateful сервисы на bare-metal:

  • PostgreSQL (Master + 2 Replica) - критически важная БД, требует максимальной производительности и минимального overhead
  • PostgreSQL Shards (149 основных + 149 реплик) - хранилище исторических данных, низкая нагрузка, но большой объём данных
  • Redis Cluster - in-memory БД, требует низкой задержки
  • NGINX L7 балансировщики - высоконагруженные, требуют минимального overhead

3. Вспомогательные сервисы на арендованных виртуальных машинах (Hetzner):

  • ClickHouse - аналитика, не критична для основной работы системы
  • HashiCorp Vault - управление секретами, низкая нагрузка

Конфигурации серверов

Собственное железо (bare-metal)

Название Конфигурация CPU (Ядра) RAM Количество Покупка (5 лет) Аренда/мес
PostgreSQL Master 2×6338/16×32GB/2×NVMe4T/2×25Gb/s 128 512 GB 1 $18 500 $308
PostgreSQL Replica 2×6338/16×32GB/2×NVMe4T/2×25Gb/s 128 512 GB 2 $37 000 $616
PostgreSQL Shards 2×6338/4×32GB/2×NVMe10T/2×25Gb/s 32 128 GB 149 $2 235 000 $37 250
PostgreSQL Shards Repl 2×6338/4×32GB/2×NVMe10T/2×25Gb/s 32 128 GB 149 $2 235 000 $37 250
NGINX L7 2×6338/4×32GB/2×NVMe1T/2×25Gb/s 128 128 GB 9 $126 000 $2 100
Kubernetes Master 2×6338/8×32GB/2×NVMe2T/2×25Gb/s 128 256 GB 3 $45 000 $750
Kubernetes Worker 2×6338/16×32GB/2×NVMe4T/2×25Gb/s 128 512 GB 3 $55 500 $925
Redis Cluster 2×6338/4×32GB/2×NVMe512Gb/2×25Gb/s 128 128 GB 3 $30 000 $500
Итого - 9 536 38.7 ТБ 319 $4 787 000 $79 699

Примечание:

  • Серверы для шардов используют менее производительную конфигурацию (32 ядра вместо 128, 128 ГБ RAM вместо 512 ГБ), но с большим объёмом дисков (10 ТБ вместо 4 ТБ), так как исторические данные редко запрашиваются и не требуют высокой производительности.
  • Стоимость одного сервера шардов: $15 000 (149 основных + 149 реплик = 298 серверов × $15 000 = $4 470 000, включено в общую сумму).

Аренда виртуальных машин (Hetzner)

Название Хостинг Конфигурация CPU (Ядра) RAM Количество Аренда/мес
ClickHouse Hetzner i5-13500/64GB/2×NVMe512Gb/2×10Gb/s 14 64 GB 1 $80
HashiCorp Vault Hetzner i5-13500/32GB/2×NVMe256Gb/2×10Gb/s 14 32 GB 1 $50
Итого аренда - - 42 128 GB 2 $130

Суммарные затраты

Категория Серверов CPU (Ядра) RAM Покупка (5 лет) Аренда/мес
Bare-metal 319 9 536 38.7 ТБ $4 787 000 $79 699
Аренда VM 3 42 128 ГБ $7 800 $130
ВСЕГО 322 9 578 38.8 ТБ $4 794 800 $79 879

Распределение ресурсов в Kubernetes

Для сервисов в оркестрации Kubernetes указываем requests и limits для CPU и RAM, а также количество реплик.

Микросервисы

Пусть:

  • CPU requests = требуемое количество ядер / количество реплик
  • CPU limits = CPU requests × 2 (запас для пиковых нагрузок, но без throttling)
  • RAM requests = базовое потребление памяти на экземпляр
  • RAM limits = RAM requests × 2 (защита от утечек памяти)
Сервис CPU/r CPU/l RAM/r RAM/l Кол. реплик Обоснование
Микросервис Transaction 3 6 2 GB 4 GB 3 Высокая нагрузка (7818 RPS), требуется отказоустойчивость N+1
Микросервис Wallet 2 4 2 GB 4 GB 3 Средняя нагрузка (4794 RPS), требуется отказоустойчивость N+1
Микросервис API 1 2 1 GB 2 GB 2 Низкая нагрузка (48 RPS), достаточно 2 реплик

Системные сервисы

Сервис CPU/r CPU/l RAM/r RAM/l Кол. реплик Назначение
Prometheus 2 4 8 GB 16 GB 2 Сбор метрик со всех сервисов, требуется отказоустойчивость
Grafana 1 2 4 GB 8 GB 2 Визуализация метрик, требуется отказоустойчивость

Сводная таблица ресурсов Kubernetes

Сервис CPU/r (всего) CPU/l (всего) RAM/r (всего) RAM/l (всего) Кол. реплик (всего)
Микросервис Transaction 12 24 6 GB 12 GB 3
Микросервис Wallet 7.5 15 6 GB 12 GB 3
Микросервис API 2 4 2 GB 4 GB 2
Prometheus 4 8 16 GB 32 GB 2
Grafana 2 4 8 GB 16 GB 2
ИТОГО 27.5 55 38 GB 76 GB 12

Распределение по Worker Nodes:

  • 3 Worker Nodes с конфигурацией 128 ядер CPU / 512 GB RAM каждая
  • Общая емкость: 384 ядра CPU / 1536 GB RAM
  • Использование: 27.5 ядер (7.2%) / 38 GB (2.5%) - большой запас для масштабирования

Источники

  1. Экспертная оценка, опыт Александра Быкова :)
  2. На-Связи.ru - Статистика Сбербанка на 2018 год
  3. Амурская правда - Статистика пользователей Сбербанк Онлайн
  4. VK - Статистика месячной аудитории на 2023 год
  5. Habr - 110 тысяч новых сессий в минуту: архитектура Сбербанк Онлайн
  6. Bankinform - Клиентская база Сбербанка в 2025 году
  7. SberBank Investor Relations - Финансовая отчетность за 7 месяцев 2025 года
  8. В каких странах есть офисы Сбербанка? - Рамблер/личные финансы
  9. Российские банки за рубежом: какие банки есть в Европе, США
  10. Как часто пользователи взаимодействуют с приложением?
  11. Центробанк РФ - Заседание по финстабильности, 28 августа 2025
  12. Интерфакс - Бизнес новости, 28 августа 2025
  13. Клерк.ру: Последние изменения для бухгалтеров, 10 июня 2025
  14. ЦБ РФ: Аналитический обзор Системы быстрых платежей, 2025 год
  15. ВТБ сообщает о семикратном росте международных переводов, октябрь 2024
  16. Актуальные события в банковской сфере, 28 июля 2025 г.
  17. Finance.Mail.ru: Выдача потребительских кредитов в России в июле выросла на 13%
  18. РБК Недвижимость: Новости рынка недвижимости
  19. Занимательный оптокабель
  20. Сравнительный анализ методов балансировки трафика. HighLoad++ Junior / Хабр
  21. What is the difference between 10G and 2.5G ports?- Walsun
  22. Типы портов коммутатора
  23. Testing the Performance of NGINX and NGINX Plus Web Servers – NGINX Community Blog
  24. HAProxy Kubernetes Ingress Controller Twice as Fast with Lowest CPU vs. Four Competitors | OpsMatters
  25. Консистентность данных: что это и почему она так важна
  26. Краткий обзор возможностей PostgreSQL | PostgreSQL
  27. Распределённые транзакции в микросервисах: от SAGA до Two‑Phase Commit / Хабр
  28. Кластеризация для обеспечения отказоустойчивости | Microsoft Learn
  29. Сколько нужно ядер cpu, чтобы выдержать 30k+ rps? / Хабр
  30. Нагрузочный поединок: Tarantool 2.10 vs Redis 7.0.5 / Хабр
  31. Все, что нужно PostgreSQL: быстрые диски, дорогой процессор и терабайты RAM / Хабр

Приложения

Приложение A

Лекция 2

Приложение B

Карта России

Приложение C

2PC

Приложение D

Схема охлаждения

About

Курсовая работа по дисциплине "Проектирование высоконагруженных систем". Технопарк. 2025. Осень

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published