Przejdź do treści
Architektura 1 min czytania

Skalowanie bazy danych w sklepie B2B - replikacja, sharding, read replicas

Większość problemów wydajnościowych „bazy danych" w sklepach B2B nie jest problemem bazy. Jest problemem braku cache, źle napisanych zapytań N+1, lub indeksów. Skalowanie bazy (replikacja, read replicas, sharding) to **ostatnie** narzędzie, nie pierwsze. Najpierw napraw to, co masz. Potem dodaj cache. Dopiero potem skaluj DB.

Jakub Owsianka Autor
Zaktualizowano:
Okladka artykulu: Skalowanie bazy danych w sklepie B2B - replikacja, sharding, read replicas (kategoria: Architektura)
Okladka artykulu: Skalowanie bazy danych w sklepie B2B - replikacja, sharding, read replicas (kategoria: Architektura)
Spis treści (9)

W skrócie

  • 1. Pierwsze kroki przed skalowaniem: profile slow query log, dodaj brakujące indeksy, napraw N+1, dodaj Redis cache
  • 2. Master-slave replication: read replicas dla raportów i powtarzalnych queries
  • 3. Percona / MariaDB zamiast MySQL: marginalne zyski performance + lepsze tooling
  • 4. Sharding: rzadko sensowne w polskim B2B - koszt operacyjny wysoki
  • 5. PostgreSQL zamiast MySQL: dla projektów z dużą logiką JSON / analytics

Najpierw zoptymalizuj, dopiero potem skaluj

Sklep „wolny" zazwyczaj nie potrzebuje większej bazy. Potrzebuje:

1. Slow query log. MySQL slow_query_log → long_query_time = 1 → przeglądanie zapytań > 1s. Najczęściej znajdziesz 5-10 zapytań do refaktoru.

2. Brakujące indeksy. Każdy WHERE / JOIN po kolumnie bez indeksu = full table scan. EXPLAIN każdej powolnej query.

3. N+1 queries. Klasyczny problem ORM. Lista 50 produktów → 51 queries (1 dla listy + 50 per produkt po kategorię/atrybuty). Eager loading rozwiązuje.

4. Cache. Jeśli wciąż ta sama query wykonywana 100×/min - cache w Redis. Cache warstwy.

5. Search dedykowany. Filtry i search z MySQL przy 30k+ SKU = bottleneck. Elastic. Search.

Te 5 kroków rozwiązuje 80% problemów wydajnościowych „bazy" w średnich sklepach B2B. Bez kosztownego skalowania.

Pionowa skalowalność (większy serwer)

Najprostsze. Większa maszyna = więcej CPU/RAM/IO. Większość polskich B2B działa na 1-2 maszynach DB.

Konfiguracja typowa dla średniego sklepu:

  • Magento 2.4 + Comarch XL integracja
  • 50k SKU, 200 kontrahentów, 5k zamówień/mies.
  • Maszyna: 16-32 CPU cores, 64-128 GB RAM, NVMe 1-2 TB
  • Hetzner / OVH / dedykowane: 2-5 tys. zł / mies.

To wystarcza często do 100 M zł obrotu rocznego. Dopiero powyżej rozważasz skalowanie poziome.

Tuning MySQL/MariaDB dla sklepu:

innodb_buffer_pool_size = 70-80% RAM
innodb_log_file_size = 512MB-1GB
innodb_flush_log_at_trx_commit = 2 (kompromis między bezpieczeństwem a wydajnością)
innodb_io_capacity = 2000-10000 (zależnie od dysku)
max_connections = 500-1000

To są typowe wartości startowe. Tuning per workload przy pomocy mysqltuner lub pt-mysql-summary.

Master-slave replication

Pierwsze poziome skalowanie. Master przyjmuje zapisy, slaves obsługują odczyty.

Architektura:

