Clarifications about Redis and Memcached
antirez.com
antirez.com
I'm sure there are extreme cases where Memcached is in fact the better tool for the job over Redis for caching workloads. I also expect that 99%+ of people trying to decide between Redis and Memcached will never get into that territory. Redis is so fast that unless you're doing O(n) operations on very large data sets, you're unlikely to notice any substantial differences.
The other thing about caching is that the data is, by its nature, disposable and rebuildable. So even in the extreme minority case where Redis would no longer be sufficient, migration from one KV cache system to another is about as easy as it gets. Pre-optimizing your caching layer stack for Facebook levels of traffic isn't even justifiable from a lock-in standpoint like it might be with other data storage needs.
In the case of your average Sidekiq user, serving cache fragments for a Rails app, memcached vs redis for your caching layer is almost certainly an inconsequential choice WRT the performance of your application, and the choice of Redis reduces your ops and client library overhead. The choice should be pretty clear in those circumstances.
What I really like about both pieces of software is that they are dead simple to set up. If I were to make a decision today for new projects who are just starting to scale I'd probably take a good hard look at redis and see if you don't need any of the extra features. I could see a lot of projects eventually needing those features and leveraging redis. I really like the pub/sub feature in particular. Persistence is always nice if you don't have to pay too much for it.
Does anyone know if amazon has a redis/memcache service? I can never remember what they name things.
I really needed some kind of a parallelism and so I hacked together http://thredis.org/ (and then mostly for fun added SQL operations to it by linking it with SQLite).
Since then I've kind of abandoned this project and moved on to other things, but I still think that there is a valid case for some form parallelism in Redis. I had learned some tough lessons while hacking on Thredis such as importance of ordering locks, having retry strategies, and there are still bugs that can cause it to crash AFAIK, but the take away was that it's doable - I was a newbie at it, today I'd probably do a much better job. In my (not so scientific) testing Thredis was only slightly slower than Redis.
It is possible to remove lock contention on the read path [2] if a concurrent hash table is used. This can be done while using an O(1) eviction policy that outperforms LRU [3].
[1] https://github.com/memcached/memcached/pull/97 [2] https://github.com/ben-manes/caffeine/wiki/Design [3] https://github.com/ben-manes/caffeine/wiki/Efficiency
However, if data access is read-heavy and not equally distributed across keys, then having shared memory (aka multithreading) is quite essential since you want all cores to operate on the same data, and shared memory is much better than sending the data across especially if the heavily accessed keys vary quickly over time.
I'm not sure if memcached handles this well (it requires a lightweight rwlock/RCU/MVCC mechanism, for instance), but a shared-nothing system like Redis cannot provide good performance in all cases.
So, not knowing much about Redis, I would conclude based on this blog post that memcached has a pretty big advantage as a cache in real systems (multithreading).
However this is not true when you have a case with, like, 2/3 super hot keys that are requested a lot more than any other. But in this case what allows scalability is replication with many read-replicas.
Edit: Salvatore, you should also look at the Seastar/ScyllaDB design (if you haven't yet) - that architecture would work well for redis as well. And if user has access to DPDK (or other kernel bypass enabled NICs, like Solarflare), their performance will go up even further.
https://www.usenix.org/system/files/conference/osdi14/osdi14...
https://github.com/scylladb/seastar/wiki/Memcached-Benchmark
Many of the developers I work with are unfamiliar with Redis. Maybe they've heard of it and they install it to use Sidekiq and that's it. From the perspective of a newcomer, memcached is "safer" to run because it'll be memory limited automatically with literally zero config necessary. Redis does require the non-default LRU and memory tuning to be a safe cache.
It sounds like my performance concerns are primarily a thing of the past. Glad to hear it and I look forward to the threaded I/O coming after lazyfree.
EDIT: This started out a bit flippant. Wanted to make the point that antirez is not just handwaving.
For example one of the points without elaboration was 'there are “pure caching” use cases where persistence and replication are important'. Sometimes caching warming isn't feasible i.e. needing to restart the cache in the middle of a production workload. Using entirely volatile cache one can find extended downtime from the dog pile of requests waiting for the cache to warm up. Persistence can be an attractive form of insurance against this scenario.
Memcached text: 43585 OPS @ 4.58 msec
Memcached binary: 40242 OPS @ 4.96 msec
Redis: 39727 OPS @ 5.03 msec
Redis, pipeline 4: 131312 OPS @ 6.09 msec> Redis in its special case of memcached replacement, may be addressed executing multiple processes
This is always less optimal to a single process. Simpler is better.
> Redis is very very observable
This has a cost...trashing your phenomenal read and write performance. Running a concurrent redis, just for monitoring, is a hack that I have used to continue leveraging the observability.
NUMA lets you address non-local memory, but memcached and redis don't utilize libnuma so they don't know whether the memory is local or not. The entire system's memory is available as one contiguous blob, but some of it is a lot slower than the other (depending on which CPU core you're running on). To get around this, on most servers you'll need to run two processes (and two different ports) and bind them to appropriate CPU core sets and memory.
Caching web content can grow and grow until you run out of memory. If you aren't using Redis for data that can be easily regenerated, then go ahead and use Redis as a cache. But if you are, I think it will give you operational peace of mind to segregate where you store your background jobs and where you cache content.
https://github.com/seamusabshere/lock_and_cache
(and lock too, with Redis Redlock)
I guess that's not a problem anymore..?
I'm slowly working on my own memcached clone and plan to add persistence there eventually. Not so sure about replication, it might be too hard. In principle, after I'm done with getting a better version of memcached, both feature-wise and performance-wise, if time permits, I can also add the redis protocol support.
Therefore, it will be possible to have both in a single package and don't worry finding which one is better.
This is my project, if anyone is interested: https://github.com/ademakov/MainMemory
[Update: my statement was only about cache-related functionality, admittedly redis supports very interesting data structures, persistence, replication. But as just a very fast in-memory cache, there is nothing particularly advanced in either case. On the other hand there are projects like RAMCloud, Seastar that I find inspiring when I work on my own project.]