PHP 에서 PHPRedis 를 사용해서 redis 연계 하기

C 로 만든 PHP 용 Redis 모듈인 PHPRedis를 사용하여 Redis 와 연계하는 방법을 설명합니다.


Open Source Key/Value 저장소인 redis 는 다양한 개발 언어용 client 를 지원하고 있습니다.


PHP 에서 redis 에 연동하기 위한 client library 중 가장 유명한 것은 Pure PHP 로 개발한 predis 와 C 언어로 만든 PHP 모듈인 PHPRedis 두 가지입니다.


이중 C 로 만든 extension 인 PHPRedis 가 성능이 더 우수하다는 벤치마크 결과가 많으므로 이를 사용하여 PHP 에서 redis 에 연계하는 방법을 알아 보겠습니다.


설치

PHPRedis 는 C 로 만들었으므로 패키지로 제공되지 않을 경우 별도로 컴파일해서 설치해야 합니다.

컴파일하려면 C 컴파일러와 PHP 개발도구가 필요하므로 사전에 설치해 둡니다.

CentOS
yum install php-devel
Ubuntu
sudo apt install php-dev

Linux/OSX 

pecl 을 사용해서 설치하는 것이 가장 간편하며 root 로 실행해야 합니다.


  1. pecl 설치 명령어를 실행합니다.

    pecl install redis
  2. igbinary 지원을 yes 로 설정합니다.

    enable igbinary serializer support? [no] : yes
  3. lzf 압축 지원 여부를 설정합니다.

    enable lzf compression support? [no] : yes
  4. RHEL/CentOS 는 설치가 완료되면 php 의 모듈 디렉터리에 로딩을 위한 모듈 설정 파일을 만들어 둡니다.


    CentOS 에서 ini 생성
    sudo echo "extension=redis.so" > /etc/php.d/30-predis.ini   



  5. 설치가 완료되면 php 의 모듈 디렉터리에 로딩을 위한 모듈 설정 파일을 만들어 둡니다.

    CentOS 에서 ini 생성
    sudo echo "extension=redis.so" > /etc/php/7.3/mods-available/phpredis.ini
  6. ubuntu 는 phpenmod 로 간단하게 설정할 수 있습니다.

    Ubuntu 에서 redis 활성화
    sudo phpenmod redis

Windows

PECL 사이트에서 미리 컴파일해 놓은 바이너리를 다운로드 받습니다.

igbinary library 도 같이 사용하면 serialize 시 저장 공간이 줄고 속도도 빠르므로 같이 설치합니다.

이 글을 쓰는 현재 버전은 5.3.1 입니다.


다운받은 dll 을 PHP 의 ext 폴더에 넣고 php.ini 에 extension 을 추가합니다.

extension=redis


확인

커맨드에서 다음 명령을 실행하여 extension 에 redis 가 있는지 확인합니다.

redis 확인
$ php -r "phpinfo();"|grep redis


또는 다음 php 코드 수행해 봅니다.

php redis-test.php
redis-test.php
<?php
$redis = new Redis();
try {
    $redis->connect('127.0.0.1','6379', 2.5, NULL, 150);
    $key = 'myKey';
    $value = ['val1' => 'myValue1', 'val2' => 'Value2'];
    $ttl = 3600;
    $redis->setex( $key, $ttl, $value );
    $value = $redis->get($key);
    var_dump($value);
} catch(RedisException $e) {
    var_dump($e);
}
$redis->close();


설치가 완료되었으면 의존성 관리를 위해서 composer.json 에 의존성 설정을 추가해 줍니다.

composer.json 의존성 설정
"require": {
	"ext-redis": "*"
}


Laravel  에서 Facade 로 사용

Facade 방식으로 사용하려고 할 경우에만 아래 설정이 필요하고 new Redis; 구문으로 instance 를 생성해서 사용해도 됩니다.


라라벨의 Redis facade 는 PHPRedis 가 제공하는 기본 클래스 이름인 Redis 와 충돌하므로 config/app.php 에 다음과 같이 별도의 이름으로 변경해 줍니다.

'aliases' => [
        'PHPRedis' => Illuminate\Support\Facades\Redis::class,


config/database.php 에 clinet 를 phpredis 로 설정해 줍니다.

config/database.php
'redis' => [
        'client' => 'phpredis',


이제 Redis facade 대신 PHPRedis 를 사용하면 됩니다.

Redis Facade 사용
PHPRedis::set('a', 123);
$a = PHPRedis::get('a');
// $a = 123


SELinux 를 사용할 경우

SELinux 를 사용하는 경우 위 예제 코드는 쉘 상에서는 정상 동작하지만 웹 서버에서 실행하면 에러가 발생할 수 있습니다.

PHP Fatal error:  Uncaught exception 'RedisException' with message 'Redis server went away' in /var/www/html/redis.php:20


이는 SELinux 의 기본 보안 정책이 웹 서버는 redis 가 사용하는 포트인 6379 에 연결할 수 없기 때문입니다. 

이럴 경우 다음 명령어로 httpd 가 6379 포트에 연결할 수 있도록 설정해 주면 됩니다.


CentOS 6

semanage port -a -p tcp -t http_port_t 6379


CentOS 7

CentOS 은 redis_port_t 라는 context 가 추가되었으므로 다음 custom TE 를 작성한 후에 module 을 컴파일하고 로딩하면 됩니다.

  1.  httpd-redis.te  파일 작성

    httpd-redis.te
    module httpd-redis 1.0;
    require {
            type redis_port_t;
            type httpd_t;
            class tcp_socket name_connect;
    }
    #============= httpd_t ==============
    #!!!! This avc can be allowed using the boolean 'httpd_can_network_connect'
    allow httpd_t redis_port_t:tcp_socket name_connect;
  2. audit2allow 로 TE 컴파일

    audit2allow -a -M httpd-redis
  3. module 설치

    semodule -i httpd-redis.pp


같이 보기


Ref