连接服务器
Predis 提供了各式各样连接服务器或服务器集群的方式。通过指定两个以上服务器,Predis 自动切换集群连接,透明地处理多个连接上的客户端分片。应该注意的是,集群连接相比单一连接(即 Predis 被连接到一个单独的服务器)有较多开销,这是由于支持一致的哈希时需要更复杂的内部结构。
连接默认的服务器(127.0.0.1)和端口(6379)
$redis = new Predis\Client();
redis = new Predis\Client(array(
'host' => '10.0.0.1',
'port' => 6380,
));
或者
$redis = new Predis\Client('redis://10.0.0.1:6380/');
$redis = new Predis\Client(array(
array('host' => '10.0.0.1'),
array('host' => '10.0.0.2'),
));
或者
$redis = new Predis\Client(array(
'redis://10.0.0.1/',
'redis://10.0.0.1/',
));
或者
$redis = Predis\Client::create(
array('host' => '10.0.0.1'),
array('host' => '10.0.0.2')
);
或者
$redis = Predis\Client::create(
'redis://10.0.0.1/',
'redis://10.0.0.1/'
);
$redis = new Predis\Client(array(
'host' => '10.0.0.1',
'password' => 'secret',
'database' => 10,
));
或者
$redis = new Predis\Client('redis://10.0.0.1/?password=secret&database=10');
支持的连接参数
参数 |
描述 |
默认值 |
__host__ |
服务器的 IP 地址或主机名称 |
127.0.0.1 |
__port__ |
服务器监听的 TCP 端口 |
6379 |
__password__ |
服务器用于身份验证的密码 |
no不使用密码 |
__database__ |
连接后,选择的数据库索引 |
为设定索引,使用默认的 Redis 数据库 |
__timeout__ |
连接服务器的超时时间 |
5 秒 |
__read_write_timeout__ |
在网络 socket 上读写操作的超时时间 |
系统默认 (NOTE: 使用 -1 禁用读写超时) |
发送指令
使用 Predis 向 Redis 发送请求真的相当简单,但是处理指令的方式不止一种:
$redis->set('library', 'predis');
$retval = $redis->get('library');
// Client::createCommand uses the current server profile
// to create and return a new command instance
$cmdSet = $redis->createCommand('set');
$cmdSet->setArgumentsArray(array('library', 'predis'));
$cmdSetReply = $redis->executeCommand($cmdSet);
$cmdGet = $redis->createCommand('get');
$cmdGet->setArgumentsArray(array('library'));
$cmdGetReply = $redis->executeCommand($cmdGet);
- 最长的方式(and partially discouraged)
$cmdSet = new Predis\Commands\Set();
$cmdSet->setArgumentsArray(array('library', 'predis'));
$cmdSetReply = $redis->executeCommand($cmdSet);
$cmdGet = new Predis\Commands\Get();
$cmdGet->setArgumentsArray(array('library'));
$cmdGetReply = $redis->executeCommand($cmdGet);
另外还有各种各样的方式,在处理指令实例时去设置指令的参数:
$cmdSet = $redis->createCommand('set', array('library', 'predis'));
$cmdSet = $redis->createCommand('set');
$cmdSet->setArgumentsArray(array('library', 'predis'));
$cmdSet = $redis->createCommand('set');
$cmdSet->setArguments('library', 'predis');
如果你想要发送的指令在 Predis 中没有定义,该怎么办?
$reply = $redis->rawCommand("NEWCMD $key $param1 $param2");
PredisCommand, PredisInlineCommand, PredisBulkCommand and PredisMultiBulkCommand.
class BrandNewRedisCommand extends \Predis\InlineCommand {
public function getCommandId() { return 'NEWCMD'; }
}
$redis->getProfile()->registerCommand('BrandNewRedisCommand', 'newcmd');
$reply = $redis->newcmd($key, $param1, $param2);
Server profiles
Predis introduced the concept of server profiles to allow developers to specify, in a programmatic way, which Redis version they are going to connect to. This means that you can know beforehand which commands or features are supported by the selected Redis version and allows us to handle eventual behavioral differences in certain commands. As of today there are three predefined profile classes: PredisRedisServer_v1_0 (Redis v1.0), PredisRedisServer_v1_2 (Redis v1.2) and PredisRedisServer_vNext (the development version of Redis). When you create an instance of PredisClient, the default server profile being used is the latest stable version of Redis available at release time, but you can always force Predis to use a different profile:
- Set a different server profile when instanciating a new PredisClient instance
$profile1_0 = new Predis\RedisServer_v1_0();
printf("MSET SUPPORTED: %s\n", $profile1_0->supportsCommand('mset') ? 'YES' : 'NO');
$profile1_2 = new Predis\RedisServer_v1_2();
printf("MSET SUPPORTED: %s\n", $profile1_2->supportsCommand('mset') ? 'YES' : 'NO');
$redis = new Predis\Client('redis://127.0.0.1/', $profile1_2);
- Get an instance of the default server profile supported by the current version of Predis
$defaultProfile = Predis\RedisServerProfile::getDefault();
echo get_class($defaultProfile); // OUTPUT: Predis\RedisServer_v1_2
- Get an instance of a server profile supported by Predis by using a version string
$profile = Predis\RedisServerProfile::get('1.2');
echo get_class($profile); // OUTPUT: Predis\RedisServer_v1_2
$profile = Predis\RedisServerProfile::get('dev');
echo get_class($profile); // OUTPUT: Predis\RedisServer_vNext
h2. Pipelining
Pipelining can help with performances when you need to issue a whole set of commands to Redis. This is done by recording the commands issued to the client without actually sending them to the server, playing them all at once over the wire when flushing the pipeline (send the commands) and then listening to what the server has to tell us (read the responses).
- Initialize a pipeline inside of a block of code using an anonymous function (PHP 5.3 only)
$replies = $redis->pipeline(function($pipe) {
$pipe->ping();
$pipe->flushdb();
$pipe->incrby('counter', 10);
$pipe->exists('counter');
$pipe->mget('does_not_exist', 'counter');
});
- Initialize a pipeline and return an instance to play with (this also works with PHP 5.2)
$pipe = $redis->pipeline();
$pipe->ping();
$pipe->flushdb();
$pipe->incrby('counter', 10);
$pipe->exists('counter');
$pipe->mget('does_not_exist', 'counter');
$replies = $pipe->execute();
h2. Client-side sharding
The key-value model allows you to easily distribute your data across several servers and this is usually achieved by hashing the keys against a list of servers to select which one will be used to store their respective values. The same data-partitioning strategy can be used with Redis using a client library capable of handling connections to more than one server, but this is not enough to guarantee a consistent distribution and accessibility of your data as time passes. Predis supports "consistent hashing":http://en.wikipedia.org/wiki/Consistent_hashing when storing your list of servers, so that adding or removing a server does not affect the pre-existing distribution and availability of data on the others. Key tags are another interesting feature that allows you to decide which portion of a key should be hashed against the server list so you can redirect a subset of keys to the same instance. E.g., instead of using plain keys like "uid:1000:username" and "uid:1000:password" that will almost surely produce a different hash (and thus, sent on different servers) you can go with "{uid:1000}:username" and __"{uid:1000}:password"__, where the curly brackets define which part of the key will be hashed. Everything is handled transparently, even when using pipelines.
- Initialize a clustered client and set/retrieve key-values using key tags
$redis = Predis\Client::create(
'redis://10.0.0.1/',
'redis://10.0.0.2/'
);
$redis->set('{uid:1000}:username', 'nrk');
$redis->set('{uid:1000}:password', md5('mystrongpassword'));
$username = $redis->get('{uid:1000}:username'); // nrk
$password = $redis->get('{uid:1000}:password'); // c924729b0e04eb0d21908a7454c0218a