TL;DR:
'cluster' => true
powinno być prawdziwe, aby utworzyć jednego klienta zbiorczego, który obsługuje wiele węzłów.'options' => ['cluster' => 'redis']
należy dodać do konfiguracji jako rodzeństwodefault
(nie dziecko), aby poinformować Predis, aby obsługiwał klastrowanie po stronie serwera zapewniane przez platformę Azure.- jeśli używasz uwierzytelniania z klastrowaniem po stronie serwera,
'options' => [ 'cluster' => 'redis', 'parameters' => ['password' => env('REDIS_PASSWORD', null)], ]
będą potrzebne do uwierzytelniania nowo wykrytych węzłów klastra.
Pełny tekst
W konfiguracji redis można skonfigurować wiele połączeń z wieloma instancjami redis. cluster
opcja mówi Laravelowi, jak obsługiwać te wiele zdefiniowanych połączeń.
Jeśli cluster
jest ustawione na false
, Laravel utworzy indywidualny \Predis\Client
instancje dla każdego połączenia. Do każdego połączenia można uzyskać dostęp indywidualnie i nie będzie ono mieć żadnego związku z innym połączeniem.
Jeśli cluster
jest ustawiona na true
, Laravel utworzy agregację \Predis\Client
wystąpienie przy użyciu wszystkich zdefiniowanych połączeń. Bez żadnej innej konfiguracji jest to rodzaj „fałszywego” klastra. Wykorzystuje fragmentowanie po stronie klienta do dystrybucji przestrzeni kluczy i może wymagać zewnętrznego monitorowania i konserwacji w celu zapewnienia prawidłowego równoważenia obciążenia klucza.
Problem, z którym się spotykasz, polega jednak na tym, że platforma Azure implementuje (przypuszczalnie) prawdziwy klaster Redis po stronie serwera, który obsługuje automatyczne fragmentowanie obszaru kluczy. W tym przypadku węzły wiedzą o sobie nawzajem i rozmawiają ze sobą oraz mogą poruszać się w górę iw dół. Tutaj MOVED
i ASK
odpowiedzi pochodzą.
Predis
biblioteka może automatycznie obsłużyć te odpowiedzi, ale tylko wtedy, gdy powiesz jej, że musi. W takim przypadku musisz poinformować Predis
klienta, którego potrzebuje do obsługi klastrowania, a robi to Laravel za pomocą options
tablica na redis
konfiguracja.
Na redis
konfiguracji, options
klucz powinien być rodzeństwem twoich połączeń (tj. default
), a nie dziecko. Dodatkowo opcje należy określić jako key => value
pary.
Twoja konfiguracja powinna więc wyglądać tak:
'redis' => [
'cluster' => true,
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'options' => [
'cluster' => 'redis',
],
],
cluster
klawisz pod redis
config powie Laravelowi, aby utworzył agregację Predis\Client
instancja, która może obsługiwać wiele węzłów oraz cluster
klawisz pod options
array poinformuje tę instancję, że musi obsługiwać klastrowanie po stronie serwera, a nie po stronie klienta.
Uwierzytelnianie
Oryginalne parametry połączenia (w tym uwierzytelnianie) nie są współdzielone z połączeniami do nowych węzłów wykrytych przez -MOVED
i -ASK
odpowiedzi. Tak więc wszelkie błędy, które wcześniej uzyskałeś z -MOVED
odpowiedzi będą teraz po prostu konwertowane na NOAUTH
błędy. Jednak po stronie serwera 'cluster'
konfiguracja pozwala na 'parameters'
rodzeństwo, które definiuje listę parametrów do użycia z nowo odkrytymi węzłami. Tutaj możesz umieścić swoje parametry uwierzytelniania do użycia z nowymi węzłami.
Wierzę, że będzie to wyglądać mniej więcej tak:
'redis' => [
'cluster' => true,
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'options' => [
'cluster' => 'redis',
'parameters' => ['password' => env('REDIS_PASSWORD', null)],
],
],
Uczciwe ostrzeżenie, to wszystkie informacje, które właśnie otrzymałem z badań i nurkowania z kodem. Chociaż korzystałem z Redis z Laravel, nie korzystałem z klastrowania po stronie serwera (jeszcze), więc to nadal może nie działać.
Kilka przydatnych informacji, na które natknąłem się podczas tego badania:
Problem Predis omawiający połączenie z klastrem redis:
https://github.com/nrk/predis/issues/259#issuecomment-117339028
Wygląda na to, że Predis nie został skonfigurowany do korzystania z klastra redis, ale zamiast tego używasz go ze zwykłą starą logiką shardingu po stronie klienta (co jest również domyślnym zachowaniem). Należy skonfigurować klienta ustawienie klastra opcji z wartością redis, aby klient wiedział, że musi grać razem z klastrem redis. Szybki przykład:
$client = new Predis\Client([$node1, $node2, ...], ['cluster' => 'redis']);
Dzięki temu klient będzie mógł automatycznie obsługiwać odpowiedzi -MOVED lub -ASK pochodzące z węzłów Redis.
Artykuł MS omawiający klastrowanie w pamięci podręcznej redis:
https://docs.microsoft.com/en-us/azure/redis-cache/cache-how-to-premium-clustering#how-do-i-connect- do-mojej-cache-gdy-klastrowanie-jest-włączone
Możesz połączyć się z pamięcią podręczną przy użyciu tych samych punktów końcowych, portów i kluczy, których używasz podczas łączenia się z pamięcią podręczną, która nie ma włączonego klastrowania. Redis zarządza klastrowaniem na zapleczu, więc nie musisz nim zarządzać z poziomu swojego klienta.
Kod Laravela do tworzenia Predis\Client
instancje:
https://github.com/laravel/framework/blob/v5.3.28/src/Illuminate/Redis/Database.php#L25-L66