Hi,
quick preamble: I'm the developer of Predis.
> Hi There,
> I wonder how Predis compare to phpRedis, in the following aspects:
> 1) which one support command pipelining better?
I don't think there is much difference in terms of support since
command pipelining is actually based on a quite simple trick that does
not require anything special. The only real difference is in how this
feature is exposed to developers by the public API of each library,
but again it is not something relevant unless you need one or two
specific features of Predis that are related to client-side
clustering.
> 2) How about clustering support? Which one follows redis development faster?
With Predis, clustering is achieved via client-side sharding against
multiple Redis servers.
phpredis on the other hand does not support clustering and I think
their decision is to wait for Redis cluster (which IMHO is a
reasonable choice at this point), but I'm sure that Nicolas, one of
the authors of phpredis, can give you all the details about the future
directions on that matter.
As for the development speed, both libs are constantly updated to add
features and fix bugs and to add support for new commands and reflect
changes in Redis.
> 3) Which one performs better?
While Predis is implemented only in pure PHP, phpredis is a C
extension for PHP which makes it faster for obvious reasons,
especially on localhost connections. The speed and overhead of Predis
is more than acceptable for many scenarios, but it basically depends
on your requirements so you might want to do some ad-hoc tests first
to determine which one suits your application best.
> 4) And how about stability?
I'd say they both work fine in terms of stability.
> Finally, could anyone explain what exactly is pipelining? Is it same as
> multi/exec? Could anyone give me code examples of how pipelining works in
> phpRedis and Predis?
In Redis, pipelining commands means to send multiple requests to the
server without reading the replies to each one of them until the end,
thus saving useless network round-trips between the client and the
server (which speeds things up quite a bit in many cases). MULTI /
EXEC is a completely different beast as all the commands executed
between MULTI and EXEC are basically executed sequentially as a single
atomic operation (see the docs at
http://code.google.com/p/redis/wiki/MultiExecCommand for a more
detailed description). These two concepts are complementary and MULTI
/ EXEC "transactions" can be pipelined to a server instance.
As for the examples, they pretty much look alike in their basic forms:
/* predis */
$ret = $redis->pipeline()
->set('key1', 'val1')
->get('key1')
->set('key2', 'val2')
->get('key2')
->execute();
/* phpredis */
$ret = $redis->multi(Redis::PIPELINE)
->set('key1', 'val1')
->get('key1')
->set('key2', 'val2')
->get('key2')
->exec();
Anyway I really suggest you to take a look at the documentation and
the examples of both the libraries to get a more in-depth glimpse at
how they both support pipelining.
--
Daniele Alessandri
http://clorophilla.net/
http://twitter.com/JoL1hAHN
>> 4) And how about stability?
> I'd say they both work fine in terms of stability.
> Hi Daniele,
> Thanks for the explanations. I hope to get some comments from phpredis
> developer too :) Still have a few questions:
He is on this mailing list, so I guess he will eventually find the
time to give his contribution.
> While testing with predis at the stage when we evaluate redis vs. mongodb to
> be used in our project, I encountered serious problems with large value. I
> found some info in predis community that this is a problem of php's socket
> implementation? I don't know if there are any progress with php 5.3?
Yeah, Predis by default uses PHP's socket streams but with them
there's no way for developers to set in userland the TCP_NODELAY flag
on the underlying socket, which is very annoying and can lead to
extremely low throughput when transmitting large values that do not
fit in a single TCP packet.
I have implemented a workaround for this by creating a new connection
class that internally leverages socket resources provided by the PHP
socket extension. It can be used with the current development version
of Predis, see https://github.com/nrk/predis/blob/socket_extension/lib/addons/SocketBasedTcpConnection.php
BTW phpredis was affected by the same problem right until a couple of
months ago or so, but they were able to fix this issue in a simple and
clean way since PHP exposes to C extensions a way to get the
underlying raw socket out of socket streams, thus allowing the
TCP_NODELAY flag to be set.
> So pipelining is NOT multi/exec. But what if there are errors during the
> pipelining? You said "until the end", which I understand is:
Pretty much all the implementations of pipelining return an array of
replies, so server errors (as in -ERR replies sent back to the client
by Redis) are usually simply stored in that array together with
regular replies [*]. In the end, the only difference when operating
with pipelines is that you can't build and send commands based on the
reply from previous ones. The rest of the workflow is basically the
same.
> 1) pipelining is a client behavior which has nothing to do with redis server
> 2) redis server still send replies to client, but client just ignore it
> until the "batch" of commands finished. i.e. it send second command before
> receiving reply from first command and so on... In another word, it boost
> performance by sending commands faster, but it does not save any bandwidth
> consumption (or, is there a command to instruct redis server to NOT send any
> reply in "pipeline" mode???)
> Is that correct?
1) and 2) are both correct. There's currently no way to tell the
server to discard one or multiple replies for issued commands, but
this could be easily emulated client-side just by writing all the
requests to the server and disconnecting the client instance instead
of performing any read operation (while Redis simply discards the
replies buffer for the associated connection). This might seem a bit
hackish and needs further support by the client library, but it would
definitely work.
[*] by default Predis throws an exception as soon as a -ERR reply is
intercepted while reading replies from the server, this behaviour can
be overridden to return error objects by initializing the client with
the 'throw_on_error' option set to false:
$redis = new Predis\Client($server, array('throw_on_error' => false));
--
You received this message because you are subscribed to the Google Groups "Redis DB" group.
To post to this group, send email to redi...@googlegroups.com.
To unsubscribe from this group, send email to redis-db+u...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/redis-db?hl=en.
Most clients use the other method though, which is very similar to
just using multi/exec.
--
Derek
Clustering: I think the idea of waiting redis cluster to mature might be a wise option for now. What I do worry is: it seems that you cannot do operations on two keys if they spread over 2 machines, and that's why the "hash mark" (i.e. {...}) is designed in redis keys. I feel that could be a non-trivial problem in "porting" non-cluster-ready code to cluster-ready code.
Pipeline/Multi-Exec: from Daniele's explanation, I now have a fair understanding of the difference and purpose of the two. But I still have one question remain unclear: how about client side buffering? i.e. when doing://Predis version#1 $ret = $redis->pipeline()
#2 ->set('key1', 'val1')
#3 ->get('key1')
#4 ->set('key2', 'val2')
#5 ->get('key2')
#6 ->execute();
How is the underlying communication happening? i.e. ALL data is sent (as a \n separated list of strings) to server at the moment of execute(), or it happens throughout line#2~#6? I feel that if the client can "buffer" commands (as long as a pipeline or mult is requested) and send out commands in one go, performance would be best.
--
I agree that it is a primitive way of having set intersections work in a distributed redis setup and that if you can wait for redis cluster that will be better. but even then redis cluster itself is going to need to do something similar to this in the background in order to support intersection on the same shard or whatever they end up being called in redis-cluster speak.
Cheers-
-Ezra
Ezra Zygmuntowicz
ezmo...@gmail.com
Right now, only the tests and Salvatore's blog post explain how it works.
Sorting into a distributed environment with key tags:
http://antirez.com/post/Sorting-in-key-value-data-model.html
How to tag a key in Redis::Distributed (redis-rb):
https://github.com/ezmobius/redis-rb/blob/master/test/distributed_key_tags_test.rb#L26
How to define a custom tag format with a regular expression:
https://github.com/ezmobius/redis-rb/blob/master/test/distributed_key_tags_test.rb#L43
To set one thing clear though, function and method names are completely case-insensitive in PHP. Whichever library you use, calling HGETALL or hGetAll won't change a thing. Redis commands aren't case-sensitive either, for that matter.
> Although php functions/methods are case insensitive, you must use lowercase
> when using Predis... I just tested it. Am I doing anything wrong...
You are doing nothing wrong: Predis uses the __call metamethod to
catch method names that represent Redis commands, and names are
checked in a case-sensitive fashion.