I am trying to connect to Redis with predis 1.1 and SSL, using information https://github.com/nrk/predis, where in the example the following configuration is used:
// Named array of connection parameters:
$client = new Predis\Client([
'scheme' => 'tls',
'ssl' => ['cafile' => 'private.pem', 'verify_peer' => true],
]);
My Laravel configuration looks like below:
'redis' => [
'client' => 'predis',
'cluster' => env('REDIS_CLUSTER', false),
'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)],
'scheme' => 'tls',
],
],
Unfortunately I am getting the following error:
ConnectionException in AbstractConnection.php line 155:
Error while reading line from the server. [tcp://MY_REDIS_SERVER_URL:6380]
Suggestions are appreciated :)
I was able to get it to work!
You need to move 'scheme' from 'options' to 'default':
My working config:
'redis' => [
'client' => 'predis',
'cluster' => env('REDIS_CLUSTER', false),
'default' => [
'scheme' => 'tls',
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'options' => [
'parameters' => ['password' => env('REDIS_PASSWORD', null)],
],
],
Note: I had also removed the 'cluster' option from 'options', but I don't suspect this to be the make-or-break with this problem.
In my final-final config, I changed it to: 'scheme' => env('REDIS_SCHEME', 'tcp'), and then defined REDIS_SCHEME=tls in my env file instead.
Tested with AWS ElastiCache with TLS enabled.
Edit:
The above config only works with single-node redis. If you happen to enable clustering and TLS then you'll need a different config entirely.
'redis' => [
'client' => 'predis',
'cluster' => env('REDIS_CLUSTER', false),
// Note! for single redis nodes, the default is defined here.
// keeping it here for clusters will actually prevent the cluster config
// from being used, it'll assume single node only.
//'default' => [
// ...
//],
// #pro-tip, you can use the Cluster config even for single instances!
'clusters' => [
'default' => [
[
'scheme' => env('REDIS_SCHEME', 'tcp'),
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DATABASE', 0),
],
],
'options' => [ // Clustering specific options
'cluster' => 'redis', // This tells Redis Client lib to follow redirects (from cluster)
]
],
'options' => [
'parameters' => [ // Parameters provide defaults for the Connection Factory
'password' => env('REDIS_PASSWORD', null), // Redirects need PW for the other nodes
'scheme' => env('REDIS_SCHEME', 'tcp'), // Redirects also must match scheme
],
]
]
Explaining the above:
'client' => 'predis': This specifies the PHP Library Redis driver to use (predis).
'cluster' => 'redis': This tells Predis to assume server-side clustering. Which just means "follow redirects" (e.g. -MOVED responses). When running with a cluster, a node will respond with a -MOVED to the node that you must ask for a specific key.
If you don't have this enabled with Redis Clusters, Laravel will throw a -MOVED exception 1/n times, n being the number of nodes in Redis cluster (it'll get lucky and ask the right node every once in awhile)
'clusters' => [...] : Specifies a list of nodes, but setting just a 'default' and pointing it to the AWS 'Configuration endpoint' will let it find any/all other nodes dynamically (recommended for Elasticache, because you don't know when nodes are comin' or goin').
'options': For Laravel, can be specified at the top-level, cluster-level, and node option. (they get combined in Illuminate before being passed off to Predis)
'parameters': These 'override' the default connection settings/assumptions that Predis uses for new connections. Since we set them explicitly for the 'default' connection, these aren't used. But for a cluster setup, they are critical. A 'master' node may send back a redirect (-MOVED) and unless the parameters are set for password and scheme it'll assume defaults, and that new connection to the new node will fail.
Thank you CenterOrbit!!
I can confirm the first solution does allow Laravel to connect to a Redis server over TLS. Tested with Redis 3.2.6 on AWS ElastiCache with TLS, configured as single node and single shard.
I can also confirm the second solution does allow Laravel to connect to a Redis Cluster over TLS. Tested with Redis 3.2.6 on AWS ElastiCache with TLS, configured with "Cluster Mode Enabled", 1 shard, 1 replica per shard.
I was receiving the following error when I first tried to implement the cluster solution:
Error: Unsupported operand types
I missed the additional set of array brackets when I moved the "default" settings into the "clusters" array.
INCORRECT
'clusters' => [
'default' => [
'scheme' ...
]
]
CORRECT
'clusters' => [
'default' => [
[
'scheme' ...
]
]
]
I hope this saves someone else a bit of troubleshooting time.
The accepted solution by CenterOrbit worked for me, as I was using AWS I had to add tls:// in my .env
Laravel
tls://username:password#URL:PORT?database=0
Try it. It will work
Related
I have configured Redis (using a socket) in the Laravel in my hosting server. Everything works fine (I have tested reading from cache, sessions etc.), I have one database for a cache and a second one for users sessions.
However, when I run "php artisan cache:clear" it shows the error:
"In AbstractConnection.php line 155: Connection refused [unix:/path/.redis/redis.sock]".
This error also occures when I run any command which uses Redis, for example "php73 artisan cron:updateForeignPrices".
.env
CACHE_DRIVER=redis
SESSION_DRIVER=redis
REDIS_HOST=/path/.redis/redis.sock
REDIS_PASSWORD=null
REDIS_PORT=0
REDIS_CACHE_DB=0
REDIS_SESSION_DB=1
config/database.php
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'cluster' => true,
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
'prefix' => Str::slug(env('APP_NAME'), '_').'_',
'parameters' => ['password' => env('REDIS_PASSWORD', null)],
],
'default' => [
'scheme' => 'unix',
'path' => env('REDIS_HOST'),
'host' => env('REDIS_HOST'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT'),
'database' => env('REDIS_CACHE_DB', 0)
],
'cache' => [
'scheme' => 'unix',
'path' => env('REDIS_HOST'),
'host' => env('REDIS_HOST'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT'),
'database' => env('REDIS_CACHE_DB', 0),
],
'session' => [
'scheme' => 'unix',
'path' => env('REDIS_HOST'),
'host' => env('REDIS_HOST'),
'password' => env('REDIS_PASSWORD'),
'port' => env('REDIS_PORT'),
'database' => env('REDIS_SESSION_DB', 1),
]
]
Hosting provider's info about Redis (translated):
Socket: /path-to-my-directory/.redis/redis.sock
User and password: (none)
Port: 0
RAM: 128 MB
Instruction on WordPress Litespeed:
In the „Host” field paste address from the panel, for example: /home/klient.dhosting.pl/dhtutorial/.redis/redis.sock
In the „Port” field remove a default value and type "0".
Leave "user" and "password" empty.
It seems like everything works correctly in a direct use of Redis, but not via console. Anyone has an idea how to fix it?
Thanks in advance, I have searched whole Internet.
REDIS_HOST should point to the address where the Redis server is hosted whether it's hosted on a local machine or cloud service. somethings like below:
REDIS_HOST=12.0.0.1
REDIS_PASSWORD=password
REDIS_PORT=6379
set REDIS_HOST=127.0.0.1 or your host address
Try to use the following configuration.
.env
CACHE_DRIVER=redis
SESSION_DRIVER=redis
REDIS_SCHEME=unix
REDIS_PATH=/path/.redis/redis.sock
REDIS_CACHE_DB=0
REDIS_SESSION_DB=1
config.database.php
'redis' => [
'client' => env('REDIS_CLIENT', 'predis'),
'cluster' => true,
'options' => [
'cluster' => env('REDIS_CLUSTER', 'predis'),
'prefix' => Str::slug(env('APP_NAME'), '_').'_',
'parameters' => ['password' => null],
],
'default' => [
'scheme' => env('REDIS_SCHEME'),
'path' => env('REDIS_PATH'),
'database' => env('REDIS_CACHE_DB', 0)
],
'cache' => [
'scheme' => env('REDIS_SCHEME'),
'path' => env('REDIS_PATH'),
'database' => env('REDIS_CACHE_DB', 0),
],
'session' => [
'scheme' => env('REDIS_SCHEME'),
'path' => env('REDIS_PATH'),
'database' => env('REDIS_SESSION_DB', 1),
]
]
This project was set up by another team and I'm unable to get passed this one error. Using PHP 7.2 and Laravel 6.2. My docker-compose.yml:
redis:
image: redis
command: ["redis-server", "--appendonly", "yes","--requirepass","Redis.123"]
volumes:
- redis-data:/data
container_name: redis-master
ports:
- "6379:6379"
and database.php:
'redis' => [
'client' => env('REDIS_CLIENT', 'phpredis'),
'options' => [
'cluster' => env('REDIS_CLUSTER', 'redis'),
'prefix' => env('REDIS_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_').'_database_'),
],
'default' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_DB', 0),
],
'cache' => [
'url' => env('REDIS_URL'),
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => env('REDIS_CACHE_DB', 1),
],
]
The container is up and running and "Ready to accept connections". This error is in my stack trace if I attempt to hit the base url or any endpoints. I have aliased redis in app.php: 'RedisManager' => Illuminate\Support\Facades\Redis::class, as others have recommended. Can anyone see anything obvious that is missing or could cause this? Predis is installed in the composer.json: "predis/predis": "^1.1",, but not set in the config. If I changed phpredis to predis I get the error development.ERROR:SELECTfailed: NOAUTH Authentication required. [tcp://127.0.0.1:6379].
The error you get when you set to phpredis, it is most likely related to phpredis extension. You need to install this extension if you want to use phpredis client.
The error you get when you set it to predis is totally different. It is authentication error because you didn't set password. In your .env file, append this
REDIS_PASSWORD=Redis.123
Then artisan config:clear, it could do the work.
In .end file, please put REDIS_HOST=redis-master which is your redis container name.
I have 2 servers running same laravel app (laravel 5.3) and both are behind reverse proxy(nginx). for the session I set it to use redis. Also, I use cartalyst sentinel for user authentication.
let say the reverse Proxy is A, while servers for laravel are B and C.
The problem is:
When I log in A which is forwarding the request to B, and then the next request in A is forwarded to C.
When the request is forwarded to C, i can't pass the request because C see me as a guest not as an authenticate user.
how can I share session behind reverse proxy in different server?
config/cache.php
'default' => env('CACHE_DRIVER', 'redis'),
'stores' => [
'redis' => [
'driver' => 'redis',
'connection' => 'default',
],
],
config/session.php
'driver' => env('SESSION_DRIVER', 'redis'),
'connection' => 'session',
config/database.php
'redis' => [
'cluster' => false,
'default' => [
'host' => env('REDIS_HOST', '192.168.1.102'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
'prefix' => env('REDIS_PREFIX', 'prod'),
],
'session' => [
'host' => env('REDIS_HOST', '192.168.1.102'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 1,
'prefix' => env('REDIS_PREFIX', 'prod_session'),
],
update: 11 Oct 2017
I try using laravel default Auth and it's work. from my view point the problem is in cartalyst sentinel that not ready for use in horizontal scaling server.
I have memcached selected as my cache driver. However , ran into a weird issue.
Once I am doing:
Cache::put('name','John',15);
In the very next line if I give
var_dump(Cache::get('name'))
it shows me :
bool(false)
Couldn't understand what's going wrong here. I have memcached running on port 11211 on my localhost which I can telnet.
Also phpinfo() shows php-memcached library is installed.
My config/cache.php file reads:
'default' => env('CACHE_DRIVER', 'memcached'),
'stores' => [
'apc' => [
'driver' => 'apc',
],
'array' => [
'driver' => 'array',
],
'database' => [
'driver' => 'database',
'table' => env('CACHE_DATABASE_TABLE', 'cache'),
'connection' => env('CACHE_DATABASE_CONNECTION', null),
],
'file' => [
'driver' => 'file',
'path' => storage_path('framework/cache'),
],
'memcached' => [
'driver' => 'memcached',
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'), 'port' => env('MEMCACHED_PORT', 11211), 'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => env('CACHE_REDIS_CONNECTION', 'default'),
],
],
'prefix' => env('CACHE_PREFIX', 'laravel'),
Please help.
You have a typo. The method to set a value in the cache is put(), but you used get() twice. Try this:
Cache::put('name','John',15);
Finally after an entire day of Googling , I found the solution.
It seems I had to add the following line to bootstrap/app.php :
$app->configure('cache');
Also , please note that if you are running your application inside a VM/docker container , you need to provide the Host ip .
i spent 3 hours figuring out why my code was not working and can’t get the data from the cache and finally i figured out why :
Cache::put('name','John',15);
and when you do that You put that on the Cache for Only 15s or maybe 15ms depends on your configuration on the code.
You have to also check if you have permission on the storage Folder :
sudo CHOWN -R www:data:www:data storage
You can verify that you inserted the data on cache manually and you will see that you already cached that data but the expire date ttl is expired.
Good luck
I want to put session and cache data into redis. This is my configuration in database.php:
'redis' => array(
'cluster' => false,
'default' => array(
'host' => '192.168.56.101',
'port' => 6379,
'database' => 0,
),
'session' => array(
'host' => '192.168.56.101',
'port' => 6379,
'database' => 1,
),
),
session.php:
return array(
'driver' => 'redis',
'connection' => 'session',
);
cache.php:
'driver' => 'redis',
However, where I write code like this:
Cache::remember('aa',1,function(){
return 'bb';
});
cache driver uses the same redis database as session driver does, which results in:
127.0.0.1:6379[1]> keys *
1) "aa"
2) "e0606244bec40b0352fb2b7b65d98049e49f6189"
Anyone knows how to force cache to use a specific redis connection? Or I have to mix them up together?
Introduction
Here is my note, for some other guy who running in to this problem, I think this is should be in the docs.
By default, redis gives you 16 separate databases, but laravel out of the box will try to use database 0 for both sessions and cache.
Our solution is to let Redis caching using database 0, and database 1 for Session, there for solving the session clear by running php artisan cache:clear problem.
Note: Tested at Laravel 5.1
1. Setting up Session Redis connection
Modify config/database.php, add session key to the redis option:
'redis' => [
'cluster' => false,
'default' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'session' => [
'host' => env('REDIS_HOST', 'localhost'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 1,
],
],
2. Make use of the session connection
Modify config/session.php, change the following:
'connection' => null,
to:
'connection' => 'session',
3. Using Redis as session driver
Modify .env, change SESSION_DRIVER:
SESSION_DRIVER=redis
4. Testing out
Execute the following artisan command, then check your login state:
php artisan cache:clear
If the login state persists, voilà!
Laravel 5.5:
database.php should look like this:
'redis' => [
'client' => 'predis',
'default' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 0,
],
'session' => [
'host' => env('REDIS_HOST', '127.0.0.1'),
'password' => env('REDIS_PASSWORD', null),
'port' => env('REDIS_PORT', 6379),
'database' => 1,
],
],
And in the session.php you have to update also the key "connection" to the right key. In this case 'session'
'connection' => 'session',
Laravel 5 now supports this.
https://github.com/laravel/framework/commit/d10a840514d122fa638eb5baa24c8eae4818da3e
You can select redis connection by modifying config/cache.php
'stores' => [
'redis' => [
'driver' => 'redis',
'connection' => 'your-connection-name',
],
],
Laravel 4 CacheManager does not support selecting redis connection.
What you need to do is to modify/extend CacheManager and override createRedisDriver() method.
Modify this line
return $this->repository(new RedisStore($redis, $this->getPrefix()));
To
return $this->repository(
new RedisStore($redis, $this->getPrefix(),
$this->app['config']['cache.redis'])
);
Now you can define your configuration in cache.php
'redis' => 'your-connection-name'