将会话从memcached迁移到redis,而无需在laravel中注销用户
目前,我们使用Memcached来存储Laravel基于cookie的会话,但希望在整个会话中使用Redis,并使用缓存来保持一致性将会话从memcached迁移到redis,而无需在laravel中注销用户,laravel,session,redis,memcached,Laravel,Session,Redis,Memcached,目前,我们使用Memcached来存储Laravel基于cookie的会话,但希望在整个会话中使用Redis,并使用缓存来保持一致性 有没有一种方法可以将所有用户会话从Memcached迁移到Redis,而无需注销用户?下面是如何进行这种迁移的示例。试着这样做: <?php $host = '127.0.0.1'; $port = null; $oldPrefix = 'sess_'; $newPrefix = 'sess_'; $sessionDir = '/var/lib/php/s
有没有一种方法可以将所有用户会话从Memcached迁移到Redis,而无需注销用户?下面是如何进行这种迁移的示例。试着这样做:
<?php
$host = '127.0.0.1';
$port = null;
$oldPrefix = 'sess_';
$newPrefix = 'sess_';
$sessionDir = '/var/lib/php/session/';
$m = new \Redis();
$m->connect($host, $port);
// $m = new \Memcached();
// $m->addServer($host, $port);
$sessions = scandir($sessionDir);
if (!$sessions) {
die('nothing to migrate');
}
foreach ($sessions as $s) {
if (in_array($s, ['.', '..'])) {
continue;
}
$sessionName = str_replace($oldPrefix, '', $s);
$sessionContents = file_get_contents($sessionDir.$s);
if (!$m->set($newPrefix.$sessionName, $sessionContents)) {
die(sprintf('Could not migrate session %s'.PHP_EOL, $newPrefix.$sessionName));
}
echo '.';
}
die(PHP_EOL);
我能够在不注销用户的情况下迁移会话。我为此创建了artisan命令:
<?php
namespace App\Console\Commands;
use \Memcached;
use \Redis;
use Illuminate\Console\Command;
class MigrateSessionToRedis extends Command
{
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'migrate:session';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Migrate sessions from Memcached to Redis';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct() #NOSONAR
{
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle()
{
$this->info('Starting session migration..');
$memcached = new Memcached();
$memcached->addServer(env('MEMCACHED_HOST'), 11211);
$sessions = $this->getMemcachedKeys(env('MEMCACHED_HOST'));
if (! is_array($sessions)) {
$this->error('Could not retrieve sessions from Memcached');
exit(1);
}
foreach ($sessions as $session) {
$value = $memcached->get($session);
if ($value) {
$object = unserialize($value);
$valueForRedis = serialize(serialize($object));
// Set session in Redis with session expiry lifetime
Redis::set("{$session}", $valueForRedis, 'EX', config('session.lifetime'));
}
}
$this->info('Finished session migration.');
}
/**
* Get all memcached keys. Special function because getAllKeys() is broken since memcached 1.4.23.
* Should only be needed on php 5.6
*
* cleaned up version of code found on Stackoverflow.com by Maduka Jayalath
*
* @return array|int - all retrieved keys (or negative number on error)
*/
private function getMemcachedKeys($host = '127.0.0.1', $port = 11211) #NOSONAR
{
$mem = @fsockopen($host, $port);
if ($mem === false) {
return -1;
}
// retrieve distinct slab
$r = @fwrite($mem, 'stats items' . chr(10));
if ($r === false) {
return -2;
}
$slab = [];
while (($l = @fgets($mem, 1024)) !== false) {
// finished?
$l = trim($l);
if ($l == 'END') {
break;
}
$m = [];
// <STAT items:22:evicted_nonzero 0>
$r = preg_match('/^STAT\sitems\:(\d+)\:/', $l, $m);
if ($r != 1) {
return -3;
}
$a_slab = $m[1];
if (!array_key_exists($a_slab, $slab)) {
$slab[$a_slab] = [];
}
}
reset($slab);
foreach ($slab as $a_slab_key => &$a_slab) {
$r = @fwrite($mem, 'stats cachedump ' . $a_slab_key . ' 100' . chr(10));
if ($r === false) {
return -4;
}
while (($l = @fgets($mem, 1024)) !== false) {
// finished?
$l = trim($l);
if ($l == 'END') {
break;
}
$m = [];
// ITEM 42 [118 b; 1354717302 s]
$r = preg_match('/^ITEM\s([^\s]+)\s/', $l, $m);
if ($r != 1) {
return -5;
}
$a_key = $m[1];
$a_slab[] = $a_key;
}
}
// close the connection
@fclose($mem);
unset($mem);
$keys = [];
reset($slab);
foreach ($slab as &$a_slab) {
reset($a_slab);
foreach ($a_slab as &$a_key) {
$keys[] = $a_key;
}
}
unset($slab);
return $keys;
}
}
最重要的一点是让他们保持登录状态。他们现有的cookie不应该失效。你的想法对我很有帮助