PostgreSQL高可用方案-patroni+etcd+vipmanager(一)


1 前言

1.1概述

Patroni + etcd + vipmanager cybertec推出的postgresql 高可用方案。其中, Etcd 用於存放集群狀態信息。Patroni 負責為PostgreSQL 集群提供故障轉移和高可用服務。vipmanager 根據etcdConsul中保存的狀態管理虛擬IP用於提供和管理虛擬ip,用於對外提供訪問地址。

1.2 方案架構

 

1.3 軟件介紹

1.3.1 etcd

etcdCoreOS團隊於20136月發起的開源項目,它的目標是構建一個高可用的分布式鍵值(key-value)數據庫。etcd內部采用raft協議作為一致性算法,etcd基於Go語言實現。

etcd作為服務發現系統,有以下的特點:

  • 簡單:安裝配置簡單,而且提供了HTTP API進行交互,使用也很簡單
  • 安全:支持SSL證書驗證
  • 快速:根據官方提供的benchmark數據,單實例支持每秒2k+讀操作
  • 可靠:采用raft算法,實現分布式系統數據的可用性和一致性

1.3.2 Patroni 

PatroniCybertec公司開發的,可用於使用流復制來創建,管理,維護和監視高可用性PostgreSQL集群設置的工具。

Patroni 是根據MIT許可證發行的,可以通過PIP輕松安裝。 對於UbuntuDebian,可以通過系統存儲庫獲得;對於FedoraCentOSRHELCYBERTEC提供了RPM軟件包。.

1.3.2 vip-manager

vip-managerCybertec公司開發的,根據etcdConsul中保存的狀態管理虛擬IP的工具。如果 vip-manager 看到它在當前主數據庫所在服務器上運行,它將獲取虛擬IP

1.4 方案的功能

該方案實現PostgreSQL的高可用和在線恢復。主要的功能如下:

1. 在主數據庫所在服務器上,創建接受訪問的虛擬IP。若主數據庫改變,虛擬ip也會漂移到新主數據庫所在的節點。

2. 若主數據庫停止,自動啟動主數據庫;

3. 若后備數據庫停止,自動啟動后備數據庫;

4. 若主數據庫無法啟動,則將某一后備數據庫提升為主數據庫將舊的主數據庫降級為后備數據庫,之后它可通過一條命令重新初始化;

5. 若后備數據庫無法啟動可通過一條命令重新初始化;

6. 支持手動切換主數據庫和后備數據庫;

1.5 實驗環境

本實驗需要兩台服務器。

硬件:

內存:32G

CPU:雙核四線程CPU * 2

    

操作系統:

Centos 7.5

 

軟件環境:

yum

Python 3.6.8

pip 9.0.3

etcd 3.3.11

patroni 2.0.2

PostgreSQL 12.4

vip-manager 1.0

 

主服務器(primary)的ip地址是10.19.134.134,主機名是node134PostgreSQL 的主節點和patroni 的主節點均在此部署。

后備服務器(standby)的ip地址是10.19.134.135,主機名是node135PostgreSQL 的備節點和patroni 的備節點均在此部署。

集群對外提供服務的虛擬ip 10.19.134.140。

 

 

2 安裝和部署

 

2.1 安裝和部署etcd

 

在兩台服務器上分別部署etcd 3.3

安裝和部署etcd的方法詳見下面的文章:

 

在Linux上部署etcd集群

 

2.2 安裝PostgreSQL

 

在兩台服務器上分別安裝PostgreSQL。本文中,我們通過源碼安裝 PostgreSQL 12.4

1. 關閉防火牆

 

[root@node134 ~]# systemctl  disable --now  firewalld

 

2. 關閉selinex

 [root@node134 ~]# sed   -e   '/^ \{0,\}SELINUX=/c\SELINUX=disabled'  -i  /etc/selinux/config

 

     setenforce 0

 

3. 安裝依賴

[root@node134 ~]# yum -y install readline-devel zlib-devel gcc

 

[root@node134 ~]# yum -y install perl perl-devel perl-ExtUtils-Embed

 

[root@node134 ~]# yum -y install python python-devel

 

 

