PHP 7.2 以降用の柔軟で機能が充実した Redis クライアント。
このプロジェクトの詳細については、よくある質問をご覧ください。
EVALSHA
またはEVAL
間の自動切り替え。SCAN
、 SSCAN
、 ZSCAN
およびHSCAN
(Redis >= 2.8) の抽象化。このライブラリは Packagist にあり、Composer を使用してプロジェクトの依存関係を簡単に管理できます。各リリースの圧縮アーカイブは 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 ' );
クライアントは、stunnel などの SSL プロキシを構成することなく、TLS/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()
の 2 番目の引数に渡すことで構成できます。
$ 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 は読み取り専用コマンドを認識し、ある種のロード バランシングを提供するためにそれらのコマンドをランダム スレーブに送信し、最終的に変更を伴う操作を実行するコマンドを検出するとすぐにマスターに切り替えます。キースペースまたはキーの値。スレーブに障害が発生したときに接続エラーを発生させる代わりに、クライアントは、構成で提供されているスレーブの中の別のスレーブにフォールバックしようとします。
レプリケーション モードでクライアントを使用するために必要な基本構成では、1 つの Redis サーバーがマスターとして識別される必要があります (これは、 role
パラメーターをmaster
に設定することで接続パラメーター経由で行うことができます)、および 1 つ以上のスレーブ (この場合は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 インスタンスを指す接続パラメーターのリスト、 replication
オプションをsentinel
に設定、 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 統合は、Redis データセットの部分レプリカを PHP 共有ランタイム メモリにキャッシュすることにより、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 への貢献は、新機能、バグ修正、または単なるバグ レポートのプル リクエストの形で高く評価されます。発行リクエストとプルリクエストのテンプレートに従うことのみをお願いします。
注意: Predis に同梱されているテスト スイートを、運用環境で実行されている Redis のインスタンスや、関心のあるデータが含まれている Redis のインスタンスに対して実行しないでください。
Predis には、ライブラリのあらゆる側面をカバーする包括的なテスト スイートがあり、必要に応じて、実行中の Redis インスタンスに対して統合テストを実行できます (各コマンドの実装の正しい動作を検証するには、2.4.0 以上が必要です。サポートされていないものの統合テスト) Redis コマンドは自動的にスキップされます。Redis が稼働していない場合、このライブラリのテストの詳細については、テストの README を参照してください。
Predis は継続的統合に GitHub Actions を使用しており、過去および現在のビルドの履歴はアクション ページで確認できます。
Predis のコードは、MIT ライセンスの条件に基づいて配布されます (「ライセンス」を参照)。