
Learn how horizontal scaling expands beyond fixed cpu limits by exploring replication options, distribution mechanisms, connection pooling, queuing, partitioning, sharding, and multi-master approaches for high availability and scalable performance.
Explore Cassandra's availability and partition tolerance, its consistency trade-offs, and PostgreSQL scaling options within the context of relational databases and distributed systems.
Explore how transactions ensure consistency in banking operations, updating both balances or none, and prioritize data consistency over partial availability in high availability systems.
Explore how availability and partition tolerance shape a system, balancing data consistency with user experience as likes and pictures are tracked, given scale and the impossibility of meeting all requirements.
Explore PostgreSQL replication to boost performance and high availability by copying data from a master server to distant bases, using built-in options or middleware and relying on logs.
Learn how to distribute read traffic across PostgreSQL replicas with a load balancer, creating a replica read pool and using tools like EDU Proxy and DG poll tool.
Use queuing to smooth write traffic by delaying real-time persistence of rights within an acceptable timeframe. If traffic remains high, split the dataset to scale in parallel.
Partitioning splits a table into multiple tables, enabling queries to scan smaller tables and indexes without the application noticing. It keeps partitions in the same database, avoiding shard complexities.
Explore multi master replication where multiple nodes hold identical data and allow writes via bidirectional replication since PostgreSQL 9.4. Understand challenges like conflicting updates, sequences, upgrades, failover testing.
Learn to configure PostgreSQL for streaming and asynchronous replication by initializing a primary database cluster with initdb, creating data directories, system tables, and the default Postgres database.
Configure the primary for replication by editing postgresql.conf to enable remote access with listen_addresses, create a replication user with replication flag, update pg_hba.conf, and restart.
Understand PostgreSQL logical replication, with publisher and subscriber roles, enabling selective table replication, streaming decoded statements, and efficient migrations with less data transfer than physical replication.
Set up two PostgreSQL database clusters on the same machine to demonstrate logical replication. Configure the publisher and subscriber ports and enable logical level, then start both instances to test.
Perform a selective copy of data by creating a test database and table, using pg_dump to transfer the schema to a subscriber via port 5434.
Create a publication for table one, or specify multiple tables or all tables, and pair it with a subscription to enable replication.
Create a subscription to pull changes from publications, enable replication slots and initial snapshot, and verify replicated inserts, updates, deletes, and truncates on the subscriber.
Understand the limitations of logical replication in PostgreSQL: schema and sequences are not replicated, changes require manual syncing with PGD, and only regular and partition tables are supported.
Monitor PostgreSQL replication with the PDA starter application table to view key metrics, including lag between master and standby in seconds or milliseconds, and set alerts.
Use logical replication for flexibility; it doesn't require schemas, supports major versions, Windows to Linux replication, multiple subscriptions, selective operations, and incremental changes with triggers, boosting performance on slow networks.
Handle hundreds to thousands of concurrent connections in large applications by using a connection pooler such as PGE Bouncer to boost PostgreSQL performance beyond 350 transactions per second.
PGE bouncer acts as a proxy between the application and PostgreSQL, maintaining an array of open connections to quickly serve requests with a minimal memory footprint.
Build a PgBouncer setup to front a PostgreSQL test database, run a stress test, and note its 1-to-1 connections and the need for external load balancing for high availability.
Install PgBouncer using your OS package manager—yum on Red Hat or CentOS, apt-get on Ubuntu or Debian, or brew on macOS; or download and build from sources.
Install pgbouncer and copy the default config from the OS directory. Edit the file to configure backend servers, alias test_tb, authentication, and a dummy superuser.
Launch the PGA bouncer using the configuration file to start the system. Connect to the progress database on port 6432 using alias B and user progress, with log entries.
Boost performance by tuning the PGE bouncer: set mean_proposal_size, keep the default pool size per user per database at 20, cap the queue with max_client_connections, and keep nodes nearby.
Explore pool modes for PostgreSQL connections, including session, transaction, and statement modes, and learn how each affects connection lifecycle, concurrency, and application behavior.
The benchmark shows that PgBouncer dramatically increases throughput and lowers connection time for many short-lived connections, from 3.21 ms to 0.23 ms, using 20 clients and 1000 transactions.
Implement a load balancing solution for PostgreSQL replicas using Google Cloud, enabling horizontal scaling and improved high availability.
Balance load for grid connections to improve read availability and move toward high availability. Route read requests via the energy proxy to replicas, while writes connect to the primary.
Create a primary PostgreSQL instance with two read replicas on Google Cloud to boost read capacity, using private IPs in the same region and a least-privilege test user.
Create a Google Cloud engine instance to run HAProxy, install the load balancer, and configure the Cloud SDK and APIs to enable PostgreSQL high availability.
Partitioning can dramatically boost performance when done right. Identify partition keys from workflows and joins, and apply one of four methods to minimize scanned data.
Demonstrate range partitioning in PostgreSQL by splitting a customers table into age-based partitions, migrating with minimal downtime, and identifying each row’s partition via a system column.
Explore partitioning methods to optimize PostgreSQL performance, including range and list partitions, hash partitioning, and multilevel partitioning, with examples using sales dates, departments, regions, and product keys.
Explore strategies to handle growing write traffic by sharding data into logical partitions distributed across physical nodes, and employ functional partitioning to scale PostgreSQL databases efficiently.
Identify a partition key from the data model, such as user ID, and implement horizontal partitioning with data mapping table to route queries and maintain unique primary keys across shards.
Explore second level sharding with multiple partition keys, such as user ID and article ID, to view data efficiently from different angles and cross the boundaries between shards for comments.
Organizations must plan for a wide range of failure scenarios to achieve high availability and business continuity, ensuring the database remains available even when some parts fail.
Achieve high availability by replicating data to a standby replica, exploring log shipping, streaming, and logical replication at a high level, and choosing manual or automatic failover with failback considerations.
PostgreSQL uses warm standby or log shipping to archive changes and recover on standby servers. Hot standby reduces delay, while streaming and logical replication now cover most replication use cases.
Explore cascading replication in PostgreSQL, streaming changes from the primary to standbys. Compare topologies: primary-fed standbys, or one-secondary-per-standby, or a secondary feeding multiple targets for faster failover and balanced load.
Explore a high-availability example with one primary and one standby, where client connects to the primary for reads and writes; failover is manual via a trigger file or Paramount Command.
Implement high availability by using PostgreSQL built-in streaming replication to synchronize data, then use BGP for load balancing and automatic failover, with pgpool routing writes to the primary and reads to the replica.
Learn to configure PostgreSQL streaming replication to enable read load balancing, write separation, and failover by setting up a primary, creating a replica using base backup, and configuring replication access.
Configure Pgpool-II to balance load across a primary and standby in a streaming replication setup, directing inserts and deletes to the primary and selects to the standby.
PostgreSQL is one of the most powerful and easy-to-use database management systems. It has strong support from the community and is being actively developed with a new release every year.
PostgreSQL supports the most advanced features included in SQL standards. It also provides NoSQL capabilities and very rich data types and extensions. All of this makes PostgreSQL a very attractive solution in software systems.
In this course, we discussed the problem of building scalable solutions based on PostgreSQL utilizing the resources of several servers. There is a natural limitation for such systems—basically, there is always a compromise between performance, reliability, and consistency. It's possible to improve one aspect, but others will suffer. In this course, we'll see how to find the best match for our use-cases so that we know eactly which aspects need scaling, and avoid the common trade-offs of distributed systems.
Scaling PostgreSQL is a journey. You should come out of this course more prepared to assess your scaling needs and understand how to scale reads and how to scale writes.
Each of this solution presented in this course will improve some aspect of the scalability topic, but each of them will add some complexity, and maybe some limitation or constraint.
We have to ask the right questions to get the system requirements, and this why we dedicated an entire lecture, so that we examine what questions we have to put ourself, before starting the Scaling Journey.
After this course, we should come out more prepared and understand how to scale reads.
We have several options for replication, depending on wether we favor performance or flexibility.
Replication can be used as a backup or a standby solution that would take over in case the main server crashes.
Replication can also be used to improve the performance of a software system by making it possible to distribute the load on several database servers.
Then, if we have one sort of replication in place, we could ask ourself if we want to allow several computers to serve the same data.
To achieve this, we should have a mechanism to distribute the requests. We’ll see here two of the most popular options available.
Next, if the number of database connections is great, then we’ll probably want to use a connection pooler. Again, we’ll cover two options here.
We’ll also see, how to scale writes, and how to make your traffic growth more predictable by adding queuing to your architecture.
Then, we’ll check partitioning for those cases when we have to deal with big tables.
Also, we’ll check sharding to scale writes, and all the complex decisions that come with it.
Finally, we’ll see shortly the multi-master solution, which is a relatively new concept that seems to be promising.
If our goal is to achieve only High availability, or the ability to continue working even in the situation where one part of the cluster fails, we can check out only those solutions.
The pre-requirements for HA is to put in place a replication strategy.
Then, we can use tools to allow a second server to take over quickly, if the primary server fails.
Introduction to Scaling PostgreSQL
Why scale PostgreSQL?
What is Vertical Scaling?
What is Horizontal Scaling?
Read Versus Write Bound Workloads
Why Statistics are essential?
How to enable and make us of Statistics? (Hands-on)
How to scale Postgres for Reads?
How replication helps to scale out?
What are the Load-Balancers?
How to scale Postgres for Writes?
How to make use of Queues?
How could Partitioning and Sharding help in scaling out?
What is the Multi-Master solution about?
Understanding the Limitations of Scaling out PostgreSQL
CAP Theorem Explained
PostgreSQL vs. Cassandra
Use case: CA Systems
Use case: AP Systems
How to use Streaming Replication?
What is Streaming Replication?
Asynchronous vs. Synchronous Replication
How to Initialise Primary Database? (Hands-on)
How to Configuring the Primary for Replication? (Hands-on)
How to Configuring the Replica Instance? (Hands-on)
Testing Replication Setup (Hands-on)
How to use Logical Replication?
What is Logical Replication in Postgres?
Step by step Logical Replication setup
How to setup the servers for Logical Replication? (Hands-on)
How to make a selective Copy of the Data? (Hands-on)
How to Create the Publication? (Hands-on)
How to Create the Subscription? (Hands-on)
Postgres Limitations of Logical Replication
How to Monitoring Logical Replication? (Hands-on)
Best use-cases for using Logical Replication
How to make use of PgBouncer?
What is PgBouncer?
Fundamental concepts of connection pooling
How to build a PgBouncer Setup? (Hands-on)
How to install and configure PgBouncer? (Hands-on)
How to create a basic configuration file for PgBouncer? (Hands-on)
How to connect to PgBouncer? (Hands-on)
Explaining Advanced Settings for Performance
Which are the available Pool Modes?
Executing a benchmark with PgBouncer (Hands-on)
How to scale PostgreSQL in Google Cloud?
Introduction
Key Components on Google Cloud
Key Characteristics of the Architecture
How to create PostgreSQL Instances on Google Cloud? (Hands-on)
How to create a Google Cloud Engine (GCE) for HAProxy? (Hands-on)
How to configure HAProxy for Load-Balancing? (Hands-on)
Testing Load-Balancing
How to make use of PostgreSQL Partitioning?
What is Partitioning?
Which Tables Need Partitioning?
How should the Tables be Partitioned?
Declarative vs. Inheritance Partitioning
How to create a Partitioned Table? (Hands-on)
Partitioning Methods
How to Shard PostgreSQL?
What is Sharding?
Pain-Points of Sharding?
What is Second Level Sharding?
What is good Sharding?
How to query across multiple Shards?
How to setup High Availability (HA) on PostgreSQL?
Why High Availability?
Steps to achieve High Availability
Essential Questions to ask before setting-up High Availability
Log-Shipping Replication
Streaming Replication and Logical Replication
Cascading Replication
Synchronous vs. Asynchronous Replication
Automatic Failover and Always-on Strategy
Simple HA Solution Example
Better HA Solution Example
How to make use of PgPool II?
What is PgPool II?
Pgpool-II Features
How to Configure Pgpool-II with Streaming Replication? (Hands-on)
How to setup Streaming Replication? (Hands-on)
How to Configuring Pgpool-II for Load Balancing ? (Hands-on)
Testing load-balancing & read/write separation (Hands-on)
How to Configure Pgpool for PostgreSQL High-Availability? (Hands-on)
How to Configure PostgreSQL Primary Server? (Hands-on)
How to Configure Pgpool-II Server? (Hands-on)
How to Configure PostgreSQL Replica Server? (Hands-on)
Testing The Failover (Hands-on)
How to restore failed nodes? (Hands-on)