4. 創建用戶組postgres

[root@node134 ~]# groupadd postgres

 

5. 創建用戶postgres,並且設置這個用戶屬於用戶組postgres

[root@node134 ~]# useradd -d /var/lib/pgsql -g postgres postgres

 

6. 從官網下載PostgreSQL源碼,這里我們下載 postgresql-12.4.tar.gz

 

7. 在數據庫所在服務器上解壓它

[root@node134 ~]# tar zxvf postgresql-12.4.tar.gz

 

 

 8. 進入解壓后的目錄,並編譯和安裝PostgreSQL。

 [root@node134 ~]# ./configure  --prefix=/opt/postgresql-12 --with-perl --with-python

 

[root@node134 ~]# make world

 

[root@node134 ~]# make install-world

 

這里  --prefix=/opt/postgresql-12 表示 PostgreSQL 的安裝目錄是 “/opt/postgresql-12”

 

9. 修改PostgreSQL 的安裝目錄的擁用者為 postgres,並設置用戶權限

[root@node134 ~]# chown postgres:postgres /opt/postgresql-12/ -R

 

[root@node134 ~]# chmod 755 /opt/postgresql-12/ -R

 

10. 切換OS用戶為postgres,之后的操作均通過此用戶完成。

[root@node134 ~]# su postgres

 

11. 創建PostgreSQL的數據目錄

[postgres@node134 ~]# /opt/postgresql-12/bin/initdb -U postgres -D /opt/postgresql-12/data -E utf8

 

12. 根據需要,修改 postgresql.conf 中的參數。

比如:

 

listen_addresses = '*'

 

logging_collector = on

 

log_directory = 'pg_log'

 

13. 啟動數據庫

[postgres@node134 ~]# cd /opt/postgresql-12/bin

 

[postgres@node134 ~]# ./pg_ctl start -D ../data

 

14. 登錄數據庫,修改postgres用戶的密碼

[postgres@node134 ~]# ./psql -h 127.0.0.1 -U postgres -p 5432

 

postgres=# alter user postgres password 'postgres123';

 

postgres=# \q

 

15. 修改 /data/pg_hba.conf,將認證方式從默認的trust 改為 md5,設置允許訪問的ip地址。本實驗中,修改和新增的內容如下:

 

host    all             all             127.0.0.1/32            md5

 

host    all             all             10.19.134.0/24            md5

 

 

16. 重啟數據庫

[postgres@node134 ~]# cd /opt/postgresql-12/bin

 

[postgres@node134 ~]# ./pg_ctl restart -D ../data

 

完成PostgreSQL 的部署。

 

2.3 搭建 postgresql 主備集群

 

部署postgresql 主備集群的方法詳見如下文檔:

 

【轉載】Linux下PostgreSQL主備環境搭建和切換

 

2.4 安裝和部署Patroni

 

1. 在兩台服務器上安裝 epel ,gccpython 3

 

[root@node134 ~]# yum -y install epel-release

 

[root@node134 ~]# yum -y install gcc

 

[root@node134 ~]# yum -y install python3

 

[root@node134 ~]# yum -y install python3-devel

 

2. 使用pip安裝 psycopg2 patroni

 

[root@node134 ~]# pip install psycopg2-binary -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com

 

[root@node134 ~]# pip install patroni[etcd,consul] -i https://mirrors.aliyun.com/pypi/simple/ --trusted-host=mirrors.aliyun.com

 

 

3. 驗證是否安裝成功:

 

[root@node134 ~]# which patroni

 

 

 

4. 在主機node134 上創建patroni的配置文件:

 

[root@node134 ~]# mkdir -p /etc/patroni/

 

[root@node134 ~]# cd /etc/patroni/

 

[root@node134 ~]# vi /etc/patroni/patroni_postgresql.yml

 

內容如下:

 

scope: postgresql12
namespace: /postgresql/
name: node134

restapi:
 listen: 10.19.134.134:8008
 connect_address: 10.19.134.134:8008

etcd:
 host: 10.19.134.134:2379

