暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

PG高可用架构实施方案

张春光的一亩三分地 2020-11-23
824

1、PG概述

PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统(RDBMS)。PostgreSQL最初设想于1986年,当时被叫做Berkley Postgres Project。该项目一直到1994年都处于演进和修改中,直到开发人员Andrew YuJolly ChenPostgres中添加了一个SQLStructured Query Language,结构化查询语言)翻译程序,该版本叫做Postgres95,在开放源代码社区发放。

1996年,再次对Postgres95做了较大的改动,并将其作为PostgresSQL6.0版发布。该版本的Postgres提高了后端的速度,包括增强型SQL92标准以及重要的后端特性(包括子选择、默认值、约束和触发器)。

PostgreSQL是一个非常健壮的软件包,有很多在大型商业RDBMS中所具有的特性,包括事务、子选择、触发器、视图、外键引用完整性和复杂锁定功能。另一方面,PostgreSQL也缺少商业数据库中某些可用的特性,如用户定义的类型、继承性和规则。

2020-05-21,PostgreSQL全球开发组宣布PostgreSQL13的第一个Beta版本正式提供下载。这个版本包含将来PostgreSQL 13正式版本中的所有特性和功能,当然一些功能的细节在正式版本发布时可能会有些变化。

鉴于PG版本的稳定性和使用广泛性,我们选择PG11--postgresql-11.7这个版本。

2、高可用架构概述

Patroni+ ZooKeeper 方案:

健壮性:使用分布式文件系统作为数据存储,主节点故障时进行主节点重新选举,具有很强的健壮性。

支持多种复制方式: 基于内置流复制,支持同步流复制、异步流复制、级联复制。

支持主备延迟设置:可以设置备库延迟主库WAL的字节数,当备库延迟大于指定值时不做故障切换。

自动化程度高: 1)支持自动化初始PostgreSQL实例并部署流复制; 2)当备库实例关闭后,支持自动拉起; 3)当主库实例关闭后,首先会尝试自动拉起; 4)支持switchover命令,能自动将老的主库进行角色转换。

避免脑裂: 数据库信息记录到ZOOKEEPER 中,通过优化部署策略(多机房部署、增加实例数)可以避免脑裂。

2.1.          Patroni简介

Patroni基于Python开发的模板,结合DCS(例如ZooKeeper, ETCD, Consul )可以定制PostgreSQL高可用方案。

Patroni并不是一套拿来即用的PostgreSQL高可用组件,涉及较多的配置和定制工作。

Patroni接管PostgreSQL数据库的启停,同时监控本地的PostgreSQL数据库,并将本地的PostgreSQL数据库信息写入DCS

Patroni的主备端是通过是否能获得leader key 来控制的,获取到了leader keyPatroni为主节点,其它的为备节点。

2.2.          ZooKeeper简介

ZooKeeper是一款基于FastPaxos算法和协议开发的Zookeeper 分布式服务框架是Apache Hadoop 的一个子项目,它主要是用来解决分布式应用中经常遇到的一些数据管理问题,如:统一命名服务、状态同步服务、集群管理、分布式应用配置项的管理等Patroni监控本地的PostgreSQL状态,并将相关信息写入ZooKeeper,每个Patroni都能读写ZooKeeper上的key,从而获取外地PostgreSQL数据库信息。

ZooKeeperleader节点不可用时,ZooKeeper会一致性的选择一个合适的节点作为主节点,新的ZooKeeper主节点将获取leader key,因此建议ZooKeeper集群为三个以上且为奇数的节点,不建议部署在同一个机房,有条件话尽量部署在三个机房。

一个标准的3节点ZooKeeper集群,最大容许1个节点故障。

 

3、读写分离和虚拟IP

3.1.          HAProxy

HAProxy提供高可用性、负载均衡以及基于TCPHTTP应用的代理,支持虚拟主机,它是免费、快速并且可靠的一种解决方案。HAProxy特别适用于那些负载特大的web站点, 这些站点通常又需要会话保持或七层处理。HAProxy运行在当前的硬件上,完全可以支持数以万计的并发连接。并且它的运行模式使得它可以很简单安全的整合进当前的架构中,同时可以保护你的web服务器不被暴露到网络上。

HAProxy做数据库读写分离,主要是通过限制访问的端口号来实现,例如访问5000端口是主数据库,可读可写;访问5001端口连接的是从数据库,做只读查询。

3.2.          Keepalive

通过keepalive 来实现  PostgreSQL 数据库的主从自动切换,以达到高可用,当主节点宕机时,从节点可自动切换为主节点,继续对外提供服务,同时为了保证 keepalived 不会出现单点故障,所以keepalived 也搭建主备节点,防止单点故障。

