menu-icon

Laravel 8のRedisクライアントのパフォーマンスの比較

現在、LaravelではRedisクライアントとして PhpRedisPredisの2つが利用可能です。PHP extensionであるPhpRedisの方がパフォーマンスが高いとは思いますが、どの程度の違いがあるのか気になったので比較してみました。

LaravelのRedisクライアント

まず、それぞれについてのおさらいです。

PhpRedis

phpredis/phpredis

Redisサーバーと通信するためのAPIを提供するextensionです。C言語で実装されています。

Predis

predis/predis

Redisサーバーと通信するためのAPIを提供するパッケージです。composerでインストールでき、extensionが導入できない環境でも使えます。

Predisの削除に関して

Laravel 6のリリース時点では、Predisは長期間放置されていたため、将来のリリースで削除する旨がドキュメントに記載されていました(Redis 6.x Laravel)。しかし、メンテナンスが再び行われるようになり、Laravel 7 からは「削除」という文言はなくなりました(Redis 7.x Laravel)。PhpRedisを推奨しているのは変わらないですが、今後もPredisの利用はできると思ってよさそうです。

比較方法

Redisとデータをやり取りするだけのバッチを作り、それぞれのクライアントでの実行時間を比較します。

環境

使用したバージョンは以下です。

  • Redis 3.2(predisの対応バージョン)
  • PHP 7.4
  • Laravel 8

参考までに docker-compose.ymlも載せておきます。

docker-compose.yml
version: '3'
services:
  app:
    build: ./docker/php
    volumes:
      - .:/var/www/html
    links:
      - redis
  redis:
    image: redis:3.2
    volumes:
      - redis:/data
volumes:
  redis:
    driver: local
docker/php/Dockerfile
FROM php:7.4-fpm

COPY --from=composer /usr/bin/composer /usr/bin/composer

RUN apt-get update \
    && apt-get install -y \
        git \
        unzip \
        zip \
    && pecl install redis \
    && docker-php-ext-enable redis

WORKDIR /var/www/html

バッチ

単純にデータを読み書きするバッチです。Redisのヘビーユースを想定して、読み書き共に10000回繰り返しています(ちょっとヘビー過ぎたかも知れません)。

app/Console/Commands/RedisBenchmark.php
<?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use Illuminate\Support\Facades\Redis;

class RedisBenchmark extends Command
{
    private const REPEAT_NUM = 10000;

    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'redis:benchmark';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Check redis connector\'s performance';

    /**
     * Execute the console command.
     *
     * @return int
     */
    public function handle()
    {
        for ($i = 0; $i < self::REPEAT_NUM; $i++) {
            Redis::set($this->getKey($i), 'hoge');
        }
        
        for ($i = 0; $i < self::REPEAT_NUM; $i++) {
            Redis::get($this->getKey($i));
        }

        return 0;
    }
    
    private function getKey(int $no): string
    {
        return "data.key.{$no}";
    }
}

バッチの実行

timeコマンドで時間を計測します。

$ time php artisan redis:benchmark

なおクライアントの切り替えは、環境変数REDIS_CLIENTで行います。

結果

上記のコマンドをそれぞれ50回実行し、平均(±標準偏差)を算出しました。

  • PhpRedis … 1.317 ± 0.03 (秒)
  • Predis … 1.509 ± 0.026 (秒)

Predisを使用した場合の処理時間はPhpRedisの場合の約1割増しと、明らかに差がでました。実際のアプリケーションだと、ここまでの差はでないと思いますが、導入の手間以外にデメリットもなさそうなので、多少手間だとしても可能ならばPhpRedisを使いたいです。

まとめ

Laravel 8 でPhpRedisPredisを比較しました。PhpRedisの方が普通に速いので、導入できる環境であれば、Laravelの推奨に従ってPhpRedisで良さそうです。