Wielkość connection poola w Spring Bootowej apce

0

Załóżmy że mamy aplikację z jakiejś dziedziny, nie prostego CRUDa ale też nie drugiego Netflixa. Załóżmy pewien rząd wielkości użytkowników (up to you - 1000, 10 000, 1 000 000). Jak dobrać konkretną liczbę połączeń do bazy danych w naszym connection poolu? Wartość orientacyjna to np 100 czy 200, ale czemu właśnie te 100 a nie np 300? Jak to ustalić? :D

Może trywialne pytanie, ale nie wiem.

1
Pinek napisał(a):

Jak dobrać konkretną liczbę połączeń do bazy danych w naszym connection poolu? Wartość orientacyjna to np 100 czy 200, ale czemu właśnie te 100 a nie np 300?

Są dwie szkoły:

  • pierwsza - na oko. Na oko dobieramy wartość tak żeby było dobrze
  • druga - czytamy dokumentację. Ki2dyś w dokumentacji postgresa było że ilość połączeń powinna wynosić ilość rdzeni razy dwa + ilość sterownikó twardego dysku. czyli nie 100-200 a bardziej 10-20
0

jeśli nad gołą bazą danych jest warstwa obiektowa, MOŻE dawać nawet niezamierzony efekt cache -> łagodzi wymogi połączeń.

disclaimer: to zależy

3

@KamilAdam:

druga - czytamy dokumentację. Ki2dyś w dokumentacji postgresa było że ilość połączeń powinna wynosić ilość rdzeni razy dwa + ilość sterownikó twardego dysku. czyli nie 100-200 a bardziej 10-20

Ta druga szkoła ma sens w przypadku aplikacji non-blocking (gdzie zamiast ilość rdzeni mamy ilość rdzeni aktywnie wykonujących połączenia) - na małą aplikację (server i baza na jednej maszynie) wystarczają wtedy 2 połączenia zwykle.
W przypadku SpringBoot czy dowolnej blokującej architektury mamy tony wiszących połączeń, które nic nie robią - więc trzeba te limity robić większe.

A co do pytania. Ustalić eksperymentalnie - porównać ilość koniecznych połączeń przy różnych obciążeniach. Zrobić load test po przewidywane obciążenie i/lub esktrapolować rezultat.
Raczej nie kojarze aplikacji, gdzie miałbym więcej niż 50 połączeń w puli (ale mogę nie pamiętać). Na ogół większe aplikacje chodziły na większej ilości węzłów, z których każdy miał swoją pulę 20-30. Więcej nie było sensu, bo i tak najpierw umierało CPU.

1

Tak, żeby pobranie połączenia z puli nie było wąskim gardłem aplikacji :) (minimalizacja czasu oczekiwania na zasób) i tak żeby aplikacja nie zeżarła puli procesów/sesji, które baza ma ustawione jako max (inne aplikacje mogą ucierpieć).

3

IMO można do tego podejść tak jak się szacuje wielkość puli wątków w systemie blokującym. Patrzysz ile masz zapytań na sekundę i jakie czasy odpowiedzi. Wtedy wystarczy policzyć N = Qps * t. Oczywiście dodawanie wątków w nieskończoność nie działa, to tylko estymata.

Przykład: dostajesz 2000 zapytań na sekundę, czasy odpowiedzi chcesz mieć na poziomie 50ms. To oznacza, że potrzebujesz 10 wątków. Czyli nie ma sensu dawać więcej niż 10 połączeń do puli, bo i tak nie będzie komu obsłużyć tego zapytania.

Przy systemach non-blocking, gdzie używany jest systemowy event loop liczbę wątków określa się jako 2* liczba CPU.

2

Ja proponuje jeden wątek. Przy starcie aplikacji ładujesz dane do pamięci i z bazy już nie czytasz. Jak idą updaty to składasz je w jakieś batche i pchasz periodycznie przez ten jeden wątek ;)

1 użytkowników online, w tym zalogowanych: 0, gości: 1, botów: 0