And it's far more likely you are continuously upgrading your process than Redis.
Ideally every significant part should live in its own universe, only interacting with other parts via well-defined interfaces. Sadly, it's either more expensive (even as Unix processes, to say nothing of Windows), slower (Erlang / Elixir), or both (microservices).
Or do you compare using separate processes to having multiple threads in a single process?
As far as isolation goes, if you are worried about the properties of reading and writing data to the disk then I simply don't know what to tell you. Isolation from what?
Perfomance-wise, I do not know of a nice portable way of flushing changes to disk securely that does not block (like, e.g. fsync does).
If you own the whole system and can tune whole kernel and userspace to run single application, sure, why overengineer. Otherwise software faults (bugs, crash due to memory overcommit, oom killer etc.) take down single process, and that can be less disruptive than full stop/start.
Not for Redis.
> I do not know of a nice portable way of flushing changes to disk securely that does not block (like, e.g. fsync does).
If you use Redis, you're either not waiting for writes to be acknowledged or you're waiting on fsync. You always fsync no matter whether it's in process or not or you're risking losing data.
Which process blocks doesn't affect performance, it's getting the data there in the first place.
> Otherwise software faults (bugs, crash due to memory overcommit, oom killer etc.) take down single process, and that can be less disruptive than full stop/start.
Even worse: Redis crashes and now your application (which hasn't crashed) can't read or write data, perhaps in the middle of ongoing operations. You have a whole new class of failure modes.
It does... and it's a blocking operation (Bad). It's used when storing data to a file to allow restarts w/o losing the said data.
I think a good rule of thumb is:
* If you need it from a single process and it doesn't need to survive process restarts, just use basic in-process data structures.
* If you need it from multiple processes or it needs to survive process restarts, but not system restarts, use redis.
* If it needs persistence across system restarts, use a real DB.
Redis helps you get to the point (need cache on separate machines) where you might want to consider moving to postgres, or not because you don't feel it warrants the investment of programmer hours at that point.
How could that very clear statement be misunderstood as to be well I am building a bunch of stuff I might need to tomorrow, it is the exact opposite of that!
I guess it's my fault, nobody on HN seems to understand a single thing I say even though the words seem reasonably clear to me.
But yeah redis is not an answer for most single machine questions.
What's the overhead of postgres vs redis, when run locally? Why do you think postgres isn't run locally?
There's nothing special about postgres. It's just a program that runs in another process, just like redis. For local connections, it uses fast pipes, to reduce latency, and you get access to some faster data bulk transfer methods. I've used it in this way on many occasions.
Except for temporary tables which are wiped after each session.
Postgres has a shared memory cache, which can be set the same as redis, so your operations will all happen with in memory, with some background stuff putting it onto disk for you in the case your computer shuts off. Storage won't be involved.
BUT, postgres still has ~6x the latency [1], even when run from memory.
[1] https://medium.com/redis-with-raphael-de-lio/can-postgres-re....
If you have to parse and plan queries every time PostgreSQL is obviously much slower than Redis. It is much more interesting to see what happens if prepared statements are used.
And having a locking system fluctuate in latency between milliseconds and seconds would cause all sorts of headaches.
> And having a locking system fluctuate in latency between milliseconds and seconds would cause all sorts of headaches.
With the frequency that a locking system is likely to be used, it’s highly unlikely that those pages would ever get purged from the buffer pool.
a) Writes will be happening on a slow, highly contentious disk.
b) You have no guarantees that the data will be in-memory.
Both of which make it a poor solution for use cases such as locking.
That's fine. If what you want is a single-node deployment combined with in-memory purism them SQLite has your back.
https://github.com/raphaeldelio/redis-postgres-cache-benchma...
A bit more work yes that could be simplified, but fully supported if you control the stack.
Highly recommended for running tests, especially in CI/CD pipelines. Doing this simple change can speed up DB-heavy tests 30-50%.
Is that relevant though? Some benchmarks on the web show Postgres outperforming Redis in reads as well as low-volume writes (less than 1k key-value pairs), and Redis only beating Postgres for high volume key-value writes.
I wonder what type of use cases have high volume writes.
Maybe queuing, locking and pub/sub ?
Why Postgres wouldn’t run on the same server as the app? It’s actually pretty common.
If you only have one long lived process or good global variable control, then it is much less appealing in the single-server scenario. Similarly, if you require access from multiple hosts, it becomes a less obvious choice (especially if you already have a database in the loop). And redis is also overkill is you’re using it only as a cache.
As in performance improvement - cache should never be considered a datastore, e.g. you can pull the plug and nothing else happens (aside losing performance). It'd be a lot more beneficial all the processes to have a local cache, themselves. The latter is at least 4 orders of magnitude faster than redis. Now you may like some partitioning, too.
Acting as shared memory for an inherently single-CPU language like JS is one I can think of. However, I don't use Redis, so you'd be better placed to drive the discussion forward with examples.
IPC, I suppose?
My Sidekiq background job system runs entirely on top of Redis. Structures like Sorted Sets become the basis for indexes. Lists provide extremely fast queue behavior and Hashes map easily to persistent objects. Databases, traditionally, have not performed well when used as queues.
Those are the big 3 structures necessary to implement anything: trees, lists and maps.
I do see the point of Redis if you have multiple hosts, but I was unsure why someone would use it on just one host.
That's perfectly fine. You can compare Redis to other specialized tools just like you can compare it with Postgres and SQLite.
Also, never realized redis has native support for a Bloom Filter.
That said, anitirez renaming it to lredis or reldis would be epic and one of my favorite moves of all time
I don't think this is a realistic scenario at all.
If you need a KV store, you want it to be the fastest by keeping it in-memory, you want it to run on each node, and you don't care how much it cost to scale vertically, then you do not run a separate process on the same node. You just keep a plain old dictionary data structure. You do not waste cycles deserializing and serializing queries.
You only adopt something like Redis when you need far more than that, namely you need to have more than one process access shared data. That's at the core of all Redis usecases.
https://redis.io/docs/latest/develop/interact/search-and-que...
After the significant success of the first conversion, we've been working to convert all the rest of our apps.
And no, host language data structures aren't useful because they aren't in shared memory between all the worker processes, and even if we found a module that implemented them in shared memory, we like to be able to preserve the sessions across a host restart, and then we'd need a process to save the data structures to disk and load them back, and by the time we did that we'd have just reinvented redis.
Also session data is often Blobs which db's don't process as efficiently as columnar data.
You might if you want the KV to persist between app restarts (for warm starts.)
I feel that the virtualize and distribute everything to hell and back-trend might actually be about to break, there are signs, and G knows it's about time. The amounts wasted on cloud providers for apps that would run everything just fine on a single server, the effort wasted configuring their offerings, surreal.
I want a “redis” with something akin to the Consul client - which is a sidecar that participates in the Raft cluster and keeps up to date, cheaper lookups for all of the processes running on the same box.
The few bit of data we needed to invalidate on infrequent writes went into consul, and the rest went into the dumbest (as in boring, not foolish) memcached cluster you can imagine.
But as you say there was the network overhead, and what would be lovely is a 2 tier KV store that cached recent reads locally and distributed cache invalidation over Raft. Consistent hashing for the systems of record, broadcast data on put or delete so the local cache stays coherent.
I wonder if something like Cockroach DB might even work for small clusters.
I have no idea how fast Redis can get, but it is entirely possible for an RDBMS to execute a query in well under a millisecond. I have instrumentation proving it. If everything is on the same machine, I would wager that IPC would ultimately be the bottleneck for both cases.
But for lots of cases, especially internal business tools, we can scale up a single instance for a long time, and this in-memory caching makes things super fast.
There’s a library, django-cachalot [1], that handles cache invalidation automatically any time a write happens to a table. That’s a rather blunt way to handle cache invalidation, but it’s wonderful because it will give you a boost for free with virtually no effort on your part, and if your internal business app has infrequent updates it basically runs entirely in RAM, and falls back to regular database queries if the data isn’t in the cache.
If all you want to do is queues and whatnot, then sure, you don't need an in-memory KV store.
The point of an in-memory KV store is to do stuff that needs the performance characteristics of RAM. You obviously can't get the performance characteristics of RAM over a network connection. This is like, a tautology.