Redis 2.2.0 RC1 is out
antirez.com
antirez.com
* Sorted sets are now less memory hungry.
* Now write operations work against keys with an EXPIRE set! Imagine the possibilities.
I use Redis for many, many things. In fact, I realized the other day that without it, I probably wouldn't still be bootstrapping. Not because I couldn't use something else, but because I wouldn't enjoy the work nearly as much. Starting a company is a long, arduous road and finding joy in the work is really important.
v1:limiter:UNIQUEID:TYPE:HHMM
where UNIQUEID is a username or IP address, etc, TYPE is the specific action to limit (login, signup, etc), and HHMM is a quantized timestamp (e.g. 1205, 1210). You increment this key every time the action occurs and use an expire to keep it clean. It's not perfect, but it does the trick for most usecases.I also make pretty judicious use of databases to group different classes of data together. Primarily into 3 groups actually: transient data, persistent/customer data, and internal stuff like the error logs and job queues. That way I can dump data at different intervals for each group (I use a tool I wrote called redis-dump: https://github.com/delano/redis-dump).
Thanks again for the data point!
For instance GETBIT/SETBIT will turn strings into a large bitmap. While GETRANGE/SETRANGE makes users able to use strings as arrays for fixed length data.
I think there will be big use cases for this new commands, as it is possible to store a lot of data in little space, with O(1) random access.
Nice work, Salvatore. Seriously.
A lot of the other things could probably be done with the right combination of stored procedures and clever SQL but again, redis makes it so much easier as to make things qualitatively different. It's just a bunch of C files with no real external dependencies (I don't even have to run ./configure before building it!).
Operationally, for a generic non-db-expert kind of person like me, redis is much simpler to manage than PostgreSQL. With redis I don't need to worry about vacuuming, write ahead logs, archiving, query tuning & statistics, lock management, etc (to name a few things from the config file).
This isn't about PostgreSQL at all. There's things where relational databases are a good fit, and things that are a bad fit. As such, this isn't about what PostgreSQL does poorly, but about the cases where a key-value store with some pretty good data structures comes in handy. Would you really store temporary data in your relational database? Would you use it as a caching mechanism? Perhaps as a queue? Not unless you're crazy. So I guess this isn't about what PostgreSQL performs poorly, but about where Redis is a better solution.
You have items that you want to retrieve (LRANGE) in the same order, or in reverse order you push inside (LPUSH / RPUSH). Usually you need the latest items (think to timelines), and all this should be FAST and efficient.
In Redis this is trival to model. SQL is so far from modeling this in the right way that you need an "ORDER BY" statement for all your LRANGE-alike query even if there is nothing to order, you want to retrieve things in their natural insertion order.
Sorted sets can model a zillion of use cases in the same way. They are ordered per score on insertion. You can ask for ranges, for the RANK of an element, and things like this, in a matter of microseconds per queries. Completely impossible to model with SQL in a natural and fast way.
Just to cite another one (but there are tens of cases like this), bloom filters anyone? With Redis 2.2 you can manipulate a unique bitfield at the lower level, and even accessing to the sub bytes if you wish, with very efficient operations.
One usecase I can't figure out, is storing/querying IP address ranges. Is there a natural way with Redis to check if a number is within a given range? (without storing every value and without multiple calls)
The only way I can think to do this is to store the range as two integers, as you suggest, and query twice. The first to find the nearest lower bound for an IP and then a second time for the upper bound.
I especially like the simple protocol. It's possible to write a simple client without any external libraries within days --maybe hours if you're really good ;). Try to do that with SQL or MongoDB (Javascript parser anyone?).
redis is a nice memcached or scalable data structures replacement. we use it as a simple rabbitmq replacement.
We eventually abandoned it when we realized our queueing needs could be modeled in Redis. In a way that we fully control, understand and can debug. And it wasn't even much work!
I'd argue this is highly preferable unless your project really needs complex routing of the kind that only AMQP can provide. Most projects don't.
The newer pub/sub stuff promises to be very useful, too, but we didn't have a use-case for that, yet. Our app generally needs messages to persist until they are consumed.
What I can say however is that none of the concerns we initially had about performance/scalability held any water.
We are still running on a single redis instance (plus a slave) on a moderately sized server and it happily processes 100 messages/sec average between 4 producers and a varying number of consumers (20-100).
To add insult to injury our monitoring metrics show that this isn't even a worthwhile load for redis. The server is nowhere near breaking a sweat, the CPUs barely drop below 90% idle, there's no disk i/o to speak of, and the memory usage is more than reasonable (plenty headroom for our purposes).
Thus "just throw it at redis" has long become a common stopgap meme in this particular project. And so far we didn't have to replace any of these supposed stopgaps with something else.
Could you be so kind to qualify what load are we talking about, as producers/consumers & message rate/size/persistence level?
I have used ActiveMQ with systems of about ten nodes and a message rate of <2k/sec and it worked fine, and I always believed rabbitmq was faster/more stable (erlang bias!) so if your volume is 500k/s I'm ok, otherwise I'd file this as another slightly worrying information about rabbitmq (after the problems I heard from reddit)
Unwise, maybe. But thanks to the ease of doing this upgrade on several nodes with Puppet I couldn't help myself.
"oops, just found a bug on RC1 (setbit/getbit) I guess it's going to be RC2 soon ;)"
"Nevermind, no bug about RC1, just my mistake".
Twitter to HN gateway. :-)
This operations are useful every time you want to use Redis for caching timelines, as the idea is: if this user is already in cache (at least a single item exists) then push against the cache, otherwise not.
Twitter's Redis-backed timeline storage is here, if anyone is interested: https://github.com/twitter/haplocheirus