同时,可以使用keepalive虚拟出来的IP进行数据库访问,结合HAProxy的读写分离功能,进行实现可高可用下的读写分离。

 

4、实施方案目标

 

4.1.          实施方案总体拓扑

 


4.2.          实施方案拓扑说明

技术方案主要目的是

Ø  利用zookeeper将节点做成分布式架构;

Ø  postgresql 数据库和patroni软件结合,完成数据库的主从复制;

Ø  利用haproxy进行主库和从库的读写分离;

Ø  利用keepalive做节点间的高可用,并利用虚拟IP地址对外提供服务

关键点是整合上述的各自功能,实现架构可自动切换的高可用功能。上述拓扑实施完成后,主要带来以下收益:

 

5、项目实施控制

数据库系统项目通常都是以循序渐进的方式推进,构建新的数据库平台。


6、实施环境准备

为了能让客户完成数据库整合项目,在项目实施前需要具备以下条件:

6.1.          主机

由于数据库整合项目,需要先构建三个数据库整合平台,因此必须有9台主机来建立数据库平台:

主机升级改造

硬件名称

规格

数量

说明

其他

服务器

CPU:24cpu

MEM:64G

硬盘:服务可用存储空间不低于2T

3

构建基于PG数据库的高可用平台

 建议五台服务器,三台服务器用于做分布式主从复制,两台做高可用读写分离和VIP

 

6.2.          存储

PG数据库的高可用平台可以使用本地磁盘空间,也可以单独挂载高性能存储设备如果单独挂载存储设备,空间需求如下:

存储升级改造

硬件名称

规格

数量

说明

其他

生产存储

10T容量

1

用于生产存储,存储可以使用现有存储设备具体容量和需求以实际为主

Raid 1+0

10T为可用空间

备份存储

20T容量

1

用于备份存储,备份存储可以使用现有存储设备具体容量和需求以实际为主

Raid 5

SAN交换机

6

2

用于搭建san环境

如存在,则忽略

 

6.3.          软件系统

如果对于软件有正版化需求,则需要额外购买正版化的Postgreslinux软件授权.

操作系统升级改造

软件名称

规格

数量

说明

其他

PostgreSQL


3

PG数据库的高可用平台


Patroni


3

PG数据库的高可用平台


zookeeper


3

PG数据库的高可用平台


haproxy


3

PG数据库的高可用平台


keepalive


3

PG数据库的高可用平台


RHEL 7.6 x64

企业版

3

用于PG数据库的高可用平台操作系统


 

6.4.          IP地址

实施过程中,对应很多软件都是开源的,安装相对繁琐复杂,因此建议打开互联网连接,能够和对应的安装源通信。

资源升级改造

软件名称

规格

数量

说明

其他

公有IP地址

生产段

3

用于PG数据库的高可用平台公用IP,日常管理

开放5432关口

虚拟IP地址

生产段

1

用于PG数据库的高可用平台虚拟IP,集群高可用

开放5000和5001端口

 

7、实施方案

7.1.          规划

7.1.1.     软件版本

POSTGRES数据库集中平台:

              项目

版本

操作系统

Redhat Linux  AS 7.6 64bit

数据库软件版本

PostgreSQL  11.7

 

7.1.2.     存储规划

生产存储数据库部分存储容量规划如下:

数据库名

raid级别

LUN

可用容量(GB)

用途

TWXPDS

随操作系统

LUN1:100G

1T

主要用于数据库存储,

暂时分配1T空间,Linux LVM方式,方便后面空的动态扩展

备份存储容量规划如下:

系统名称

raid级别

LUN

可用容量(GB)

用途

TWXPDS

随操作系统

LUN2:600G

600G

主要用于数据库备份,暂时分配600G空间,Linux LVM方式,方便后面空的动态扩展

WALS归档存储容量规划如下:

数据库名

raid级别

LUN

可用容量(GB)

用途

TWXPDS

随操作系统

LUN3:300G

300G

主要用于WALS归档,暂时分配300G空间,Linux LVM方式,方便后面空的动态扩展

 

7.1.3.     数据库命名约定

POSTGRES数据库集中平台:

项目

取值

群集名

pg_micky

主机名

micky1、micky2、micky3

数据库名

TWXPDS

字符集

UTF8

参数要求

max_connections:  500

shared_buffers:  16000MB

work_mem:  32MB

maintenance_work_mem:  512MB

synchronous_commit:  on

max_wal_size:  1GB

min_wal_size:  80MB

listen_addresses:  '*'

port: 5432

安装组

groupadd -g  1000 postgres

安装用户

useradd -u 1000 -g postgres postgres

软件目录

mkdir  -p /pgdata/data

mkdir  -p /backup

mkdir  -p /archive_wals