bootstrap:
 # this section will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster
 # and all other cluster members will use it as a `global configuration`
 dcs:
   ttl: 30
   loop_wait: 10
   retry_timeout: 10
   maximum_lag_on_failover: 1048576
   master_start_timeout: 300
   synchronous_mode: false
   postgresql:
     use_pg_rewind: true
     use_slots: true
     parameters:
       listen_addresses: "*"
       port: 5432
       wal_level: replica
       hot_standby: "on"
       wal_keep_segments: 10
       max_wal_senders: 10
       max_replication_slots: 10
       wal_log_hints: "on"


postgresql:
 listen: 10.19.134.0:5432
 connect_address: 10.19.134.134:5432
 data_dir: /opt/postgresql-12/data
 bin_dir: /opt/postgresql-12/bin
 config_dir: /opt/postgresql-12/data
 pgpass: /etc/patroni/.pgpass

 authentication:
   replication:
     username: repuser
     password: repuser123
   superuser:
     username: postgres
     password: postgres123
   rewind:
     username: postgres
     password: postgres123

tags:
   nofailover: false
   noloadbalance: false
   clonefrom: false
nosync: false

 

 

5. 修改它的屬主為postgres,並設置只有屬主才有讀寫權限其他用戶無任何權限:

 

[root@node134 ~]# chown -R postgres.postgres /etc/patroni/

 

[root@node134 ~]# chmod 600 /etc/patroni/patroni_postgresql.yml

 

6. 在主機node135 上創建patroni的配置文件:

 

[root@node135 ~]# mkdir -p /etc/patroni/

 

[root@node135 ~]# cd /etc/patroni/

 

[root@node135 ~]# vi /etc/patroni/patroni_postgresql.yml

 

內容如下:

 

scope: postgresql12
namespace: /postgresql/
name: node135

restapi:
  listen: 10.19.134.135:8008
  connect_address: 10.19.134.135:8008

etcd:
  host: 10.19.134.135:2379

bootstrap:
  # this section will be written into Etcd:/<namespace>/<scope>/config after initializing new cluster
  # and all other cluster members will use it as a `global configuration`
  dcs:
    ttl: 30
    loop_wait: 10
    retry_timeout: 10
    maximum_lag_on_failover: 1048576
    master_start_timeout: 300
    synchronous_mode: false
    postgresql:
      use_pg_rewind: true
      use_slots: true
      parameters:
        listen_addresses: "*"
        port: 5432
        wal_level: replica
        hot_standby: "on"
        wal_keep_segments: 10
        max_wal_senders: 10
        max_replication_slots: 10
        wal_log_hints: "on"

postgresql:
  listen: 10.19.134.0:5432
  connect_address: 10.19.134.135:5432
  data_dir: /opt/postgresql-12/data
  bin_dir: /opt/postgresql-12/bin
  config_dir: /opt/postgresql-12/data
  pgpass: /etc/patroni/.pgpass

  authentication:
    replication:
      username: repuser
      password: repuser123
    superuser:
      username: postgres
      password: postgres123
    rewind:
      username: postgres
      assword: postgres123

tags:
  nofailover: false
  noloadbalance: false
  clonefrom: false

nosync: false

 

7. 然后修改它的屬主為postgres,並設置只有屬主才有讀寫權限

 

[root@node135 ~]# chown -R postgres.postgres /etc/patroni/

 

[root@node135 ~]# chmod 600 /etc/patroni/patroni_postgresql.yml

 

8. 我們可以將 patroni 注冊為服務創建文件 /usr/lib/systemd/system/patroni.service,內容如下:

 

[Unit]
Description=High availability PostgreSQL Cluster
After=syslog.target network.target

[Service]
Type=simple
User=postgres
Group=postgres
ExecStart=/usr/local/bin/patroni /etc/patroni/patroni_postgresql.yml
KillMode=process
TimeoutSec=30
Restart=no

[Install]
WantedBy=multi-user.target

 

 

9. 完成后,通過操作系統命令啟動和關閉patroni服務:

[root@node134 ~]# systemctl start patroni

 

10. 在另一個窗口中查看 patroni 集群狀態

 

