Zookeeper

2 posts

datadog3 min readCurated summary

When failover isn’t safe: Building high-availability PostgreSQL on Kubernetes

Datadog’s gameday testing exposed a PostgreSQL failure mode in which network latency caused replication lag to grow until no standby could be safely promoted. Although the clusters remained writable, they could not fail over without risking data loss, forcing operators to wait for connectivity and replicas to recover. Datadog’s solution was to redesign failover candidates around synchronous replication coordinated by Patroni, balancing stronger durability with acceptable write latency. ## The Zonal Failure That Exposed the Weakness - A simulated availability-zone failure introduced network latency in a staging environment. - Several Kubernetes-based PostgreSQL clusters had primary nodes in the affected zone. - Communication between primaries and replicas degraded, causing: - Rapidly increasing replication lag - Stalled writes - Applications serving stale data - No replica being current enough for safe promotion - The clusters prioritized continued writes over durability, leaving them writable but unable to fail over safely. ## Baseline PostgreSQL Architecture - Each cluster uses a single-writer design: - One active leader handles writes. - Two standby nodes are reserved for failover and do not serve application traffic. - A separate read-replica pool handles read-only traffic and scales independently. - Read replicas are intentionally excluded from failover candidates. - Patroni manages replication, leader elections, and failover. - ZooKeeper acts as Patroni’s distributed configuration store, tracking: - The current leader lock - Cluster configuration - Member replication state and latest LSN - ZooKeeper’s ephemeral leader key ensures that only one node can become primary. - During partitions, Patroni favors safety by pausing or demoting nodes that cannot verify cluster state. ## Why Failover Was Not Safe - Patroni checks replication lag before promoting a standby using `maximum_lag_on_failover`. - During the gameday, all eligible standbys exceeded that threshold. - Patroni correctly rejected promotion because each candidate could have been missing committed transactions. - The cluster therefore had no safe writable primary, even though the original leader was impaired. - The failure was a consequence of asynchronous replication and network latency, not a failure in Patroni’s safety mechanisms. ## Asynchronous Versus Synchronous Replication - **Asynchronous replication**, used originally: - Lets the leader commit and respond without waiting for replicas. - Provides low write latency and high throughput. - Can lose transactions committed on the leader but not yet copied to a standby. - **Synchronous replication**: - Requires the leader to receive acknowledgment from at least one replica before confirming a transaction. - Reduces the chance that a failover candidate is significantly behind. - Provides stronger durability, but may increase write latency when replicas experience network or availability problems. ## The Redesigned Approach - Datadog reworked its PostgreSQL deployment so failover candidates use synchronous replication. - Patroni coordinates these replicas and continues to enforce safe leader election. - The design aims to make failover both automatic and safe while limiting performance impact. - Benchmarking and failure testing were used to evaluate the trade-off between durability and latency. Datadog’s experience demonstrates that asynchronous replication can leave a system operational but unable to fail over during network disruption. For clusters where data durability and automatic recovery are critical, synchronous replication for designated failover candidates offers a safer architecture, provided its latency and availability costs are measured carefully.

Read original(opens in new tab)
datadog3 min readCurated summary

Introducing Kafka-Kit: Tools for scaling Kafka

Datadog operates Kafka at extreme scale, ingesting trillions of data points daily and requiring petabytes of NVMe storage. To manage frequent data movement caused by scaling, recovery, and capacity changes, the company built Kafka-Kit, a set of operational tools that improve partition placement and replication control. Its primary tools, `topicmappr` and `autothrottle`, automate safer and more predictable Kafka operations. ## Kafka-Kit - Kafka-Kit addresses two major operational areas: - Data placement across brokers - Replication auto-throttling - Its main tools are: - `topicmappr`, for generating partition-to-broker mappings - `autothrottle`, for automatically controlling replication bandwidth ## Partition Placement with `topicmappr` `topicmappr` replaces Kafka’s `kafka-reassign-partitions.sh --generate` functionality while adding operational safeguards and placement controls. - Produces deterministic output: identical inputs generate the same partition map. - Supports minimal-movement broker replacement: - Failed brokers can be replaced without unnecessarily moving healthy partitions. - Partitions with complete in-sync replicas are normally left untouched. - Provides rack-aware placement using Kafka’s `broker.rack` metadata and ZooKeeper. - Supports placement based on: - Partition count - Storage size, enabling bin-packing and storage rebalancing - Allows replication factors to be increased or decreased while topics are running. - Generates clear summaries of: - Brokers being removed or added - Partition-level changes - Broker distribution before and after reassignment - Warnings and resulting partition-map files The tool is written in Go and can run from any system with access to Kafka’s ZooKeeper cluster. It requires topic names and broker IDs, then verifies that the brokers are live, sufficiently numerous, and properly distributed across configured localities. ## Replacing Failed Brokers For a failed broker, `topicmappr` can rebuild affected topics while limiting movement to the necessary partitions. - Existing replicas are preserved whenever possible. - Replacement brokers fill the gaps left by failed brokers. - The generated report makes the proposed changes visible before execution. - The example replaces broker `1002` with brokers `1003` and `1004`, showing the updated replica assignments and broker totals. ## Placement Strategies `topicmappr` offers multiple strategies for deciding where replicas should live, including `count` and tunable `storage` placement. ### Count Placement Strategy - The default strategy. - Balances leadership and the number of partitions held by each broker. - Works well when traffic is expected to be distributed evenly across partitions. - Does not require metrics data, allowing maps to be generated quickly. - Also attempts to maximize the number of distinct broker-to-broker replica relationships. - This avoids concentrating a broker’s partitions with the same small subset of peers, improving distribution across the cluster and its racks. ## Storage-Aware Placement - The storage strategy uses partition size when assigning replicas. - It supports storage bin-packing and rebalancing, which is important when brokers have uneven disk utilization. - This is particularly useful for Datadog’s large Kafka clusters, where storage capacity—not just partition count—can determine when data must be moved. Datadog’s approach demonstrates that Kafka’s flexible primitives can be extended with purpose-built tooling. For large deployments, deterministic assignments, rack awareness, minimal movement, and storage-based balancing can make scaling and failure recovery substantially safer and more predictable.

Read original(opens in new tab)