mkdir  -p /scripts

 

chown  -R postgres.postgres /backup

chown  -R postgres.postgres /archive_wals

chown  -R postgres.postgres /scripts

chown  -R postgres.postgres /pgdata/data

表空间命名

TWXPDS

 

7.1.4.     数据库网络规划

项目

取值

PUB IP

192.168.24.140.X/255.255.254.0

VIP

192.168.140.X

网关

192.168.140.1

监听端口

5432

 

 

7.2.          数据库集中平台创建

7.2.1.     基础环境准备

1) 创建用户、组

以root身份运行以下命令:

groupadd -g 1001 postgres

useradd -u 1000 -g postgres postgres

 

设置postgres账户的密码:

passwd postgres

Changing password for user postgres.

New UNIX password: password

retype new UNIX password: password

passwd: all authentication tokens updatedsuccessfully.

 

 

2)  IP规划(具体以实际为准)

127.0.0.1  localhost localhost.localdomain localhost4 localhost4.localdomain4

::1        localhost localhost.localdomain localhost6 localhost6.localdomain6

 

192.168.140.74  micky1

192.168.140.75  micky2

192.168.140.76  micky3

 

3)  创建相关目录

数据库存放位置:

mkdir -p /pgdata/data

---存放pg数据库

mkdir -p /backup

---备份pg数据库

mkdir -p /archive_wals

---WALS归档

mkdir -p /scripts

---特殊脚本部署位置

 

授权给psotgres账户:

 chown -R postgres.postgres/backup

chown -R postgres.postgres /archive_wals

chown -R postgres.postgres /scripts

chown -R postgres.postgres /pgdata/data

chown -R postgres:postgres /usr/local/postgresql

 

4)  共享存储规划(以实际需求为准):

/dev/mapper/pgbackup-pgbackup: 645.3 GB

/dev/mapper/pgdata-pgdata: 1099.5 GB

/dev/mapper/pgwals-pgwals: 322.1 GB

 

5)  LVM相关操作

[root@micky1 ~]# vgcreate pgdata /dev/sdb2

  Volume group"pgdata" successfully created

[root@micky1 ~]# vgcreate pgwals /dev/sdb3

  Volume group"pgwals" successfully created

[root@micky1 ~]# vgcreate pgbackup/dev/sdb4

  Volume group"pgbackup" successfully created

[root@micky1 ~]# lvcreate -l 100%VG -npgdata pgdata

  Logicalvolume "pgdata" created.

[root@micky1 ~]# lvcreate -l 100%VG -npgwals pgwals

  Logicalvolume "pgwals" created.

[root@micky1 ~]# lvcreate -l 100%VG -npgbackup pgbackup

  Logicalvolume "pgbackup" created.

6)  创建用户Profile

创建 所有 用户环境文件:

export PATH=/usr/local/postgresql/bin:$PATH

exportLD_LIBRARY_PATH=/usr/local/postgresql/lib:$LD_LIBRARY_PATH

 

 

export ZKHOME=/u01/apache-zookeeper-3.6.1

PATH=$PATH:$HOME/bin:$ZKHOME/bin

创建 postgres 用户环境文件:

export PGHOME=/usr/local/postgresql

export PGDATA=/pgdata/data

 

7)  安全设置

关闭防火墙:

[root@micky3 ~]# systemctl stop firewalld.service

[root@micky3 ~]# systemctl disablefirewalld.service

设置SELinux:

[root@micky3 ~]# vi /etc/selinux/config

 

# This file controls the state of SELinux on thesystem.

# SELINUX= can take one of these three values:

#    enforcing - SELinux security policy is enforced.

#    permissive - SELinux prints warnings instead of enforcing.

#     disabled- No SELinux policy is loaded.

SELINUX=disabled

# SELINUXTYPE= can take one of three values:

#     targeted- Targeted processes are protected,

#     minimum- Modification of targeted policy. Only selected processes are protected.

#     mls -Multi Level Security protection.

SELINUXTYPE=targeted

 

8)  安装依赖包

rpm -ivh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

yum -y install  libffi-devel

wget -chttps://www.python.org/ftp/python/3.8.2/Python-3.8.2.tar.xz

cd Python-3.8.2

./configure --with-ssl

make && make install

创建Python软连接:

rm -f /usr/bin/python

ln -s /usr/local/bin/python3 /usr/bin/python

7.2.2.     软件安装

tarzxvf postgresql-11.7.tar.gz

cdpostgresql-11.7

./configure--prefix=/usr/local/postgresql

 

#编译安装

makeworld && make install-world

……

make[2]:Leaving directory `/root/postgresql-11.7/contrib/unaccent'

make-C vacuumlo install

make[2]:Entering directory `/root/postgresql-11.7/contrib/vacuumlo'

