You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@iggy.apache.org by kr...@apache.org on 2026/10/06 07:08:23 UTC

(iggy-website) branch main updated: fix(docs): correct the architecture page against server 0.9.0 (#128)

This is an automated email from the ASF dual-hosted git repository.

kparisa pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/iggy-website.git


The following commit(s) were added to refs/heads/main by this push:
     new 3975c83ca fix(docs): correct the architecture page against server 0.9.0 (#128)
3975c83ca is described below

commit 3975c83ca9f47c35dc6718031004ece14508c6b3
Author: Justin Mclean <jm...@apache.org>
AuthorDate: Tue Oct 6 18:08:17 2026 +1100

    fix(docs): correct the architecture page against server 0.9.0 (#128)
    
    Corrects the architecture page and its shard diagram.
    
    - TLS-wrapped TCP and WSS connections are handed to other shards as raw
    sockets before the handshake, like plaintext TCP. Only QUIC and HTTP
    stay on shard 0. The round-robin includes shard 0 by default.
    - A partition request goes into the owning shard's channel.
    - `cores=` in the NUMA mode is one count applied to every listed node.
    - Tokio's 512 is the maximum of a blocking pool that grows on demand.
    - 4096 is the io_uring submission queue size.
    - Storage: `state/log` is an empty file, a fresh partition has only
    `superblock.a`, `journal.wal` is checkpointed into `snapshot.bin`, and
    `current_config.toml` is rewritten at boot with the bound addresses and
    without secrets.
    - A sealed segment can exceed the segment size by up to one batch.
    - Removes "inspired by the Seastar framework", which the repo does not
    state.
    
    Verified against the `server-0.9.0` tag:
    `core/server/src/boot/listeners.rs`, `core/shard/src/coordinator.rs`,
    `core/shard/src/router.rs`, `core/cpu_allocation/src/lib.rs`,
    `core/server_common/src/executor.rs`,
    `core/server_common/src/bootstrap.rs`,
    `core/server/src/config_writer.rs`, `core/journal/src/superblock.rs`,
    `core/metadata/src/impls/metadata.rs`, `core/parVerified against the
    `server-0.9.0` tag: `core/server/soml`. The storage layout was also
    checked on a running `apache/iggy:0.9.0` container.
    
    Co-authored-by: Justin Mclean <ju...@apache.org>
    Co-authored-by: Kranti Parisa <kr...@laserdata.com>
---
 content/docs/introduction/architecture.mdx | 21 ++++++++++-----------
 src/components/architecture-diagrams.tsx   |  6 +++---
 2 files changed, 13 insertions(+), 14 deletions(-)

diff --git a/content/docs/introduction/architecture.mdx b/content/docs/introduction/architecture.mdx
index 5968a6189..1c444d3ae 100644
--- a/content/docs/introduction/architecture.mdx
+++ b/content/docs/introduction/architecture.mdx
@@ -13,7 +13,7 @@ Before diving into the architecture details, here's an overview of a message's j
 
 ## Thread per core (shared nothing) + io_uring
 
-Iggy uses a **thread-per-core shared nothing architecture** combined with `io_uring` for maximum performance. This design has been proven by systems like ScyllaDB and Redpanda, and is inspired by the Seastar framework.
+Iggy uses a **thread-per-core shared nothing architecture** combined with `io_uring` for maximum performance. This design has been proven by systems like ScyllaDB and Redpanda, both built on the Seastar framework.
 
 <ShardDiagram />
 
@@ -25,8 +25,8 @@ Each configured **shard** (an instance of `IggyShard`) has its own single-thread
 
 Shard 0 has a special role: it binds **every listener** - the replica plane and all client transports (TCP, QUIC, WebSocket, HTTP). Connections are then spread across shards at accept time:
 
-- **Plaintext TCP and WebSocket** connections are handed off round-robin to peer shards. Shard 0's coordinator duplicates the socket's file descriptor, ships a connection-setup frame to the target shard, and drops its own handle, so the owning shard serves the connection from then on - before a single byte is read.
-- **QUIC, TLS-wrapped TCP and secure WebSocket (WSS)** connections terminate on shard 0, because their per-connection state cannot be moved between shards. HTTP is also served on shard 0.
+- **TCP and WebSocket** connections, plaintext or TLS, are handed off round-robin across the shards. Shard 0's coordinator duplicates the socket's file descriptor, ships a connection-setup frame to the target shard, and drops its own handle, so the owning shard serves the connection from then on - before a single byte is read. For TLS-wrapped TCP and secure WebSocket (WSS), the target shard runs the TLS handshake. Shard 0 is part of the rotation by default; `skip_shard_zero_for_clients = [...]
+- **QUIC** connections stay on shard 0, installed through its UDP endpoint. HTTP is also served on shard 0.
 
 All shards, **including shard 0**, own partitions and serve partition requests.
 
@@ -35,7 +35,7 @@ All shards, **including shard 0**, own partitions and serve partition requests.
 Requests are routed between shards using **message passing** (via `crossfire` bounded mpsc channels), so partition state remains on its owning shard. The routing logic splits operations into two planes:
 
 - **Metadata operations** (create/delete stream/topic/user etc.) always execute on **shard 0** - it is the only shard that commits metadata
-- **Partition operations** (send_messages, poll_messages, store_consumer_offset) are routed to the shard owning that partition via a lock-free concurrent map lookup. A request that lands on a non-owning shard rides the inter-shard message bus to the owner
+- **Partition operations** (send_messages, poll_messages, store_consumer_offset) are routed to the shard owning that partition via a lock-free concurrent map lookup. The request is sent into the owning shard's channel, whichever shard received it
 
 Partition-to-shard assignment is **deterministic**: the packed `IggyNamespace` is hashed with `Murmur3`, and the upper 16 bits of the hash are taken modulo the shard count (the upper bits are used because Murmur3 has weak lower bits for small integer inputs).
 
@@ -53,18 +53,18 @@ The sharding system supports multiple allocation modes via the `cpu_allocation`
 - A numeric value (e.g. `4`) - exactly N shards, pinned to the first N CPUs in the process's allowed CPU set when pinning is enabled
 - A range (e.g. `"5..8"`) - shards on CPUs 5, 6 and 7 when pinning is enabled; those CPUs must be allowed for the process
 - `"numa:auto"` - automatically detect NUMA topology and select physical cores, avoiding sibling hyperthreads
-- `"numa:nodes=0,1;cores=4;no_ht=true"` - fine-grained NUMA control per node with hyperthread avoidance
+- `"numa:nodes=0,1;cores=4;no_ht=true"` - explicit NUMA nodes, with the same number of cores taken from each listed node and hyperthread avoidance
 
 ### io_uring and compio
 
-Traditional async runtimes like tokio use `epoll` which is **readiness-based** - you ask the kernel "is this file descriptor ready?" and then perform the I/O yourself. [Regular files cannot be registered with epoll](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html). Tokio runs file I/O on a blocking thread pool (512 threads by default, configurable). This does not scale well.
+Traditional async runtimes like tokio use `epoll` which is **readiness-based** - you ask the kernel "is this file descriptor ready?" and then perform the I/O yourself. [Regular files cannot be registered with epoll](https://man7.org/linux/man-pages/man2/epoll_ctl.2.html). Tokio runs file I/O on a blocking thread pool that grows on demand (up to 512 threads by default, configurable). This does not scale well.
 
 `io_uring` is **completion-based** - you submit I/O requests to a submission queue (SQ), and the kernel completes them and places results in a completion queue (CQ). Both queues are shared ring buffers between user space and kernel. Submissions and completions can be batched to reduce syscalls. This is fundamentally better for disk I/O.
 
 <IoUringComparison />
 
 Iggy uses **compio** as its async runtime, which provides a driver-disaggregated architecture on top of io_uring (Linux) and IOCP (Windows). Each shard gets its own compio executor configured with:
-- Capacity: 4096 concurrent I/O operations (by default)
+- Capacity: an io_uring submission queue of 4096 entries (by default)
 - Event interval: poll the I/O driver after 128 scheduler ticks (roughly task polls) by default
 - Cooperative task running enabled
 
@@ -99,7 +99,7 @@ local_data/
 ├── logs/
 │   └── iggy-server.log
 ├── state/
-│   └── log/
+│   └── log
 └── streams/
     └── 0/
         └── topics/
@@ -109,13 +109,12 @@ local_data/
                         ├── 00000000000000000000.index
                         ├── 00000000000000000000.log
                         ├── superblock.a
-                        ├── superblock.b
                         └── offsets/
                             ├── consumers/
                             └── groups/
 ```
 
-This example shows a fresh partition with the default paths. The stream, topic and partition directories are named after their numeric IDs, **assigned from 0**. The `metadata/journal.wal` file is the VSR write-ahead log that persists all metadata operations (stream/topic/user creation, etc.). The `runtime/current_config.toml` file captures the configuration the server actually booted with. Segment files are named by their 20-digit start offset. Recovery can create an empty active segment [...]
+This example shows a fresh partition with the default paths. The stream, topic and partition directories are named after their numeric IDs, **assigned from 0**. The `metadata/journal.wal` file is the VSR write-ahead log for metadata operations (stream/topic/user creation, etc.). Its index has 1024 slots by default (`journal_slots` under `[metadata]`). Before they run out, the server checkpoints the metadata into `metadata/snapshot.bin`, records the checkpoint in a superblock under `metad [...]
 
 ## Memory pool
 
@@ -129,6 +128,6 @@ Messages flow through a multi-stage write pipeline:
 2. Partition VSR replicates prepares. With `durability=persisted`, a multi-replica group requires recoverable prepare-WAL copies at the replication quorum before commit.
 3. Awaited writes apply committed operations before success is returned. A singleton with `durability=persisted` synchronizes local segment state before replying.
 4. Ordinary segment writes use per-topic count and byte thresholds (defaults: 1024 messages, 1 MiB); required persistence, capacity pressure, and lifecycle work can flush earlier. The `MessagesWriter` uses **vectored I/O** in chunks of up to 1024 buffers. Partial writes can require more than one I/O submission.
-5. When a segment reaches the topic's segment size (default 1 GiB), it is **sealed** and a new segment is created.
+5. When a segment reaches or passes the topic's segment size (default 1 GiB), it is **sealed** and a new segment is created. The batch that crosses the size is written whole, so a sealed segment can exceed it by up to one batch.
 
 Message `durability` and `consumer_offset_durability` default independently to `replicated`. Both policies write data to disk; `persisted` adds a stable-storage requirement at completion. See [Durability](/docs/server/durability).
diff --git a/src/components/architecture-diagrams.tsx b/src/components/architecture-diagrams.tsx
index 0e0bb7bac..f465a9410 100644
--- a/src/components/architecture-diagrams.tsx
+++ b/src/components/architecture-diagrams.tsx
@@ -126,21 +126,21 @@ export function ShardDiagram() {
       id: 0,
       label: "Shard 0 (Coordinator)",
       color: "var(--color-fd-primary)",
-      features: ["Binds all listeners: TCP, QUIC, HTTP, WS", "Replica plane listener", "Metadata plane (left-right write handle)", "QUIC + TCP-TLS + WSS + HTTP terminate here", "Hands plaintext TCP/WS to peers (fd transfer)"],
+      features: ["Binds all listeners: TCP, QUIC, HTTP, WS", "Replica plane listener", "Metadata plane (left-right write handle)", "QUIC + HTTP terminate here", "Hands TCP/WS, plaintext or TLS, to shards (fd transfer)"],
       partitions: ["P0", "P3", "P6"],
     },
     {
       id: 1,
       label: "Shard 1",
       color: "#3b82f6",
-      features: ["Metadata read handle (left-right)", "Plaintext TCP/WS via fd transfer", "Owns partitions"],
+      features: ["Metadata read handle (left-right)", "TCP/WS, plaintext or TLS, via fd transfer", "Owns partitions"],
       partitions: ["P1", "P4", "P7"],
     },
     {
       id: 2,
       label: "Shard 2",
       color: "#8b5cf6",
-      features: ["Metadata read handle (left-right)", "Plaintext TCP/WS via fd transfer", "Owns partitions"],
+      features: ["Metadata read handle (left-right)", "TCP/WS, plaintext or TLS, via fd transfer", "Owns partitions"],
       partitions: ["P2", "P5", "P8"],
     },
   ];