PHP 7.2 이상을 위한 유연하고 기능이 완전한 Redis 클라이언트입니다.
본 프로젝트에 대한 자세한 내용은 자주 묻는 질문에서 확인하실 수 있습니다.
EVALSHA
또는 EVAL
간의 자동 전환.SCAN
, SSCAN
, ZSCAN
및 HSCAN
(Redis >= 2.8)에 대한 추상화입니다.이 라이브러리는 Composer를 사용하여 프로젝트 종속성을 더 쉽게 관리하기 위해 Packagist에서 찾을 수 있습니다. 각 릴리스의 압축 아카이브는 GitHub에서 사용할 수 있습니다.
composer require predis/predis
Predis는 필요할 때 파일을 로드하기 위해 PHP의 자동 로딩 기능을 사용하고 PSR-4 표준을 준수합니다. 자동 로딩은 Composer를 통해 종속성을 관리할 때 자동으로 처리되지만 자동 로드 기능이 없는 프로젝트나 스크립트에서 자체 자동 로더를 활용할 수도 있습니다.
// Prepend a base path if Predis is not available in your "include_path".
require ' Predis/Autoloader.php ' ;
Predis Autoloader:: register ();
연결 매개변수를 전달하지 않고 클라이언트 인스턴스를 생성할 때 Predis는 127.0.0.1
및 6379
기본 호스트 및 포트로 가정합니다. connect()
작업의 기본 시간 제한은 5초입니다.
$ client = new Predis Client ();
$ client -> set ( ' foo ' , ' bar ' );
$ value = $ client -> get ( ' foo ' );
연결 매개변수는 URI 문자열 또는 명명된 배열 형식으로 제공될 수 있습니다. 후자가 매개변수를 제공하는 데 선호되는 방법이지만, 구조화되지 않거나 부분적으로 구조화된 소스에서 매개변수를 읽을 때 URI 문자열이 유용할 수 있습니다.
// Parameters passed using a named array:
$ client = new Predis Client ([
' scheme ' => ' tcp ' ,
' host ' => ' 10.0.0.1 ' ,
' port ' => 6379 ,
]);
// Same set of parameters, passed using an URI string:
$ client = new Predis Client ( ' tcp://10.0.0.1:6379 ' );
비밀번호로 보호된 서버는 매개변수 세트에 password
추가하여 액세스할 수 있습니다. Redis >= 6.0에서 ACL이 활성화되면 사용자 인증을 위해 username
과 password
모두 필요합니다.
UNIX 도메인 소켓을 사용하여 Redis의 로컬 인스턴스에 연결할 수도 있습니다. 이 경우 매개변수는 unix
구성표를 사용하고 소켓 파일의 경로를 지정해야 합니다.
$ client = new Predis Client ([ ' scheme ' => ' unix ' , ' path ' => ' /path/to/redis.sock ' ]);
$ client = new Predis Client ( ' unix:/path/to/redis.sock ' );
클라이언트는 TLS/SSL 암호화를 활용하여 stunnel과 같은 SSL 프록시를 구성할 필요 없이 보안된 원격 Redis 인스턴스에 연결할 수 있습니다. 이는 다양한 클라우드 호스팅 제공업체에서 실행되는 노드에 연결할 때 유용할 수 있습니다. tls
구성표와 ssl
매개변수를 통해 전달된 적절한 옵션 배열을 사용하여 암호화를 활성화할 수 있습니다.
// Named array of connection parameters:
$ client = new Predis Client ([
' scheme ' => ' tls ' ,
' ssl ' => [ ' cafile ' => ' private.pem ' , ' verify_peer ' => true ],
]);
// Same set of parameters, but using an URI string:
$ client = new Predis Client ( ' tls://127.0.0.1?ssl[cafile]=private.pem&ssl[verify_peer]=1 ' );
연결 체계 redis
( tcp
별칭) 및 rediss
( tls
별칭)도 지원되지만, 이러한 체계가 포함된 URI 문자열은 해당 IANA 임시 등록 문서에 설명된 규칙에 따라 구문 분석된다는 차이점이 있습니다.
지원되는 연결 매개변수의 실제 목록은 각 연결 백엔드에 따라 다를 수 있으므로 자세한 내용은 특정 문서나 구현을 참조하는 것이 좋습니다.
Predis는 일련의 연결 매개변수와 이를 집계하는 방법(클러스터링, 복제 또는 사용자 지정 집계 논리)을 클라이언트에 지시하는 적절한 옵션을 제공할 때 여러 연결을 집계할 수 있습니다. 각 노드에 대한 구성을 제공할 때 명명된 배열과 URI 문자열을 혼합할 수 있습니다.
$ client = new Predis Client ([
' tcp://10.0.0.1?alias=first-node ' , [ ' host ' => ' 10.0.0.2 ' , ' alias ' => ' second-node ' ],
], [
' cluster ' => ' predis ' ,
]);
자세한 내용은 이 문서의 집계 연결 섹션을 참조하세요.
Redis에 대한 연결은 지연되어 클라이언트가 필요한 경우에만 서버에 연결됩니다. 클라이언트가 내부적으로 자체 작업을 수행하도록 하는 것이 권장되지만 연결이 열리거나 닫힐 때를 제어하고 싶은 경우가 있을 수 있습니다. 이는 $client->connect()
호출하여 쉽게 달성할 수 있습니다. $client->connect()
및 $client->disconnect()
. 집계 연결에 대한 이러한 메서드의 효과는 각 특정 구현에 따라 다를 수 있습니다.
특정 클라이언트 옵션을 PredisClient::__construct()
의 두 번째 인수에 전달하여 클라이언트의 다양한 측면과 동작을 구성할 수 있습니다.
$ client = new Predis Client ( $ parameters , [ ' prefix ' => ' sample: ' ]);
옵션은 미니 DI와 유사한 컨테이너를 사용하여 관리되며 해당 값은 필요할 때만 느리게 초기화될 수 있습니다. Predis에서 기본적으로 지원되는 클라이언트 옵션은 다음과 같습니다.
prefix
: 명령에서 발견된 모든 키에 적용되는 접두사 문자열입니다.exceptions
: 클라이언트가 Redis 오류 시 응답을 던지거나 반환해야 하는지 여부입니다.connections
: 연결 백엔드 또는 연결 팩토리 인스턴스 목록입니다.cluster
: 클러스터 백엔드( predis
, redis
또는 callable)를 지정합니다.replication
: 복제 백엔드( predis
, sentinel
또는 callable)를 지정합니다.aggregate
: 사용자 정의 집계 연결(호출 가능)로 클라이언트를 구성합니다.parameters
: 집계 연결에 대한 기본 연결 매개변수 목록입니다.commands
: 라이브러리를 통해 사용할 명령 팩토리 인스턴스를 지정합니다.사용자는 나중에 라이브러리를 통해 사용할 수 있도록 옵션 컨테이너에 저장된 값 또는 호출 가능한 개체(지연 초기화용)를 사용하여 사용자 지정 옵션을 제공할 수도 있습니다.
집계 연결은 Predis가 클러스터링 및 복제를 구현하는 기반이며 단일 Redis 노드에 대한 여러 연결을 그룹화하고 상황에 따라 적절하게 처리하는 데 필요한 특정 논리를 숨기는 데 사용됩니다. 집계 연결에는 일반적으로 새 클라이언트 인스턴스를 생성할 때 적절한 클라이언트 옵션과 함께 일련의 연결 매개변수가 필요합니다.
Predis는 전통적인 클라이언트 측 샤딩 접근 방식을 사용하여 클러스터링 모드에서 작동하여 독립 노드 클러스터를 생성하고 노드 간에 키스페이스를 배포하도록 구성할 수 있습니다. 이 접근 방식에는 일종의 외부 상태 모니터링이 필요하며 노드가 추가되거나 제거될 때 키스페이스를 수동으로 재조정해야 합니다.
$ parameters = [ ' tcp://10.0.0.1 ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' cluster ' => ' predis ' ];
$ client = new Predis Client ( $ parameters );
Redis 3.0과 함께 새로운 감독 및 조정 유형의 클러스터링이 redis-cluster 형태로 도입되었습니다. 이러한 종류의 접근 방식은 다른 알고리즘을 사용하여 키스페이스를 배포하며 Redis 노드는 가십 프로토콜을 통해 통신하여 자체적으로 조정하여 상태, 재조정, 노드 검색 및 요청 리디렉션을 처리합니다. redis-cluster가 관리하는 클러스터에 연결하려면 클라이언트에 노드 목록이 필요하며(필요한 경우 새 노드를 자동으로 검색하므로 반드시 완료될 필요는 없음) cluster
클라이언트 옵션이 redis
로 설정되어야 합니다.
$ parameters = [ ' tcp://10.0.0.1 ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' cluster ' => ' redis ' ];
$ client = new Predis Client ( $ parameters , $ options );
더 나은 서비스 가용성을 제공하기 위해 클라이언트는 단일 마스터/다중 슬레이브 설정에서 작동하도록 구성할 수 있습니다. 복제를 사용할 때 Predis는 일종의 로드 밸런싱을 제공하기 위해 읽기 전용 명령을 인식하고 이를 임의의 슬레이브에 전송하며, 결국 수정이 필요한 작업을 수행하는 명령을 감지하는 즉시 마스터로 전환합니다. 키스페이스 또는 키 값. 슬레이브에 장애가 발생하면 연결 오류를 발생시키는 대신 클라이언트는 구성에 제공된 슬레이브 중 다른 슬레이브로 폴백을 시도합니다.
복제 모드에서 클라이언트를 사용하는 데 필요한 기본 구성에는 마스터로 식별되는 하나의 Redis 서버( role
매개변수를 master
로 설정하여 연결 매개변수를 통해 수행 가능)와 하나 이상의 슬레이브(이 경우 role
slave
로 설정)가 필요합니다. 노예의 경우 선택 사항입니다):
$ parameters = [ ' tcp://10.0.0.1?role=master ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' replication ' => ' predis ' ];
$ client = new Predis Client ( $ parameters , $ options );
위 구성에는 서버의 정적 목록이 있으며 전적으로 클라이언트의 논리에 의존하지만 서비스 검색을 위해 클라이언트의 권한 소스 역할을 하는 sentinel 서버가 있는 보다 강력한 HA 환경을 위해 redis-sentinel
에 의존하는 것이 가능합니다. redis-sentinel을 사용하기 위해 클라이언트에 필요한 최소 구성은 여러 sentinel 인스턴스를 가리키는 연결 매개변수 목록, sentinel
로 설정된 replication
옵션, 서비스 이름으로 설정된 service
옵션입니다.
$ sentinels = [ ' tcp://10.0.0.1 ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' replication ' => ' sentinel ' , ' service ' => ' mymaster ' ];
$ client = new Predis Client ( $ sentinels , $ options );
마스터 및 슬레이브 노드가 클라이언트의 인증을 요구하도록 구성된 경우 전역 parameters
클라이언트 옵션을 통해 비밀번호를 제공해야 합니다. 이 옵션을 사용하여 다른 데이터베이스 인덱스를 지정할 수도 있습니다. 그러면 클라이언트 옵션 배열은 다음과 같습니다.
$ options = [
' replication ' => ' sentinel ' ,
' service ' => ' mymaster ' ,
' parameters ' => [
' password ' => $ secretpassword ,
' database ' => 10 ,
],
];
Predis는 쓰기 및 읽기 전용 작업을 수행하는 명령을 구별할 수 있지만 EVAL
및 EVALSHA
Lua 스크립트가 슬레이브에서 실행하기에 안전한 시기를 알 수 없기 때문에 클라이언트가 마스터 노드로 전환하는 코너 케이스를 나타냅니다. 이것이 실제로 기본 동작이지만 특정 Lua 스크립트가 쓰기 작업을 수행하지 않는 경우 클라이언트에게 슬레이브를 사용하여 실행하도록 지시하는 힌트를 제공할 수 있습니다.
$ parameters = [ ' tcp://10.0.0.1?role=master ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' replication ' => function () {
// Set scripts that won't trigger a switch from a slave to the master node.
$ strategy = new Predis Replication ReplicationStrategy ();
$ strategy -> setScriptReadOnly ( $ LUA_SCRIPT );
return new Predis Connection Replication MasterSlaveReplication ( $ strategy );
}];
$ client = new Predis Client ( $ parameters , $ options );
$ client -> eval ( $ LUA_SCRIPT , 0 ); // Sticks to slave using `eval`...
$ client -> evalsha ( sha1 ( $ LUA_SCRIPT ), 0 ); // ... and `evalsha`, too.
examples
디렉터리에는 기본 시나리오와 복잡한 시나리오 모두에서 복제를 활용하기 위해 클라이언트를 구성하고 사용하는 방법을 보여주는 몇 가지 스크립트가 포함되어 있습니다.
파이프라이닝은 네트워크 왕복 타이밍으로 인해 발생하는 대기 시간을 줄여 서버에 많은 명령을 전송해야 할 때 성능을 높이는 데 도움이 될 수 있습니다. 파이프라이닝은 집계 연결에서도 작동합니다. 클라이언트는 호출 가능한 블록 내에서 파이프라인을 실행하거나 유연한 인터페이스 덕분에 명령을 연결하는 기능을 갖춘 파이프라인 인스턴스를 반환할 수 있습니다.
// Executes a pipeline inside the given callable block:
$ responses = $ client -> pipeline ( function ( $ pipe ) {
for ( $ i = 0 ; $ i < 1000 ; $ i ++) {
$ pipe -> set ( " key: $ i " , str_pad ( $ i , 4 , ' 0 ' , 0 ));
$ pipe -> get ( " key: $ i " );
}
});
// Returns a pipeline that can be chained thanks to its fluent interface:
$ responses = $ client -> pipeline ()-> set ( ' foo ' , ' bar ' )-> get ( ' foo ' )-> execute ();
클라이언트는 명령 파이프라인과 유사한 인터페이스를 사용하여 MULTI
및 EXEC
기반으로 하는 Redis 트랜잭션에 대한 추상화를 제공합니다.
// Executes a transaction inside the given callable block:
$ responses = $ client -> transaction ( function ( $ tx ) {
$ tx -> set ( ' foo ' , ' bar ' );
$ tx -> get ( ' foo ' );
});
// Returns a transaction that can be chained thanks to its fluent interface:
$ responses = $ client -> transaction ()-> set ( ' foo ' , ' bar ' )-> get ( ' foo ' )-> execute ();
이 추상화는 WATCH
및 UNWATCH
덕분에 확인 및 설정 작업을 수행할 수 있으며 WATCH
키를 터치할 때 Redis가 중단한 트랜잭션을 자동으로 재시도합니다. CAS를 사용한 트랜잭션의 예는 다음 예를 참조하세요.
Redis에서 사용할 수 있는 모든 명령을 최신 상태로 유지하기 위해 Predis를 업데이트하려고 시도하는 동안 사용자는 이전 버전의 라이브러리를 사용하거나 인수를 필터링하거나 특정 명령에 대한 응답을 구문 분석하는 다른 방법을 제공하는 것을 선호할 수 있습니다. 이를 달성하기 위해 Predis는 클라이언트가 사용하는 기본 명령 팩토리에서 명령을 정의하거나 재정의하는 새로운 명령 클래스를 구현하는 기능을 제공합니다.
// Define a new command by extending PredisCommandCommand:
class BrandNewRedisCommand extends Predis Command Command
{
public function getId ()
{
return ' NEWCMD ' ;
}
}
// Inject your command in the current command factory:
$ client = new Predis Client ( $ parameters , [
' commands ' => [
' newcmd ' => ' BrandNewRedisCommand ' ,
],
]);
$ response = $ client -> newcmd ();
인수를 필터링하거나 응답을 구문 분석하지 않고 원시 명령을 보내는 방법도 있습니다. 사용자는 명령에 대한 Redis 설명서에 정의된 서명에 따라 명령에 대한 인수 목록을 배열로 제공해야 합니다.
$ response = $ client -> executeRaw ([ ' SET ' , ' foo ' , ' bar ' ]);
EVAL
및 EVALSHA
직접 사용하여 Redis 2.6 이상에서 Lua 스크립팅을 활용하는 것이 가능하지만 Predis는 작업을 단순화하기 위해 스크립트 명령을 기반으로 구축된 더 높은 수준의 추상화로 제공합니다. 스크립트 명령은 클라이언트가 사용하는 명령 팩토리에 등록할 수 있고 일반 Redis 명령인 것처럼 액세스할 수 있지만 원격 실행을 위해 서버로 전송되는 Lua 스크립트를 정의합니다. 내부적으로는 기본적으로 EVALSHA
사용하고 대역폭을 절약하기 위해 SHA1 해시로 스크립트를 식별하지만 필요할 경우 EVAL
대체 수단으로 사용됩니다.
// Define a new script command by extending PredisCommandScriptCommand:
class ListPushRandomValue extends Predis Command ScriptCommand
{
public function getKeysCount ()
{
return 1 ;
}
public function getScript ()
{
return <<<LUA
math.randomseed(ARGV[1])
local rnd = tostring(math.random())
redis.call('lpush', KEYS[1], rnd)
return rnd
LUA ;
}
}
// Inject the script command in the current command factory:
$ client = new Predis Client ( $ parameters , [
' commands ' => [
' lpushrand ' => ' ListPushRandomValue ' ,
],
]);
$ response = $ client -> lpushrand ( ' random_values ' , $ seed = mt_rand ());
Predis는 다양한 연결 백엔드를 사용하여 Redis에 연결할 수 있습니다. 내장된 Relay 통합은 PHP 공유 런타임 메모리에 Redis 데이터 세트의 부분 복제본을 캐시하여 주요 성능 향상을 위해 PHP용 Relay 확장을 활용합니다.
$ client = new Predis Client ( ' tcp://127.0.0.1 ' , [
' connections ' => ' relay ' ,
]);
개발자는 완전히 새로운 네트워크 백엔드를 지원하거나 기존 클래스를 확장하거나 완전히 다른 구현을 제공하기 위해 자체 연결 클래스를 만들 수 있습니다. 연결 클래스는 PredisConnectionNodeConnectionInterface
구현하거나 PredisConnectionAbstractConnection
확장해야 합니다.
class MyConnectionClass implements Predis Connection NodeConnectionInterface
{
// Implementation goes here...
}
// Use MyConnectionClass to handle connections for the `tcp` scheme:
$ client = new Predis Client ( ' tcp://127.0.0.1 ' , [
' connections ' => [ ' tcp ' => ' MyConnectionClass ' ],
]);
새로운 연결 백엔드를 생성하는 방법에 대한 보다 심층적인 통찰력을 얻으려면 PredisConnection
네임스페이스에서 사용할 수 있는 표준 연결 클래스의 실제 구현을 참조할 수 있습니다.
새로운 기능에 대한 풀 요청, 버그 수정 또는 단순한 버그 보고서 형태로 Predis에 대한 기여를 높이 평가합니다. 이슈 및 풀 요청 템플릿을 준수하시기 바랍니다.
주의 : 프로덕션 환경에서 실행 중이거나 관심 있는 데이터가 포함된 Redis 인스턴스에 대해 Predis와 함께 제공된 테스트 스위트를 실행하지 마십시오!
Predis에는 라이브러리의 모든 측면을 포괄하는 포괄적인 테스트 모음이 있으며 선택적으로 실행 중인 Redis 인스턴스에 대해 통합 테스트를 수행할 수 있습니다(각 명령 구현의 올바른 동작을 확인하려면 2.4.0 이상 필요). 지원되지 않는 통합 테스트 Redis 명령은 자동으로 건너뜁니다. Redis가 실행되고 있지 않으면 통합 테스트를 비활성화할 수 있습니다. 이 라이브러리 테스트에 대한 자세한 내용은 테스트 README를 참조하세요.
Predis는 지속적인 통합을 위해 GitHub Actions를 사용하며 과거 및 현재 빌드의 기록은 작업 페이지에서 확인할 수 있습니다.
Predis용 코드는 MIT 라이선스 조건에 따라 배포됩니다(LICENSE 참조).