[root@node134 ~]# patronictl -c /etc/patroni/patroni_postgresql.yml list

 

結果如下:

 

+ Cluster: postgresql12 (6914170278151575561) -----+----+-----------+

| Member  | Host               | Role    | State   | TL | Lag in MB |

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

| node134 | 10.19.134.134:5435 | Leader  | running | 25 |           |

| node135 | 10.19.134.135:5435 | Replica | running | 25 |         0 |

 

 

上述信息可知,位於 node134 上PostgreSQL 是主數據庫,位於node135 的數據庫。

 

2.5 安裝 vip-manager

 

1. 安裝golang

yum -y install golang

 

2. 設置環境變量GOPROXY,它表示代理服務,僅在中國大陸需要。

 

export GOPROXY=https://goproxy.io

 

3. 下載 vip-manager 源碼。本文使用的版本是1.0.1

 

4. 解壓vip-manager 的源碼。

tar zxvf vip-manager-1.0.1.tar.gz

 

5. 進入解壓后的目錄vip-manager-1.0.1,編譯vip-manager

cd vip-manager-1.0.1

make

 

6. 將生成的vip-manager二進制文件復制到/usr/bin/vip-manager

cp ./vip-manager /usr/bin/vip-manager

 

 

7. 將服務文件從 package/scripts/vip-manager.service 復制到 /usr/lib/systemd/system/

 

cp ./package/scripts/vip-manager.service  /usr/lib/systemd/system/

 

8. 將安裝配置文件從vipconfig/vip-manager.yml 復制到 /etc/default/

 

cp ./vipconfig/vip-manager.yml  /etc/default/

 

8. 編輯配置文件 /etc/default/vip-manager.yml,修改下面這些參數的值:

 

ip  要管理的虛擬IP地址

 

netmask  與虛擬IP vip所屬的子網相關聯的子網掩碼。

 

interface 運行vip-manager的機器上的本地網絡接口。當使用hosting-type=basic(默認)時需要。該界面將添加和刪除vip

 

trigger-key  將由vip經理監控的DCS中的密鑰。必須匹配Patroni配置中的<namespace>/<scope>/leader。當DCS返回的值等於trigger-value時,vip-manager將確保虛擬IP已注冊到這台機器。如果不匹配,vip-manager會確保虛擬IP沒有注冊到這台機器上。

 

trigger-value  DCS的觸發鍵應答將被匹配的值。必須匹配Patroni配置中的<name>。這通常設置為與這個vip-manager實例相關聯的patroni集群成員的名稱。默認為機器的主機名。

 

hosting-type  要么是basic要么是hetzner。介紹了虛擬IP的管理機制。默認為basic

 

dcs-type  vip-manager用於監控觸發鍵的DCS類型。默認為etcd

 

dcs-endpoints 定義到達DCS地址的url。可以使用逗號分隔的列表將多個端點傳遞給這個參數或環境變量。在配置文件中,可以指定一個列表,示例請參見配置示例。dcs-type=etcd時,默認為http://127.0.0.1:2379 dcs-type=consul時,默認為http://127.0.0.1:8500

 

同時,用“#”注釋掉 etcd-ca-fileetcd-cert-fileetcd-key-file。我們不使用SSL 認證.

 

9. 在主節點上,這些參數配置如下:

 

ip: 10.19.134.140

netmask: 24

interface: eth0

trigger-key: "/postgresql/postgresql12/leader"

trigger-value: "node134"

hosting-type: basic

dcs-type: etcd

dcs-endpoints:
  - http://127.0.0.1:2379
  - http://10.19.134.134:2379

 

在備節點上,這些參數配置如下:

ip: 10.19.134.140

netmask: 24

interface: eth0

trigger-key: "/postgresql/postgresql12/leader"

trigger-value: "node135"

hosting-type: basic

dcs-type: etcd

dcs-endpoints:
  - http://127.0.0.1:2379
  - http://10.19.134.135:2379

 

10. 分別在主節點和后備節點上啟動vip-manager

systemctl start vip-manager

 

前言

1.1 etcd簡介

