Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Laravel: Use Memcache instead of Filesystem

Whenever I load a page, I can see Laravel reading a great amount of data from the /storage folder.

Generally speaking, dynamic reading and writing to our filesystem is a bottleneck. We are using Google App Engine and our storage is in Google Cloud Storage, which means that one write or read is equal to a "remote" API request. Google Cloud Storage is fast, but I feel it's slow, when Laravel makes up to 10-20 Cloud Storage calls per request.

Is it possible to store the data in the Memcache instead of in the /storage directory? I believe this will give our systems a lot better performance.

NB. Both Session and Cache uses Memcache, but compiled views and meta is stored on the filesystem.

like image 255
Hedam Avatar asked Sep 27 '22 07:09

Hedam


1 Answers

In order to store compiled views in Memcache you'd need to replace the storage that Blade compiler uses.

First of all, you'll need a new storage class that extends Illuminate\Filesystem\Filesystem. The methods that BladeCompiler uses are listed below - you'll need to make them use Memcache.

  • exists
  • lastModified
  • get
  • put

A draft of this class is below, you might want to make it more sophisticated:

class MemcacheStorage extends Illuminate\Filesystem\Filesystem {
  protected $memcached;

  public function __construct() {
    $this->memcached = new Memcached();
    $this->memcached->addServer(Config::get('view.memcached_host'), Config::get('view.memcached_port');
  }

  public function exists($key) {
    return !empty($this->get($key));
  }

  public function get($key) {
    $value = $this->memcached->get($key);
    return $value ? $value['content'] : null;
  }

  public function put($key, $value) {
    return $this->memcached->set($key, ['content' => $value, 'modified' => time()]);
  }

  public function lastModified($key) {
    $value = $this->memcached->get($key);
    return $value ? $value['modified'] : null;
  }
}

Second thing is adding memcache config in your config/view.php:

'memcached_host' => 'localhost',
'memcached_port' => 11211

Last thing you'll need to do is to overwrite blade.compiler service in one of your service providers, so that it uses your brand new memcached storage:

$app->singleton('blade.compiler', function ($app) {
    $cache = $app['config']['view.compiled'];

    $storage = $app->make(MemcacheStorage::class);

    return new BladeCompiler($storage, $cache);
});

That should do the trick.

Please let me know if you see some typos or error, haven't had a chance to run it.

like image 120
jedrzej.kurylo Avatar answered Sep 29 '22 21:09

jedrzej.kurylo