Once redis receives a piped file, will that redis instance block for all the commands as if it were one large transaction?
If not, can I wrap subsets of commands in the piped file in MULTI/EXECs?
The documentation on https://redis.io/topics/mass-insert isn't entirely clear.
Once redis receives a piped file, will that redis instance block for all the commands as if it were one large transaction?
Redis may interleave other operations between the pipelined ones.
If not, can I wrap subsets of commands in the piped file in MULTI/EXECs?
Definitely. Do that when you require "atomicity" of a block of operations.
The documentation on https://redis.io/topics/mass-insert isn't entirely clear.
True, but reading about pipelining and transactions provides the whole picture.
Related
Can XREAD (or perhaps another command) be used to atomically detect whether data was written to a Redis stream?
More specifically:
Suppose you added some data to a Redis stream in one process and saw that the data was added successfully with some auto generated key.
XADD somestream foo bar
After this XADD completes, you immediately run the following read in another process.
XREAD COUNT 1000 STREAMS somestream 0-0
Is this XREAD guaranteed to return data? The documentation is not clear about whether a successful XADD guarantees that readers will immediately see the added data, or whether there might be some small delay.
Redis's famous single threaded architecture answers that question. When you execute XADD on one process(client side) and after another process(client side) executes XREAD then the server execute them consecutively which guarantees that the data will be there before XREAD is executed.
The next quotes are from The Little Redis Book
Every Redis command is atomic, including the ones that do multiple things. Additionally, Redis has support for transactions when using multiple commands.
You might not know it, but Redis is actually single-threaded, which is how every command is guaranteed to be atomic.
While one command is executing, no other command will run. (We’ll briefly talk about scaling in a later chapter.) This
is particularly useful when you consider that some commands do multiple things.
One way to execute commands in REDIS, is via the EVAL script.
Redis uses the same Lua interpreter to run all the commands. Also
Redis guarantees that a script is executed in an atomic way: no other
script or Redis command will be executed while a script is being
executed.
Since redis is single threaded, why do we need EVAL to offer atomicity? I would expect that this is implied by the one running thread.
Am I missing something? Apologies if my question is pretty simple, I am quite new to redis
Every (data path) command in Redis is indeed atomic. EVAL allows you to compose an "atomic" command with a script that can include many Redis commands, not to mention control structures and some other utilities that are helpful to implement server-side logic. To achieve the similar "atomicity" of multiple commands you can also use MULTI/EXEC blocks (i.e. transactions) by the way.
Without an EVAL or a MULTI/EXEC block, your commands will run one after another, but other clients' commands may interleave between them. Using a script or transaction eliminates that.
Redis uses a single thread to execute commands from many different clients. So if you want a group of commands from one client to be executed in sequence, you need a way to direct Redis to do that. That's what EVAL is for. Without it, Redis could interleave the execution of commands from other clients in with yours.
As I know redis is single threaded solution from client point of view.
But what about the general architecture?
Amuse we have some lua script that going to execute several commands on keys that has some TTL.
How does redis garbage collections works? Could it interrupt the EVAL execution & evict some value or internal tasks share the single thread with user tasks?
Lua is majik, and because that is the case time stops when Redis is doing Lua. Put differently, expiration stops once you start running the script in the sense that time does not advance. However, if a key expired before the script started, it will not be available for the script to use.
When working with a single redis instance I can be sure that commands inside MULTI will be processed as a single atomic operation.
What happens when redis operates in cluster mode?
Can I be sure slaves won't get intermediate result of MULTI but only the whole/none of commands that were send as a MULTI(transaction)?
added: all commands inside MULTI operating on the same slot and keys are tagged with {tagName}
Thanks!
Redis' replication between master and slave(s) is designed to honor MULTI's assurances, so yeah, you can be sure. Put differently, the replication stream that the slave gets is a built out of the write operations that the master performs. These are sent in order, and since MULTI guarantees atomicity on the master, it follows that the same applies to the slaves.
We are using hiredis from our C++ application using the redisAsyncCommandArgv interface. What we are not able to figure out is how to execute a bunch of commands in a MULTI-EXEC transaction. The redisAsyncCommandArgv encodes only one command at a time. Can it be used to send all the commands in a transaction in one go? Synchronous API is straight forward but, they cannot be used.
Any help?
It is impossible to use MULTI-EXEC over Redis Asynchronous API. You can only choose one.
MULTI-EXEC transactions SHOULD always execute sequentially. Redis Asynchronous API, on the other hand, allows the commands to be delivered out of order. Hence, it won't make sense to make a MULTI-EXEC transaction if the commands aren't in the proper sequence or worse, if MULTI and EXEC commands themselves became out of order.