etcd是CoreOS團隊於2013年6月發起的開源項目,它的目標是構建一個高可用的分布式鍵值(key-value)數據庫。etcd內部采用raft協議作為一致性算法,etcd基於Go語言實現。

etcd作為服務發現系統,有以下的特點:

  • 簡單:安裝配置簡單,而且提供了HTTP API進行交互,使用也很簡單
  • 安全:支持SSL證書驗證
  • 快速:根據官方提供的benchmark數據,單實例支持每秒2k+讀操作
  • 可靠:采用raft算法,實現分布式系統數據的可用性和一致性

1.2 安裝環境

本實驗需要兩台服務器,如下表所示。

 

 

操作系統

內存

CPU

IP地址

主機名

服務器1

Centos 7.5

32G

雙核四線程CPU * 2

10.40.239.234

node234

服務器2

Centos 7.5

32G

雙核四線程CPU * 2

10.40.239.235

node235

2 操作流程

2.1 對服務器校時

這里我們使用國家授時中心NTP(Network Time Protocol)服務對兩台服務器校時:

ntpdate ntp.ntsc.ac.cn

2.2 安裝etcd

在兩台服務器上執行下面的命令,安裝etcd:

yum -y install etcd

 

執行下面的命令,查看etcd:

yum list installed |grep -i etcd

如果出現如下結果,表示安裝成功:

etcd.x86_64                 3.3.11-2.el7.centos            @extras

 

2.3 配置etcd

2.3.1 node234 上的配置

    1. 備份原先的etcd配置文件。

cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf.bak

 

2.編輯配置文件:

vi /etc/etcd/etcd.conf

配置如下內容:

ETCD_DATA_DIR="/var/lib/etcd/node234.etcd"

ETCD_LISTEN_PEER_URLS="http://10.40.239.234:2380"

ETCD_LISTEN_CLIENT_URLS="http://10.40.239.234:2379,http://localhost:2379"

ETCD_NAME="node234"

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.40.239.234:2380"

ETCD_ADVERTISE_CLIENT_URLS="http://10.40.239.234:2379"

ETCD_INITIAL_CLUSTER="node234=http://10.40.239.234:2380, node235=http://10.40.239.235:2380"

ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"

ETCD_INITIAL_CLUSTER_STATE="new"

 

 

這里解釋一下這些參數的含義:

ETCD_DATA_DIR:數據存儲目錄。由etcd自動創建。

 

ETCD_LISTEN_PEER_URLS:監聽在對等節點流量上的URL列表,該參數告訴etcd在指定的 “協議://IP:端口”組合上接收來自其對等方的傳入請求。協議可以是http或者https。或者,使用unix://<file-path>或者unixs://<file-path>到unix sockets。如果將0.0.0.0作為IP,etcd將監聽在所有的接口上的給定端口。如果給定了IP和端口,etcd將監聽指定的接口和端口。可以使用多個URL指定要監聽的地址和端口的數量。 etcd將響應來自任何列出的地址和端口的請求。

 

ETCD_LISTEN_CLIENT_URLS:監聽在客戶端流量上的URL列表,該參數告訴etcd在指定的“協議://IP:端口”組合上接受來自客戶端的傳入請求。協議可以是http或者https。或者,使用unix://<file-path>或者unixs://<file-path>到unix sockets。如果將0.0.0.0作為IP,etcd將監聽在所有的接口上的給定端口。如果給定了Ip和端口,etcd將監聽指定的接口和端口。可以使用多個URL指定要監聽的地址和端口的數量。 etcd將響應來自任何列出的地址和端口的請求。

 

ETCD_NAME:此成員的名字。

 

ETCD_INITIAL_ADVERTISE_PEER_URLS:此成員對等URL的列表,用來通知到集群的其余部分。 這些地址用於在集群周圍傳送etcd數據。 所有集群成員必須至少有一個路由。 這些URL可以包含域名。

 

ETCD_ADVERTISE_CLIENT_URLS:此成員的客戶端URL的列表,這些URL廣播給集群的其余部分。 這些URL可以包含域名。

 

ETCD_INITIAL_CLUSTER:啟動集群的初始化配置。配置集群的成員。

 

