Enable laravel's cache to support using connection to select the redis service

Source: Internet
Author: User
Tags memcached redis value store

Let's take a look at the redis configuration in my database. php:

The code is as follows: Copy code
/*
| --------------------------------------------------------------------------
| 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 '=> array (
'Cluster' => false,
'Default' => array (
'Host' => '2017. 168.1.120 ',
'Port' => 6379,
'Database' => 0,
),
'Cache' => array (
'Host' => '2017. 168.1.120 ',
'Port' => 6379,
'Database' => 1,
),
'Session '=> array (
'Host' => '2017. 168.1.120 ',
'Port' => 6379,
'Database' => 2,
),
),

The intention of this configuration is to use the cache configuration item during cache, and the session data is stored in the session configuration item.
Let's take a look at the configuration in app/config/cache. php.
 

The code is as follows: Copy code
'Driver '=> 'redis ',
//.......
'Path' => storage_path (). '/cache ',
/*
| --------------------------------------------------------------------------
| Database Cache Connection
| --------------------------------------------------------------------------
|
| When using the "database" cache driver you may specify the connection
| That shoshould be used to store the cached items. When this option is
| Null the default database connection will be utilized for cache.
|
*/
'Connection' => 'cache ',

Next, let's take a look at the configuration in app/config/session. php.
 

The code is as follows: Copy code
'Driver '=> 'redis ',
//.......
'Files '=> storage_path ().'/session ',
/*
| --------------------------------------------------------------------------
| Session Database Connection
| --------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the database
| Connection that shoshould be used to manage your sessions. This shold
| Correspond to a connection in your "database" configuration file.
|
*/
'Connection' => 'session ',

Here I set both drivers to redis.
After testing the above settings, we found a problem: session data can be normally stored in the specified service, and cache data is not stored as expected, it is stored in the session service. Why? Continue.
Now let's change the method. We will slightly modify the above configuration and change the session driver to non-redis, such as memcache. Then we will test the effect as follows:
The cached data is stored on the default, which is not the expected cache service. Why?
We found two problems above. For now, question A and question B are called in order.
Here we will first solve problem B.
The cause of problem B is that laravel's cache does not support redis connection (that is to say, when the cache driver is redis, the connection setting is meaningless). It is only supported when the database driver is used, so how can we change it to support it ?, It is easy to modify.
Since it is a cache, you must find cacheManager: Laravel/vender/laravel/framework/src/Illuminate/Cache/CacheManager. php
The code for modifying the method is as follows:
 

The code is as follows: Copy code
/**
* Create an instance of the Redis cache driver.
 *
* @ Return IlluminateCacheRedisStore
*/
Protected function createRedisDriver ()
{
$ Redis = $ this-> app ['redis '];
// Add a code line to get the cache connection value
$ Connection = $ this-> app ['config'] ['cache. Connection'];
// Set the third parameter for RedisStore
Return $ this-> repository (new RedisStore ($ redis, $ this-> getPrefix (), $ connection ));
}

OK. It's easy.
In this way, we can solve our problem B and ensure that when the cache driver is redis, the cached data exists in the service specified by connection (cache.
So can we solve the problem after this change? Sorry, no !!!
I tested it according to the sauce purple, and the result is the same as the previous result (the session data can be normally stored in the specified service, the cache data is not stored as expected, but is stored in the session service .)
At present, I have not found any good solutions. Why? Please refer to the following analysis.
As we all know, session is actually a kind of cache, so since it is a kind of cache, it must be handled according to the cache process (in fact, part of laravel's session driver (redis, memcache, memcached follows the cache storage process)
Specific code:
File: Laravel/vendor/laravel/framework/src/Illuminate/Session/SessionManager. php
 

The code is as follows: Copy code
/**
* Create an instance of the Redis session driver.
 *
* @ Return IlluminateSessionStore
*/
Protected function createRedisDriver ()
{
// The current redis connection is set to cache
$ Handler = $ this-> createCacheHandler ('redis ');
// Here, the connection of the current redis is set to session (that is to say, overwrite the above)
$ Handler-> getCache ()-> getStore ()-> setConnection ($ this-> app ['config'] ['session. Connection']);
Return $ this-> buildSession ($ handler );
}

This code is called when the application starts the session through booting callbacks. This method is used to create a session driver for redis.
Let's take a look at the createCacheHandler method:

The code is as follows: Copy code
/**
* Create the cache based session handler instance.
 *
* @ Param string $ driver
* @ Return IlluminateSessionCacheBasedSessionHandler
*/
Protected function createCacheHandler ($ driver)
{
$ Minutes = $ this-> app ['config'] ['session. Lifetime'];
// The createRedisDriver method of CacheManager will be called
Return new CacheBasedSessionHandler ($ this-> app ['cache']-> driver ($ driver), $ minutes );
}

Let's take a look at the createRedisDriver method of CacheManager.
File: Laravel/vendor/laravel/framework/src/Illuminate/Cache/CacheManager. php
 

The code is as follows: Copy code
/**
* Create an instance of the Redis cache driver.
 *
* @ Return IlluminateCacheRedisStore
*/
Protected function createRedisDriver ()
{
$ Redis = $ this-> app ['redis '];
 
$ Connection = $ this-> app ['config'] ['cache. Connection'];
// Here we set the redis connection of our cache
Return $ this-> repository (new RedisStore ($ redis, $ this-> getPrefix (), $ connection ));
}

This code is the code we changed, but it doesn't matter. Through the above analysis, we found that when cache and session use a driver at the same time, the final driver is determined by the connection value in the session configuration file, because it overwrites the driver value set by the cache. The reason for this problem is that, as we mentioned above, all session data processing is based on the cache process, because session is also a cache. =. =
This is actually a problem because it is not handled as required.
Whether it is a problem or not is actually not a problem, because the session is also a cache in a sense. Of course, the subsequent settings overwrite the previous settings.
Is there a solution? Provides two solutions:
1: Do not use one driver at the same time. For example, memcache is used for cache and redis is used for session.
2: use the solution I mentioned last time:

The code is as follows: Copy code

$ RedisCache = App: make ('cache'); // Assumes "redis" set as your cache
$ RedisCache-> setConnection ('cache'); // Your redis cache connection
$ RedisCache-> put ('testtcacheindex', 'fbbinvalue', 10000 );

// Or

$ Redis = Redis: connection ('cache ');
$ Redis-> set ('fbbin', 'fbbinvalue ');
Var_dump ($ redis-> get ('fbbin '))

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.