[Application]
    |
    +--- Master (writes + niektóre reads) <----- MySQL Binary Log Replication
    |
    +--- Slave 1 (reads - operacyjne)
    +--- Slave 2 (reads - raporty/BI)

Co skierować na slave:

  • Listy produktów (PLP) dla niezalogowanych
  • Wyszukiwanie produktów
  • Strony kategorii
  • Strony statyczne (CMS)
  • Raporty i analytics (osobny slave dedykowany)

Co zostaje na master:

  • Operacje na koszyku
  • Składanie zamówień
  • Panel klienta / admin
  • Dane zmienne (sesje, locki)

Implementacja w Magento:

  • Magento ma wbudowane wsparcie dla split databases (settings.xml / env.php)
  • Można zdefiniować osobne connections dla różnych obszarów (catalog vs. checkout)

Implementacja w Shopware / custom:

  • Doctrine connections (multi-master/slave)
  • Aplikacja decyduje per query (przez Read/Write split w ORM)

Realne wykonanie:

  • 1 master + 2 slaves dla średniego sklepu = ~2× pojemność read
  • Replication lag <1s dla większości scenariuszy
  • Trzeba pamiętać o async - w niektórych scenariuszach (np. zaraz po INSERT, SELECT na slave) - eventual consistency

Read replicas dla raportów

Osobny pattern, gdzie slave dedykowany jest tylko dla raportowych queries (BI, dashboardy, analytics):

  • Raporty robione na własnym slave
  • Slave może być nawet z opóźnieniem 5-15 min
  • Operacyjne queries nie obciążane raportami

To rozwiązuje problem klasyczny: raport „top 100 produktów ostatniego kwartału" wykonywany w godzinach pracy na produkcyjnej bazie wieszczy sklepowy katalog na 30 sekund.

Partycjonowanie tabel

Tabele rosną. sales_order z 5 milionami rekordów. customer_log z 50 milionami.

Partycjonowanie po dacie (najczęstsze dla e-commerce):

  • Tabela sales_order partycjonowana po created_at per miesiąc
  • Stare partycje (>2 lata) przenoszone do archiwum
  • Queries po dacie automatycznie skanują tylko relevantną partycję

MySQL/MariaDB: PARTITION BY RANGE (YEAR(created_at)*100 + MONTH(created_at))

PostgreSQL: declarative partitioning (od v10+), bardziej elegancko niż MySQL.

Magento: archiving zamówień (>2 lata) do osobnego storage, czyszczenie tabel log/index.

To nie jest sharding (różne maszyny), tylko logiczny podział wewnątrz jednej maszyny. Ale przyspiesza znacznie.

Sharding - gdy naprawdę nie ma wyjścia

Sharding = dzielenie danych na różne maszyny po klucz. Klient A-M na shard 1, N-Z na shard 2.

Problemy:

  • Skomplikowane queries (JOIN-y między shardami)
  • Migracje (przenoszenie danych między shardami)
  • Cross-shard transakcje (distributed transactions = piekło)
  • Każde dodanie kolumny / zmiana schema na N shardach

Kiedy sharding:

  • Powyżej setek milionów rekordów w głównych tabelach
  • Powyżej 10k zapisów/sec
  • Wszystkie inne opcje wyczerpane

W polskim B2B średniej skali: prawie nigdy. Sharding ma sens głównie dla globalnych marketplace'ów typu Allegro, eBay.

Alternatywa, lepsza dla większości - microservices z separacją per domain (catalog osobno, customer osobno, orders osobno). Każdy bounded context ma swoją bazę. To naturalna ścieżka.

Percona / MariaDB vs. MySQL

MySQL Community Edition od Oracle. Percona Server for MySQL - drop-in replacement, dodatkowe diagnostyki, lepsza wydajność w niektórych scenariuszach. MariaDB - fork MySQL z 2009, własny rozwój, niektóre funkcje plus.