ETCD_INITIAL_CLUSTER_TOKEN:引導期間etcd群集的初始集群令牌。

 

ETCD_INITIAL_CLUSTER_STATE:初始群集狀態(“新”或“現有”)。 對於在初始靜態或DNS引導過程中存在的所有成員,將其設置為new。 如果此選項設置為existing,則etcd將嘗試加入現存集群。 如果設置了錯誤的值,etcd將嘗試啟動,但會安全地失敗。

 

更多信息,可以參照etcd官方文檔

 

2.3.1 node235 上的配置

1. 備份原先的etcd配置文件。

cp /etc/etcd/etcd.conf /etc/etcd/etcd.conf.bak

 

2.編輯配置文件:

 

ETCD_DATA_DIR="/var/lib/etcd/node235.etcd"

ETCD_LISTEN_PEER_URLS="http://10.40.239.235:2380"

ETCD_LISTEN_CLIENT_URLS="http://10.40.239.235:2379,http://localhost:2379"

ETCD_NAME="node235"

ETCD_INITIAL_ADVERTISE_PEER_URLS="http://10.40.239.235:2380"

ETCD_ADVERTISE_CLIENT_URLS="http://10.40.239.235:2379"

ETCD_INITIAL_CLUSTER="node234=http://10.40.239.234:2380,node235=http://10.40.239.235:2380"

ETCD_INITIAL_CLUSTER_TOKEN="etcd-cluster"

ETCD_INITIAL_CLUSTER_STATE="new"

 

 

2.4 修改etcd.service

在兩台服務器上,分別修改服務啟動文件 /usr/lib/systemd/system/etcd.service,內容設置如下:

[Service]

Type=notify

WorkingDirectory=/var/lib/etcd/

EnvironmentFile=-/etc/etcd/etcd.conf

User=etcd

# set GOMAXPROCS to number of processors

ExecStart=/bin/bash -c "GOMAXPROCS=$(nproc) /usr/bin/etcd \

--name=\"${ETCD_NAME}\" \

--data-dir=\"${ETCD_DATA_DIR}\" \

--listen-peer-urls=\"${ETCD_LISTEN_PEER_URLS}\" \

--listen-client-urls=\"${ETCD_LISTEN_CLIENT_URLS}\" \

--initial-advertise-peer-urls=\"${ETCD_INITIAL_ADVERTISE_PEER_URLS}\" \

--advertise-client-urls=\"${ETCD_ADVERTISE_CLIENT_URLS}\" \

--initial-cluster=\"${ETCD_INITIAL_CLUSTER}\"  \

--initial-cluster-token=\"${ETCD_INITIAL_CLUSTER_TOKEN}\" \

--initial-cluster-state=\"${ETCD_INITIAL_CLUSTER_STATE}\""

Restart=on-failure

LimitNOFILE=65536

 

 

2.5 啟動 etcd

依次啟動 node234和node235節點的 etcd

systemctl start etcd.service

設置允許開機啟動:

systemctl enable etcd.service

2.6 查看etcd的狀態

執行下列命令,驗證etcd的狀態:

etcdctl cluster-health

結果:

member 5a4542289ef36c64 is healthy: got healthy result from http://10.40.239.234:2379

member f792ada069403352 is healthy: got healthy result from http://10.40.239.235:2379

 

查看etfd 結點列表:

etcdctl member list

結果:

5a4542289ef36c64: name=node234 peerURLs=http://10.40.239.234:2380 clientURLs=http://10.40.239.234:2379 isLeader=true

f792ada069403352: name=node236 peerURLs=http://10.40.239.235:2380 clientURLs=http://10.40.239.236:2379 isLeader=false

 
標簽:  etcd
好文要頂  關注我  收藏該文   
0
0
 
 
 
« 上一篇:  數據庫從PostgreSQL遷移至Oracle指導書(四) 
» 下一篇:  使用 barman的備份和歸檔PostgreSQL
posted @  2020-09-23 10:59   草色青青送馬蹄  閱讀( 558)  評論( 0)   編輯   收藏

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM