laravel - 将 session 从 memcached 迁移到 redis,无需在 laravel 中注销用户

标签 laravel session redis memcached

我们目前使用 Memcached 来存储 Laravel 基于 cookie 的 session ,但希望始终使用 Redis 来存储 session 和缓存以实现一致性。

有没有办法在不注销用户的情况下将所有用户 session 从 Memcached 迁移到 Redis?

最佳答案

我能够在不注销用户的情况下迁移 session 。我为此目的创建了一个 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;
    }
}

希望可以帮助到其他人。

关于laravel - 将 session 从 memcached 迁移到 redis,无需在 laravel 中注销用户,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58620014/

相关文章:

php - Laravel 9 getDriver()、getAdapter() 和 getClient() 方法

php - 将复选框值保存到数据库中

mysql - 无法登录MySQL服务器

php - 如何在登录时向 symfony2 上的 session 注入(inject)特定值?

session - 如何在Cakephp 3.0中读写Session

php - 如何将多个字符串值传递给复选框?

oracle - 如何在PL/SQL包中将 session 变量skip_unusable_indexes设置为true以加速表删除/插入?

git - 从配置服务器获取application.properties时出现Redis连接失败错误

redis - 使用 redis 集成的公共(public)交通传奇导致异常

redis - 如何将用户添加到redis?