Un client Redis flexible et complet pour PHP 7.2 et versions ultérieures.
Plus de détails sur ce projet peuvent être trouvés dans la foire aux questions.
EVALSHA
ou EVAL
.SCAN
, SSCAN
, ZSCAN
et HSCAN
(Redis >= 2.8) basée sur des itérateurs PHP.Cette bibliothèque est disponible sur Packagist pour une gestion plus simple des dépendances des projets à l'aide de Composer. Les archives compressées de chaque version sont disponibles sur GitHub.
composer require predis/predis
Predis s'appuie sur les fonctionnalités de chargement automatique de PHP pour charger ses fichiers en cas de besoin et est conforme à la norme PSR-4. Le chargement automatique est géré automatiquement lorsque les dépendances sont gérées via Composer, mais il est également possible d'exploiter son propre chargeur automatique dans des projets ou des scripts dépourvus de fonctionnalité de chargement automatique :
// Prepend a base path if Predis is not available in your "include_path".
require ' Predis/Autoloader.php ' ;
Predis Autoloader:: register ();
Lors de la création d'une instance client sans transmettre aucun paramètre de connexion, Predis suppose 127.0.0.1
et 6379
comme hôte et port par défaut. Le délai d'attente par défaut pour l'opération connect()
est de 5 secondes :
$ client = new Predis Client ();
$ client -> set ( ' foo ' , ' bar ' );
$ value = $ client -> get ( ' foo ' );
Les paramètres de connexion peuvent être fournis sous forme de chaînes URI ou de tableaux nommés. Cette dernière méthode est la meilleure pour fournir des paramètres, mais les chaînes URI peuvent être utiles lorsque les paramètres sont lus à partir de sources non structurées ou partiellement structurées :
// 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 ' );
Les serveurs protégés par mot de passe sont accessibles en ajoutant password
aux paramètres définis. Lorsque les ACL sont activées sur Redis >= 6.0, username
et password
sont requis pour l'authentification de l'utilisateur.
Il est également possible de se connecter à des instances locales de Redis à l'aide de sockets de domaine UNIX, dans ce cas les paramètres doivent utiliser le schéma unix
et spécifier un chemin pour le fichier socket :
$ client = new Predis Client ([ ' scheme ' => ' unix ' , ' path ' => ' /path/to/redis.sock ' ]);
$ client = new Predis Client ( ' unix:/path/to/redis.sock ' );
Le client peut tirer parti du cryptage TLS/SSL pour se connecter à des instances Redis distantes sécurisées sans avoir besoin de configurer un proxy SSL tel que Stunnel. Cela peut être utile lors de la connexion à des nœuds exécutés sur différents fournisseurs d'hébergement cloud. Le cryptage peut être activé à l'aide du schéma tls
et d'un ensemble d'options appropriées transmises via le paramètre 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 ' );
Les schémas de connexion redis
(alias de tcp
) et rediss
(alias de tls
) sont également pris en charge, à la différence que les chaînes URI contenant ces schémas sont analysées selon les règles décrites dans leurs documents d'enregistrement provisoires IANA respectifs.
La liste réelle des paramètres de connexion pris en charge peut varier en fonction de chaque backend de connexion. Il est donc recommandé de se référer à leur documentation spécifique ou à leur implémentation pour plus de détails.
Predis peut regrouper plusieurs connexions en fournissant un tableau de paramètres de connexion et l'option appropriée pour indiquer au client comment les regrouper (clustering, réplication ou logique d'agrégation personnalisée). Les tableaux nommés et les chaînes URI peuvent être mélangés lors de la fourniture de configurations pour chaque nœud :
$ client = new Predis Client ([
' tcp://10.0.0.1?alias=first-node ' , [ ' host ' => ' 10.0.0.2 ' , ' alias ' => ' second-node ' ],
], [
' cluster ' => ' predis ' ,
]);
Consultez la section Connexions globales de ce document pour plus de détails.
Les connexions à Redis sont paresseuses, ce qui signifie que le client se connecte à un serveur uniquement si et quand cela est nécessaire. Bien qu'il soit recommandé de laisser le client faire ses propres tâches en coulisse, il peut y avoir des moments où il est toujours souhaité de contrôler le moment où la connexion est ouverte ou fermée : cela peut facilement être réalisé en appelant $client->connect()
et $client->disconnect()
. Veuillez noter que l'effet de ces méthodes sur les connexions globales peut différer en fonction de chaque implémentation spécifique.
De nombreux aspects et comportements du client peuvent être configurés en passant des options client spécifiques au deuxième argument de PredisClient::__construct()
:
$ client = new Predis Client ( $ parameters , [ ' prefix ' => ' sample: ' ]);
Les options sont gérées à l'aide d'un mini conteneur de type DI et leurs valeurs peuvent être initialisées paresseusement uniquement en cas de besoin. Les options client prises en charge par défaut dans Predis sont :
prefix
: chaîne de préfixe appliquée à chaque touche trouvée dans les commandes.exceptions
: indique si le client doit lancer ou renvoyer des réponses en cas d'erreurs Redis.connections
: liste des backends de connexion ou une instance de fabrique de connexions.cluster
: spécifie un backend de cluster ( predis
, redis
ou callable).replication
: spécifie un backend de réplication ( predis
, sentinel
ou callable).aggregate
: configure le client avec une connexion agrégée personnalisée (appelable).parameters
: liste des paramètres de connexion par défaut pour les connexions agrégées.commands
: spécifie une instance de fabrique de commandes à utiliser via la bibliothèque.Les utilisateurs peuvent également fournir des options personnalisées avec des valeurs ou des objets appelables (pour une initialisation paresseuse) qui sont stockés dans le conteneur d'options pour une utilisation ultérieure via la bibliothèque.
Les connexions agrégées constituent la base sur laquelle Predis implémente le clustering et la réplication. Elles sont utilisées pour regrouper plusieurs connexions à des nœuds Redis uniques et masquer la logique spécifique nécessaire pour les gérer correctement en fonction du contexte. Les connexions agrégées nécessitent généralement un tableau de paramètres de connexion ainsi que l'option client appropriée lors de la création d'une nouvelle instance client.
Predis peut être configuré pour fonctionner en mode clustering avec une approche traditionnelle de partitionnement côté client afin de créer un cluster de nœuds indépendants et de distribuer l'espace de clés entre eux. Cette approche nécessite une sorte de surveillance externe de l’état des nœuds et nécessite que l’espace de clés soit rééquilibré manuellement lorsque des nœuds sont ajoutés ou supprimés :
$ parameters = [ ' tcp://10.0.0.1 ' , ' tcp://10.0.0.2 ' , ' tcp://10.0.0.3 ' ];
$ options = [ ' cluster ' => ' predis ' ];
$ client = new Predis Client ( $ parameters );
Parallèlement à Redis 3.0, un nouveau type de clustering supervisé et coordonné a été introduit sous la forme de redis-cluster. Ce type d'approche utilise un algorithme différent pour distribuer les espaces de clés, les nœuds Redis se coordonnant en communiquant via un protocole de potins pour gérer l'état de santé, le rééquilibrage, la découverte des nœuds et la redirection des demandes. Afin de se connecter à un cluster géré par redis-cluster, le client nécessite une liste de ses nœuds (pas forcément complète puisqu'il découvrira automatiquement de nouveaux nœuds si nécessaire) et les options du client cluster
définies sur 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 );
Le client peut être configuré pour fonctionner dans une configuration à un seul maître/plusieurs esclaves afin d'offrir une meilleure disponibilité du service. Lors de l'utilisation de la réplication, Predis reconnaît les commandes en lecture seule et les envoie à un esclave aléatoire afin de fournir une sorte d'équilibrage de charge et passe au maître dès qu'il détecte une commande qui effectue tout type d'opération qui finirait par modifier l'espace de clé ou la valeur d'une clé. Au lieu de générer une erreur de connexion lorsqu'un esclave tombe en panne, le client tente de revenir à un esclave différent parmi ceux fournis dans la configuration.
La configuration de base nécessaire pour utiliser le client en mode réplication nécessite qu'un serveur Redis soit identifié comme maître (cela peut être fait via les paramètres de connexion en définissant le paramètre role
sur master
) et un ou plusieurs esclaves (dans ce cas, en définissant role
sur slave
pour les esclaves est facultatif) :
$ 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 );
La configuration ci-dessus comporte une liste statique de serveurs et repose entièrement sur la logique du client, mais il est possible de s'appuyer sur redis-sentinel
pour un environnement HA plus robuste avec des serveurs sentinelles agissant comme source d'autorité pour les clients pour la découverte de services. La configuration minimale requise par le client pour travailler avec redis-sentinel est une liste de paramètres de connexion pointant vers un groupe d'instances sentinelle, l'option replication
définie sur sentinel
et l'option service
définie sur le nom du 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 );
Si les nœuds maître et esclave sont configurés pour exiger une authentification des clients, un mot de passe doit être fourni via l'option client parameters
globaux. Cette option peut également être utilisée pour spécifier un index de base de données différent. Le tableau des options client ressemblerait alors à ceci :
$ options = [
' replication ' => ' sentinel ' ,
' service ' => ' mymaster ' ,
' parameters ' => [
' password ' => $ secretpassword ,
' database ' => 10 ,
],
];
Alors que Predis est capable de distinguer les commandes effectuant des opérations d'écriture et de lecture seule, EVAL
et EVALSHA
représentent un cas particulier dans lequel le client passe au nœud maître car il ne peut pas dire quand un script Lua peut être exécuté en toute sécurité sur les esclaves. Bien qu'il s'agisse effectivement du comportement par défaut, lorsque certains scripts Lua n'effectuent pas d'opérations d'écriture, il est possible de fournir un indice pour dire au client de s'en tenir aux esclaves pour leur exécution :
$ 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.
Le répertoire examples
contient quelques scripts qui montrent comment le client peut être configuré et utilisé pour exploiter la réplication dans des scénarios de base et complexes.
Le pipeline peut améliorer les performances lorsque de nombreuses commandes doivent être envoyées à un serveur en réduisant la latence introduite par les délais d'aller-retour du réseau. Le pipeline fonctionne également avec des connexions globales. Le client peut exécuter le pipeline à l'intérieur d'un bloc appelable ou renvoyer une instance de pipeline avec la possibilité d'enchaîner des commandes grâce à son interface fluide :
// 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 ();
Le client fournit une abstraction pour les transactions Redis basée sur MULTI
et EXEC
avec une interface similaire aux pipelines de commandes :
// 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 ();
Cette abstraction peut effectuer des opérations de vérification et de définition grâce à WATCH
et UNWATCH
et fournit des tentatives automatiques de transactions interrompues par Redis lorsque les touches WATCH
ed sont appuyées. Pour un exemple de transaction utilisant CAS, vous pouvez voir l'exemple suivant.
Pendant que nous essayons de mettre à jour Predis pour rester à jour avec toutes les commandes disponibles dans Redis, vous préférerez peut-être vous en tenir à une ancienne version de la bibliothèque ou proposer une manière différente de filtrer les arguments ou d'analyser les réponses pour des commandes spécifiques. Pour y parvenir, Predis offre la possibilité d'implémenter de nouvelles classes de commandes pour définir ou remplacer les commandes dans la fabrique de commandes par défaut utilisée par le client :
// 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 ();
Il existe également une méthode pour envoyer des commandes brutes sans filtrer leurs arguments ni analyser les réponses. Les utilisateurs doivent fournir la liste des arguments de la commande sous forme de tableau, en suivant les signatures telles que définies par la documentation Redis pour les commandes :
$ response = $ client -> executeRaw ([ ' SET ' , ' foo ' , ' bar ' ]);
Bien qu'il soit possible d'exploiter les scripts Lua sur Redis 2.6+ en utilisant directement EVAL
et EVALSHA
, Predis propose des commandes de script comme une abstraction de niveau supérieur construite sur elles pour simplifier les choses. Les commandes de script peuvent être enregistrées dans la fabrique de commandes utilisée par le client et sont accessibles comme s'il s'agissait de simples commandes Redis, mais elles définissent des scripts Lua qui sont transmis au serveur pour une exécution à distance. En interne, ils utilisent EVALSHA
par défaut et identifient un script par son hachage SHA1 pour économiser de la bande passante, mais EVAL
est utilisé comme solution de secours en cas de besoin :
// 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 peut utiliser différents backends de connexion pour se connecter à Redis. L'intégration Relay intégrée exploite l'extension Relay pour PHP pour des gains de performances majeurs, en mettant en cache une réplique partielle de l'ensemble de données Redis dans la mémoire d'exécution partagée PHP.
$ client = new Predis Client ( ' tcp://127.0.0.1 ' , [
' connections ' => ' relay ' ,
]);
Les développeurs peuvent créer leurs propres classes de connexion pour prendre en charge de tout nouveaux backends réseau, étendre les classes existantes ou fournir des implémentations complètement différentes. Les classes de connexion doivent implémenter PredisConnectionNodeConnectionInterface
ou étendre 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 ' ],
]);
Pour un aperçu plus approfondi de la façon de créer de nouveaux backends de connexion, vous pouvez vous référer à l'implémentation réelle des classes de connexion standard disponibles dans l'espace de noms PredisConnection
.
Les contributions à Predis sont très appréciées, que ce soit sous la forme de demandes d'extraction de nouvelles fonctionnalités, de corrections de bugs ou simplement de rapports de bugs. Nous vous demandons uniquement de respecter les modèles de problème et de demande d'extraction.
ATTENTION : N'exécutez jamais la suite de tests livrée avec Predis sur des instances de Redis exécutées dans des environnements de production ou contenant des données qui vous intéressent !
Predis dispose d'une suite de tests complète couvrant tous les aspects de la bibliothèque et qui peut éventuellement effectuer des tests d'intégration sur une instance en cours d'exécution de Redis (requis >= 2.4.0 afin de vérifier le comportement correct de l'implémentation de chaque commande. Tests d'intégration pour les non pris en charge Les commandes Redis sont automatiquement ignorées. Si Redis n'est pas opérationnel, les tests d'intégration peuvent être désactivés. Consultez le fichier README des tests pour plus de détails sur les tests de cette bibliothèque.
Predis utilise GitHub Actions pour l'intégration continue et l'historique des versions passées et actuelles peut être trouvé sur sa page d'actions.
Le code de Predis est distribué selon les termes de la licence MIT (voir LICENCE).