Blog

ブログ

【ECCUBE4系】MemcachedにのせたDoctrineCacheのCacheClearコマンドを自作してみる

今日はcacheのお話です。

※今日は、大好きなEventSubscriberの出番はありません※

前置き

複数台構成でECCUBEを運用するときに、気になるのはcacheですよね!

cacheの恩恵は大きいですが、サーバーが複数台構成の時は困ってしまうことも。。。

今回は、3台構成のWebサーバーでDoctrineCacheをMemcachedで管理するときに、DoctrineCacheのクリアコマンドを自作したときのお話です。

DoctrineCacheをどうやってMemcachedにのせるの。。。?という内容は、ご要望があれば別日に書こうかと思ってます。

なので、今回はDoctrineCacheをどうやってMemcachedにのせる設定とかは割愛させて頂きます。

 

実際に作成したコマンド

app/Customize/Command配下に以下のファイルを作成しました。

<?php

namespace Customize\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Style\SymfonyStyle;

class DoctrineCacheClearCommand extends Command
{
    protected static $defaultName = 'memcached:doctrine-cache:clear';

    const SESSION_PREFIX = 'session';

    /**
     * @var SymfonyStyle
     */
    protected $io;

    protected function initialize(InputInterface $input, OutputInterface $output)
    {
        $this->io = new SymfonyStyle($input, $output);
    }

    protected function execute(InputInterface $input, OutputInterface $output)
    {
        try {
            $memcached = new \Memcached();
            $memcached->addServer(env('MEMCACHED_HOST'), env('MEMCACHED_PORT'));
            $keys = $memcached->getAllKeys();

            foreach ($keys as $key) {
                if (substr($key, 0, 7) !== self::SESSION_PREFIX) {
                    $memcached->delete($key);
                }
            }

            $this->io->success('Doctrine Memcached All Clear.');
        } catch (\Error $e) {
            $this->io->error('Doctrine Memcached Clear Failure Error.');
        } catch (\Exception $e) {
            $this->io->error('Doctrine Memcached Clear Failure Exception.');
        }

        return true;
    }
}

処理の説明

今回はsessionもMemcachedにのせているので、Memcachedをflush_allするというわけにはいきませんでした。

session情報も消えてしまうので、releaseする度にCustomerが再ログインしなければならないなんて、ユーザビリティ悪すぎですもんね。。。

 

方法はとてもシンプルです!

Memcachedから全てのkeyを取得して、sessionのプレフィックスがついているもの以外を順次削除していくだけです!

本当は。。。

DoctrineCacheにプレフィックスを作成して、そのプレフィックスのkeyを取得して消すという方法を取りたかったのですが、DoctrineCacheの時はプレフィックスをつけられなかったのです。。。

まだまだ勉強不足なんでしょうね。。。

 

使い道

管理画面からキャッシュクリアを行うときに合わせて呼び出すように改修したり。。。

デプロイ用のスクリプトに組み込んでみたり。。。

サーバーで直接叩いてみたり。。。

と、使っています。

サーバーが複数台構成でも、cacheとは上手く付き合っていきたいですよね、やはり画面の表示速度が違います!

 

最後に

今回は自作でキャッシュクリアのコマンドを作ってみた時のお話でした。

最近は画面側を作成するより、外部連携等のBatch作成の方が楽しいなーなんて思ってます。

この機会に、サーバーが複数台構成でもcacheと上手くお付き合いできる方法を考えてみませんか?