/usr/bin/mkdir-p '/usr/local/postgresql/bin'

/usr/bin/install-c  vacuumlo '/usr/local/postgresql/bin'

make[2]:Leaving directory `/root/postgresql-11.7/contrib/vacuumlo'

make[1]:Leaving directory `/root/postgresql-11.7/contrib'

PostgreSQL,contrib, and documentation installation complete.

7.2.3.     初始化数据库

Step1初始化并启动数据库

#初始化数据库

initdb-D /pgdata/data

 #启动服务

pg_ctl-D /pgdata/data -l /pgdata/data/logfile start

 

Step2修改参数并重启数据库

#修改postgresql.conf 文件

vi/pgdata/data/postgresql.conf

#修改为如下:

listen_addresses= '*'

port =5432

 

#--------------------允许远程连接---------------------------

#修改客户端认证配置文件pg_hba.conf,将需要远程访问数据库的IP地址或地址段加入该文件

vi/pgdata/data/pg_hba.conf

 

#在文件的最下方加上下面的这句话(出于安全考虑,不建议这样配置)

host    all        all         0.0.0.0/0             trust

host            replication            repuser            192.168.140.74/32            md5

host            replication            repuser            192.168.140.75/32            md5

host            replication            repuser            192.168.140.76/32            md5

pg_ctl-D /pgdata/data -l /pgdata/data/logfile stop

pg_ctl-D /pgdata/data -l /pgdata/data/logfile start

 

7.2.4.     配置主从同步

Step1主库创建Replication专有用户

 主库创建Replication专有用户

CREATEUSER repuser REPLICATION ENCRYPTED PASSWORD 'postgres';

 

Step2配置主库postgresql.conf参数

altersystem set wal_level = replica;

altersystem set archive_mode = on;

altersystem set archive_command = '/bin/true';

altersystem set max_wal_senders = 10;

altersystem set wal_keep_segments = 512;

altersystem set hot_standby = on;

altersystem set synchronous_commit = on;

altersystem set synchronous_standby_names = 'pg_micky01,pg_micky02,pg_micky03'; srvctlstart alter system set archive_timeout = '30s';

altersystem set archive_command = 'cp %p /archive_wals/%f';

重启数据库:

pg_ctl-D /pgdata/data -l /pgdata/data/logfile stop

pg_ctl-D /pgdata/data -l /pgdata/data/logfile start

 

Step3备库上使用pg_basebackup从主库同步数据

 [postgres@micky2 data]$ pg_basebackup -D /pgdata/data-Fp -Xs -v -P -h 192.168.140.74 -p 5432 -U repuser

Password:

pg_basebackup:initiating base backup, waiting for checkpoint to complete

pg_basebackup:checkpoint completed

pg_basebackup:write-ahead log start point: 0/2000060 on timeline 1

pg_basebackup:starting background WAL receiver

pg_basebackup:created temporary replication slot "pg_basebackup_81452"

23831/23831kB (100%), 1/1 tablespace                                         

pg_basebackup:write-ahead log end point: 0/2000130

pg_basebackup:waiting for background process to finish streaming ...

pg_basebackup:base backup completed

 

Step4配置备库recovery.conf

cp/usr/local/postgresql/share/recovery.conf.sample /pgdata/data/recovery.conf

 

vi/pgdata/data/recovery.conf

#节点micky2

recovery_target_timeline= 'latest'

standby_mode= on

primary_conninfo= 'host=192.168.140.74 port=5432 user=repuser password=postgresapplication_name=pg_atj02'

 

#节点micky3

recovery_target_timeline= 'latest'

standby_mode= on

primary_conninfo= 'host=192.168.140.74 port=5432 user=repuser password=postgresapplication_name=pg_atj03'

重启备库

pg_ctl-D /pgdata/data -l /pgdata/data/logfile stop

pg_ctl-D /pgdata/data -l /pgdata/data/logfile start

 

Step5查看配置是否生效

postgres=#SELECT usename,application_name,client_addr,sync_state FROM pg_stat_replication;

 usename | application_name |  client_addr | sync_state

---------+------------------+---------------+------------

 repuser | pg_micky02         | 192.168.140.74 | sync

 repuser | pg_micky03         | 192.168.140.75 | potential

(2rows)

 

Step6插入数据查看同步情况

#创建测试数据库

createdatabase micky;

 #切换到micky 数据库

\cmicky

 #创建测试表

createtable micky (id integer, name text);

 #插入测试数据

insertinto micky values (1,'micky');

 #选择数据

select* from micky ;

备库查询:

micky=# select * frommicky ;

 id | name

----+-------

  1 | micky

(1 row)


文章转载自张春光的一亩三分地,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论