9 Exploiting concurrency

 

This chapter covers

  • Picking a concurrency model for your application
  • Reducing latency with data and task parallleism
  • Understanding transaction isolation level impact on concurrency
  • Building intuition on database concurrency control impact on latency

Building on our deep dive into synchronization in latency-sensitive applications from the previous chapter, we now focus on improving your application latency by exploiting concurrency more generally. While Chapter 8 demonstrated how wait-free synchronization could mitigate the tail latency impacts of mutual exclusion, which is necessary when you cannot partition your data (a topic discussed in Chapter 4), this chapter examines concurrent execution more broadly.

Fundamentally, concurrency is the ability of a system to execute multiple tasks at the same time, a critical capability for low-latency systems that must handle long-running operations or I/O-bound tasks without blocking. Rather than letting a single slow operation become a bottleneck, well-designed concurrent systems can maintain responsiveness by switching between multiple tasks. In other words, instead of allowing a long-running operation to dominate the CPU or waiting for an I/O task to complete, concurrent execution can reduce latency by letting other tasks run at the same time.

9.1 Concurrency and Parallelism

9.2 Concurrency Models

9.2.1 Threads

9.2.2 Fibers

9.2.3 Coroutines

9.2.4 Event-driven concurrency

9.2.5 Futures and promises

9.2.6 Actor model

9.3 Parallel Processing

9.3.1 Data parallelism

9.3.2 Task parallelism

9.4 Transactions

9.4.1 Serializability

9.4.2 Snapshot isolation

9.4.3 Data anomalies and weaker isolation

9.5 Concurrency control

9.5.1 Two-phase locking (2PL)

9.5.2 Multi-version concurrency control (MVCC)

9.6 Putting it together: Sequential vs concurrent execution

9.7 Summary