Как заставить Laravel работать с кластером Redis на AWS - PullRequest
1 голос
/ 07 июня 2019

Я пытаюсь использовать Laravel (5.4) с кластерной версией Redis. Я следовал инструкции этот пост вроде так:

/*
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
 */

'redis' => [
     'client' => 'predis',
     'cluster' => 'true',

     'default' => [
            'host' => env('REDIS_HOST_1', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => 6379,
            'database' => 0,
     ],


    'clusters' => [
         'default' => [
            'host' => env('REDIS_HOST_1', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => 6379,
            'database' => 0,
        ],
        'jobs' => [
            'host' => env('REDIS_HOST_2', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port'     => 6379,
            'database' => 0,
        ],
        'content' => [
            'host' => env('REDIS_HOST_3', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port'     => 6379,
            'database' => 0,
        ]
   ],

    'options' => [
        'cluster' => 'redis'
    ],
]

но я продолжаю получать эту ошибку

[2019-06-07 15:53:37] local.ERROR: Predis\Response\ServerException: MOVED 5873 127.0.0.1:7001 in /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Client.php:370 Stack trace: 
0 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Client.php(335): Predis\Client->onErrorResponse(Object(Predis\Command\StringGet), Object(Predis\Response\Error)) 
1 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Client.php(314): Predis\Client->executeCommand(Object(Predis\Command\StringGet)) 
2 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php(72): Predis\Client->__call('get', Array) 
3 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Redis/Connections/Connection.php(84): Illuminate\Redis\Connections\Connection->command('get', Array) 
4 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/RedisStore.php(54): Illuminate\Redis\Connections\Connection->__call('get', Array) 
5 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(84): Illuminate\Cache\RedisStore->get('cbwvtr3cxYIFP4H...') 
6 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(68): Illuminate\Cache\Repository->get('cbwvtr3cxYIFP4H...') 
7 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/CacheManager.php(305): Illuminate\Cache\Repository->has('cbwvtr3cxYIFP4H...') 
8 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/Providers/Storage/IlluminateCacheAdapter.php(57): Illuminate\Cache\CacheManager->__call('has', Array) 
9 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/Blacklist.php(74): Tymon\JWTAuth\Providers\Storage\IlluminateCacheAdapter->has('cbwvtr3cxYIFP4H...') 
10 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/JWTManager.php(83): Tymon\JWTAuth\Blacklist->has(Object(Tymon\JWTAuth\Payload)) 
11 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/JWTAuth.php(190): Tymon\JWTAuth\JWTManager->decode(Object(Tymon\JWTAuth\Token)) 
12 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/JWTAuth.php(124): Tymon\JWTAuth\JWTAuth->getPayload('eyJ0eXAiOiJKV1Q...') 
13 /Users/Shared/dev/php/toters-api/app/Http/Middleware/TokenAuthentication.php(25): Tymon\JWTAuth\JWTAuth->authenticate('eyJ0eXAiOiJKV1Q...') 
14 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): App\Http\Middleware\TokenAuthentication->handle(Object(Illuminate\Http\Request), Object(Closure)) 
15 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Routing/Pipeline.php(53): Illuminate\Pipeline\Pipeline->Illuminate\Pipeline\{closure}(Object(Illuminate\Http\Request)) 
16 /Users/Shared/dev/php/toters-api/app/Http/Middleware/WeakEtagMiddleware.php(22): Illuminate\Routing\Pipeline->Illuminate\Routing\{closure}(Object(Illuminate\Http\Request)) 
17 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(148): App\Http\Middleware\WeakEtagMiddleware->handle(Object(Illuminate\Http\Request), Object(Closure)) 

Примечание. Я не вносил никаких изменений в данные приложения, поэтому мой код Redis по-прежнему выглядит так:

use Illuminate\Support\Facades\Redis;
..

Redis::set('key', 'val');

Далее, если я уберу настройки по умолчанию из вышеуказанного конфига, чтобы они выглядели так:

'redis' => [
     'client' => 'predis',
     'cluster' => 'true',

    'clusters' => [
         'default' => [
            'host' => env('REDIS_HOST_1', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => 6379,
            'database' => 0,
        ],
        'jobs' => [
            'host' => env('REDIS_HOST_2', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port'     => 6379,
            'database' => 0,
        ],
        'content' => [
            'host' => env('REDIS_HOST_3', '127.0.0.1'),
            'password' => env('REDIS_PASSWORD', null),
            'port'     => 6379,
            'database' => 0,
        ]
   ],

    'options' => [
        'cluster' => 'redis'
    ],
]

Я получаю эту ошибку

[2019-06-07 16:00:02] local.ERROR: Symfony\Component\Debug\Exception\FatalThrowableError: Type error: Argument 1 passed to Predis\Connection\Parameters::__construct() must be of the type array, integer given, called in /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Connection/Factory.php on line 164 in /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Connection/Parameters.php:34 Stack trace: 
0 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Connection/Factory.php(164): Predis\Connection\Parameters->__construct(6379) 
1 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Connection/Factory.php(84): Predis\Connection\Factory->createParameters(6379) 
2 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Connection/Factory.php(118): Predis\Connection\Factory->create(6379) 
3 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Client.php(135): Predis\Connection\Factory->aggregate(Object(Predis\Connection\Aggregate\RedisCluster), Array) 
4 /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Client.php(56): Predis\Client->createConnection(Array) 
5 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Redis/Connectors/PredisConnector.php(41): Predis\Client->__construct(Array, Array) 
6 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Redis/RedisManager.php(102): Illuminate\Redis\Connectors\PredisConnector->connectToCluster(Array, Array, Array) 
7 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Redis/RedisManager.php(83): Illuminate\Redis\RedisManager->resolveCluster('default') 
8 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Redis/RedisManager.php(61): Illuminate\Redis\RedisManager->resolve('default') 
9 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/RedisStore.php(211): Illuminate\Redis\RedisManager->connection('default') 
10 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/RedisStore.php(54): Illuminate\Cache\RedisStore->connection() 
11 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(84): Illuminate\Cache\RedisStore->get('cbwvtr3cxYIFP4H...') 
12 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/Repository.php(68): Illuminate\Cache\Repository->get('cbwvtr3cxYIFP4H...') 
13 /Users/Shared/dev/php/toters-api/vendor/laravel/framework/src/Illuminate/Cache/CacheManager.php(305): Illuminate\Cache\Repository->has('cbwvtr3cxYIFP4H...') 
14 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/Providers/Storage/IlluminateCacheAdapter.php(57): Illuminate\Cache\CacheManager->__call('has', Array) 
15 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/Blacklist.php(74): Tymon\JWTAuth\Providers\Storage\IlluminateCacheAdapter->has('cbwvtr3cxYIFP4H...') 
16 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/JWTManager.php(83): Tymon\JWTAuth\Blacklist->has(Object(Tymon\JWTAuth\Payload)) 
17 /Users/Shared/dev/php/toters-api/vendor/tymon/jwt-auth/src/JWTAuth.php(190): Tymon\JWTAuth\JWTManager->decode(Object(Tymon\JWTAuth\Token)) 

Итак, из сообщения об ошибке кажется, что Predis просто игнорирует мою кластерную конфигурацию и читает прямо из значения по умолчанию, а default не знает, как обращаться с моим кластеризованным хранилищем данных Redis. Идеи?

1 Ответ

3 голосов
/ 09 июня 2019

после поиска и отладки, вот что заставило его работать:

'redis' => [
    'client' => 'predis',
    'cluster' => true,
    'options' => [
        'cluster' => 'redis',
        'parameters' => [
            'host' => env('REDIS_DEFAULT_HOST', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_DEFAULT_PORT', 6379),
            'database' => 0,
            ],
        ],
    'clusters' => [
         'default' => [
            'host' => env('REDIS_DEFAULT_HOST', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_DEFAULT_PORT', 6379),
            'database' => 0,
        ],
        'jobs' => [
            'host' => env('REDIS_JOBS_HOST', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_JOBS_PORT', 6379),
            'database' => 0,
        ],
        'content' => [
            'host' => env('REDIS_CONTENT_HOST', '127.0.01'),
            'password' => env('REDIS_PASSWORD', null),
            'port' => env('REDIS_CONTENT_PORT', 6379),
            'database' => 0,
        ],
        'options' => [
            'cluster' => 'redis'
        ],
    ]
]

примечание: одна очевидная ошибка в моей конфигурации в приведенном выше вопросе заключалась в том, что я объединил хост и порт, который я исправил здесь.Вот как выглядит мой .env файл:

REDIS_DEFAULT_HOST=127.0.0.1
REDIS_JOBS_HOST=127.0.0.1
REDIS_CONTENT_HOST=127.0.0.1

REDIS_DEFAULT_PORT=7000
REDIS_JOBS_PORT=7001
REDIS_CONTENT_PORT=7002

Примечание: я создал кластер, используя следующие инструкции: https://redis.io/topics/cluster-tutorial#creating-the-cluster

Методология исследования

В связи сфакт, что: 1. в документации laravel / predis по этому вопросу отсутствует 2. большинство ответов о переполнении стека имеют следующие строки: после поиска в Google и поиска .. это то, что сработало для меня без особых объясненийо том, что происходит

Я подумал, что могу немного помочь, показав как Я нашел ответ на этот вопрос.

1) Решение проблемы с ошибкой

Для устранения этой ошибки

local.ERROR: Symfony \ Component \ Debug \ Exception \ FatalThrowableError: Ошибка типа: Аргумент 1, переданный в Predis \ Connection \ Parameters :: __ construct (), должен иметьмассив типов с указанным целым числом вызывается в /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Connection/Factory.php в строке 164 в / Users / Shared / dev / php / toters-api / vendor / predis / predis / src / Connection / Parameters.php: 34 Stack trace:

Я понял, что мой формат config / database.php был просто неверным.Поиск в Google не дал мне четкой картины, поэтому я решил использовать в коде xdebug и dive .Примечание: у меня была трассировка стека ошибок (показанная в вопросе выше), напечатанная в одном документе, и я использовала ее как вид с высоты птичьего полета, чтобы направлять меня по шагам отладки (то есть переходить / входить / выходить и т. Д., Всегда печатая выходные данныев отдельном документе и сравнивая его с моим config / database.php для проверки работоспособности / отладки компаса).

После копания и печати я наткнулся на это:

[ *Locals ] [ Superglobals ] [ User defined constants ]

- Locals at /Users/Shared/dev/php/toters-api/vendor/predis/predis/src/Client.php:55

 ▾ $options = (array [1])
  \
   ⬦ $options["cluster"] = (string [5]) `redis`
  /
 ▾ $parameters = (array [4])
  \
   ⬦ $parameters[0] = (string [14]) `127.0.0.1:7000`
   |
   ⬦ $parameters[1] = (null)
   |
   ⬦ $parameters[2] = (int) 6379
   |
   ⬦ $parameters[3] = (int) 0
  /
 ▾ $this = (Predis\Client [3])
  \
   ⬦ $this->connection = (null)
   |
   ⬦ $this->options = (null)
   |
   ⬦ $this->profile = (null)
  /

Я сравнилэто с содержимым моего .env файла:

REDIS_DEFAULT_HOST=127.0.0.1:7000
REDIS_JOBS_HOST=127.0.0.1:7001
REDIS_CONTENT_HOST=127.0.0.1:7002

, и я понял, что формат был неправильным, я не должен помещать порт хоста AND в одну и ту же переменную env .. поэтому я вместо этого поставил это так:

REDIS_DEFAULT_HOST=127.0.0.1
REDIS_JOBS_HOST=127.0.0.1
REDIS_CONTENT_HOST=127.0.0.1

REDIS_DEFAULT_PORT=7000
REDIS_JOBS_PORT=7001
REDIS_CONTENT_PORT=7002

и это решило мою первую проблему.

2) решение других проблем

после исправления вышеизложенного я получил это

CLUSTERDOWN Хэш-слот не обслуживается

это было довольно просто, это всего лишь вопрос поиска сообщения об ошибке (поскольку сообщение об ошибке было явно сообщением об ошибке Redis, а не какой-то загадочной оболочкой библиотекикак прсообщение об ошибке edis) .. и я нашел этот ответ .

Остальное было легко.

enter image description here

...