Praktyczne różnice:

  • Percona: lepsza wydajność InnoDB pod wysokim load, tooling (pt-tools)
  • MariaDB: większy rozwój własnych funkcji, niektóre features bardziej eleganckie
  • MySQL: standardowy, najbardziej zgodny ze wszystkim

Dla nowego sklepu B2B: Percona lub MariaDB > vanilla MySQL. Migracja vanilla → Percona jest bezbolesna.

PostgreSQL - alternatywa

PostgreSQL bywa lepszy dla:

  • Analytics queries. Window functions, CTE, partitioning lepsze w PG.
  • JSON. JSONB w PG to first-class citizen. W MySQL JSON jest, ale słabszy.
  • Geo queries. PostGIS to złoty standard.
  • Strict typing. Mniej niespodzianek przy automatycznych konwersjach.

Słabsze strony PG dla e-commerce:

  • Mniejsze wsparcie w Magento (Magento jest MySQL-centric)
  • Shopware wspiera, ale MySQL jest defaultem
  • Mniej deweloperów PG w polskim ekosystemie e-commerce

Dla custom projektów: PostgreSQL warty rozważenia. Dla Magento/Shopware - zostań przy MySQL/MariaDB/Percona.

Backup i recovery

Skalowanie bazy nie wystarczy bez backup'u.

Wymagania:

  • Daily full backup
  • Hourly incremental backup
  • Backup przechowywany off-site (inna lokalizacja, inna chmura)
  • Tested recovery - kwartalne testy „czy backup naprawdę odtworzy się"

Narzędzia:

  • mysqldump - najprostsze, ale powolne dla dużych baz
  • xtrabackup (Percona) - hot backup, szybsze
  • mariabackup (MariaDB) - odpowiednik xtrabackup
  • Snapshots na poziomie storage (jeśli storage to wspiera, np. ZFS, LVM)

RTO i RPO:

  • RTO (Recovery Time Objective): ile czasu w razie awarii do przywrócenia. Dla sklepu B2B - 1-4h ok.
  • RPO (Recovery Point Objective): ile danych można stracić. Dla sklepu B2B - max 1h (czyli hourly backup).

FAQ

Magento wspiera read replicas? Tak, ma split databases support (catalog / checkout / sales connections osobno). Dodatkowo Adobe Commerce ma lepsze wsparcie niż OS.

Czy mogę używać MongoDB / NoSQL w sklepie B2B? Dla głównej bazy - raczej nie, e-commerce wymaga ACID transakcji (zamówienia). MongoDB ma sens dla logów, analytics, search (czasem zamiast Elastic).

Czy AWS RDS / Aurora są drogie? Tak, kilka razy droższe niż self-hosted MariaDB/Percona na Hetznerze. Aurora ma plusy (auto-scaling, multi-AZ), ale dla polskiego B2B średniej skali - self-hosted ekonomiczniejsze.

Czy ZFS na storage daje przewagę? Snapshots, compression, copy-on-write. Dla baz danych - przewaga, ale wymaga znajomości ZFS-a (niedaleki MySQL DBA tego nie umie out-of-the-box).

Czy mogę używać MariaDB Galera Cluster? Synchronous multi-master replication. Działa, ale kompromis: synchroniczność = wolniejsze zapisy. Dla większości polskich B2B - async master-slave wystarczy.

Co dalej

O autorze

Jakub Owsianka

Architekt rozwiązania w WiseB2B - silniku platform B2B. Zaczynał po stronie biznesu (własne sklepy), potem deweloper, dziś projektuje wdrożenia dla sklepów z katalogami w dziesiątkach tysięcy SKU. W ostatnich latach wdrożył AI-development w zespole i funkcjonalności oparte o AI bezpośrednio w silniku sklepu.

Masz pytanie do tego artykułu?

Dodatkowy kontekst, problem z własnym wdrożeniem, druga opinia - napisz wprost. Odpowiadam osobiście w 1-2 dni robocze.