A request needs forty values from a volatile tier one zone away — how does a pipelined run differ from one operation taking all forty keys?
answer
- two ways to collapse trips
- independent operations versus one operation
- forty replies in order, or one
- keys on one node, or split per node
basics
~20 sBoth collapse forty round trips into one, and that is all they share. A pipelined run stays forty independent operations with forty replies matched in order; one operation taking many keys is a single operation with a single reply and a single outcome.
solid answer
~50 sBoth forms buy the same thing — the caller stops paying one round-trip time per value — but they are different mechanisms. A **pipelined run** means sending a run of operations without waiting for each reply: the caller writes all forty operations onto the connection, then reads replies. The server still executes forty operations and produces forty replies, which come back in order, so the client library pairs each reply with its operation and a failure shows up in its own reply slot. **One operation taking many keys** is a single operation: one reply, one outcome, and the server must be able to serve every key it names — on a partitioned tier that normally means every key on one node, while a partition-aware client library can split a run per node. Stores differ in which multi-key operations they offer at all, and neither form provides atomicity.
code
pseudocode · 11 lines// one trip per value: 40 round trips
for k in keys: // 40 iterations
v = read(k) // send, then wait for the reply
// one operation naming many keys: 1 trip, 1 reply
values = readMany(keys) // one outcome for the whole call
// a pipelined run: 1 trip, 40 replies
for k in keys:
send(read(k)) // nothing is read back yet
replies = readReplies(40) // matched to the sends, in ordergo deeper
Know that a call to this tier is microseconds of server work plus one network trip, and that fetching forty values one at a time pays that trip forty times. Knowing there are ways to collapse those trips is enough at this level.
Explain both mechanisms and keep them apart: a run of operations sent without waiting for replies stays many operations with many replies, while one operation naming many keys has one reply and one outcome. Do the trip arithmetic out loud.
Choose between them for a stated topology. Say what changes on a partitioned tier, where a run can be split per node and a single many-key operation cannot, and refuse to assume a many-key read is a snapshot without knowing the execution model.
Set the rule for the estate. Portable guidance cannot assume a many-key operation exists, so the default collapse is the run; the many-key form is an optimisation available where the store and the key placement both allow it.
## The two costs inside one call A call to an in-memory store is two costs added together: **the server's service time** — what the store spends executing the operation, usually tens of microseconds — and one **round-trip time** on the network. Put the tier a cross-zone hop away, give the path a round-trip time of 0.5 ms and the store 20 microseconds per operation, and the arithmetic decides the design: - Forty values fetched one at a time cost 40 x 0.5 ms = **20 ms** of the caller's wall time (what the caller measures end to end), of which the store's own work is 40 x 20 microseconds = 0.8 ms. - The same forty values with the trips collapsed cost roughly 0.5 ms + 0.8 ms = **1.3 ms**. Almost the whole first bill is network, so neither a faster store nor a larger one touches it. There are exactly two mechanisms that collapse those trips, and they are not two names for one thing. ## A pipelined run A **pipelined run** is sending a run of operations without waiting for each reply. The caller writes operation 1, 2, 3 ... 40 onto the connection and only then begins reading replies. - The operations remain **forty independent operations**. The server executes forty of them and produces forty replies. - Protocols in this class answer in the order they were asked, which is how the client library pairs reply 17 with operation 17. - Each operation reports its own outcome, so one failure appears as an error in one reply slot and the rest are unaffected. - The operations need not be related: mixed reads and writes, different keys, different value shapes. - Every reply not yet read is held in **the reply buffer at each end**, so the run's size is bounded by memory rather than by the protocol. ## One operation taking many keys A **multi-key read** or **multi-key write** is one operation that names many keys. The caller sends one request and reads one reply. - It is **one operation** from the server's point of view, with one outcome and one error if anything is wrong with it. - Keys that hold nothing are reported inside that single reply, normally as an empty position, so the caller learns which positions came back with nothing rather than getting per-operation errors. - Whether it reads all keys at one instant depends on the store: a store that executes one operation at a time necessarily does, while a store that serves requests from a thread pool may take the keys one at a time under per-entry locking. Do not assume a snapshot. - Stores in this class differ in which of these they offer: some provide a multi-key read but no multi-key write, some provide neither and answer only single-key reads and writes. Where they are absent, a pipelined run is the only collapse available — which is why portable guidance leans on the run. ## Side by side | Question | Pipelined run | One operation taking many keys | |---|---|---| | Operations the server executes | one per item in the run | one | | Replies the caller reads | one per operation, matched in order | one, with a position per key | | Mixed reads, writes, value shapes | yes | no, one kind of operation | | A single failure | visible in its own reply slot | fails the whole operation | | Other callers' operations between yours | nothing prevents them | not applicable, it is one operation | | On a partitioned tier | a partition-aware client library can split it per node | needs the keys on one node, or a proxy that scatters and gathers | ## What neither of them buys 1. **No all-or-nothing outcome.** Whatever succeeded stays applied. Nothing is rolled back in either form when part of the work fails. 2. **No isolation.** Collapsing trips is a network optimisation. It does not reserve the keyspace, and it is not a group of steps run with no other caller interleaving, not a check-and-set retry, and not a server-side program — those are separate mechanisms with separate purposes. 3. **No protection from size.** Forty small values is one bill; forty whole-collection reads in one run is another, and the replies have to fit in memory at both ends. The usable rule: reach for one operation taking many keys when the work is homogeneous, the keys are servable together and you want one simple reply; reach for a pipelined run when the work is heterogeneous, when you need per-operation outcomes, when the tier is partitioned, or when the store offers no many-key operation for what you are doing.
- Why does a run of operations give better error reporting than one operation naming many keys?Because the run stays many operations. The server answers each one separately, so a failure — a bad argument, an operation applied to the wrong value shape — is reported in that operation's own reply while the others' effects remain. One operation naming many keys has a single outcome: it either serves the request or fails it, and you cannot tell from the reply which key caused the failure.
- The tier is partitioned and forty keys land on four nodes. Which form still works?The pipelined run: a client library that knows the key-to-node assignment can group the forty operations into four sub-runs and send them to the four nodes, often in parallel. One operation naming all forty keys is a single operation and cannot be served by one node that holds only some of them — deployments either refuse it or put a proxy in front that scatters and gathers on the caller's behalf.
- If a run costs one round-trip time, why not put every operation of the request in one run?Because the replies have to be held somewhere. Everything the server has produced and the caller has not read sits in the reply buffer at each end, so a run's size is bounded by memory, not by the protocol. A run also delays every outcome until the run is drained, so a single connection failure loses the whole run's results at once.
Forty letters each posted only after the previous answer arrives is the loop. One envelope holding forty questions is the many-key operation: one envelope back. Forty letters dropped in the box at once is the pipelined run: forty answers, arriving in the order you posted them.
saying these in an interview costs you the question
- Treats a run of operations and one many-key operation as interchangeable
- Believes the replies of a run can come back out of order
- Assumes every store in this class offers an operation taking many keys
- Says one operation naming many keys works across partitions like any other
- Claims a many-key read is a snapshot on every store
- Thinks either form makes the collapsed work all-or-nothing