本来一直在用 Supabase,但是苦于 Free Plan 只能创建两个 Database,所以不得不寻找其他方案。

最初的想法是,在我美国的不同地区的 Servers 上部署 PG Instance,并且实现 HA (High Availability) 和 Replication。但是我发现如果要实现 HA,至少需要三个 Servers,而且需要保证三个 Servers 之间的优秀的网络。我又没有那么多 Servers,所以最后放弃了 HA。仅保留了主从 Replication,也就是说只要我在 Master 上创建了 Database,那么从数据库也会自动创建一个相同的 Database,并且自动同步数据。

我找到了一个相对来说比较简单的方案,就是使用 bitnami/postgresql 这个 Docker Image。

部署

Master Instance

services:
  postgres-primary:
    image: bitnami/postgresql:latest
    env_file:
      - .env
    restart: always
    volumes:
      - ./data/primary:/bitnami/postgresql
    ports:
      - "5432:5432"
# .env
POSTGRESQL_REPLICATION_MODE=master
POSTGRESQL_REPLICATION_USER=replicator
POSTGRESQL_REPLICATION_PASSWORD=password_hard_to_guess
POSTGRESQL_USERNAME=postgres
POSTGRESQL_PASSWORD=password_hard_to_guess
POSTGRESQL_DATABASE=mydb

Slave Instance

services:
  postgres-replica:
    image: bitnami/postgresql:latest
    env_file:
      - .env
    restart: always
    volumes:
      - ./data/replica:/bitnami/postgresql
    ports:
      - "5433:5432"
POSTGRESQL_REPLICATION_MODE=slave
POSTGRESQL_REPLICATION_USER=replicator
POSTGRESQL_REPLICATION_PASSWORD=password_hard_to_guess
POSTGRESQL_MASTER_HOST=master_instance_public_ip
POSTGRESQL_MASTER_PORT_NUMBER=5432
POSTGRESQL_USERNAME=postgres
POSTGRESQL_PASSWORD=password_hard_to_guess
POSTGRESQL_DATABASE=mydb

其中 Slave Instance 的 Port 其实可以不用映射到公网,因为 Slave 只负责同步数据,不负责对外提供服务。当然,我暴露 5433 是为了连接 Slave Instance 测试是否能实现自动同步。

我的 Master Instance 部署在 Los Angeles, CA,然而 Slave Instance 部署在 Pittsburgh, PA 家里的 PVE 的 Debian VM 上,实际测试下来效果非常好,能否实现几乎无延迟的同步。

优化

  • 使用 TLS 加密所有 Postgres 连接。
  • 计划实现真正的高可用性 (例如 Patroni 或 pg_auto_failover) 。