Zalando Patroni
文章目录
Patroni
Patroni是从compose/governor发展而来的开源项目,旨在帮助PostgreSQL用户快速搭建一个基于Streaming Replication特性的高可用PG集群。
Patroni基于Python3开发,运行时需要一个分布式配置存储服务(称为DCS)来分发不同Patroni实例之间的配置。
目前Patroni支持以下DCS:
- etcd or etcd3
- consul
- zookeeper
- exhibitor
- kubernetes
- raft
- aws
上述DCS中需要着重说明的是raft,Patroni可以基于pysyncobj库在内部通过Raft协议实现Leader选举功能,此时Patroni不在依赖外部的DCS
Configuration
Patroni本质上是Postgres的配置同步工具,所有配置项由以下三个部分组成:
- Dynamic configuration:保存在DCS上的配置,用户可以随时修改上述配置Patroni发现配置变化后,同步修改到所有的Postgres节点。
- Local configuration (patroni.yml):Patroni进程启动时会加载配置文件,配置文件中的配置有限级高于Dynamic configuration。Patroni进程运行过程中,用户可以通过发送SIGHUP或者调用REST API重新加载配置文件。
- Environment configuration:Environment 配置覆盖配置文件中的配置,有最高的优先级。
出于以下考虑,Patroni将一下Postgres的配置规定为动态配置,用户只能在DCS上设置:
- PostgreSQL某些参数必须在所有实例上保持相同的值
- PostgreSQL不要求Master和Replicas之间配置一致,但由于可能发生主备切换
同时Partroni还接管了PostgreSQL一些配置,在postgresql.conf直接修改这些配置没有作用,包括:
- listen_addresses:通过postgresql.listen或者PATRONI_SCOPE指定
- port:通过postgresql.listen或者PATRONI_SCOPE指定
- cluster_name:通过scope或者PATRONI_SCOPE指定
- hot_standby:强制为on
上述配置Patroni在启动Postgres时通过pg_ctl start
传递,因此具备最高的优先级。
每个节点有以下三个配置文件:
- postgresql.base.conf:Partroni进程生成,每个节点可能不同,用户可以用custom_conf配置指定改文件,或者在数据库目录中创建同名文件。如果用户没有指定custom_conf或者放置同名文件,那么原生postgresql.conf配置的内容将会被写入该文件中。
- postgresql.conf:include了postgresql.base.conf文件,并且包含DCS中的动态设置。因此该文件是所有节点都相同的。
- postgresql.auto.conf:Postgres原生配置,用于
ALTER SYSTEM
操作。
postgresql.conf修改后执行 SELECT pg_reload_conf() 或者 pg_ctl reload 就可以使配置生效
每次更新DCS配置是Patroni节点还会在数据目录下生成patroni.dynamic.json文件。当DCS上的配置不可用时,Master会通过该文件恢复DCS上的配置。
RestAPI
Patroni自身包含一个REST API,用于进行PostgreSQL的Leader选举,通过patronictl工具通过REST API执行failovers/switchovers/reinitialize/restarts/reloads,用户可以通过该REST API执行监控等工作。
1.健康检查
在Master节点上,以下Endpoint返回200:
- GET /
- GET /master
- GET /primary
- GET /read-write
- GET /standby-leader:只有在Standby Cluster集群中返回200
- GET /leader: 当Patroni节点有leader锁时,返回HTTP状态码200,即无论PostgresSQL是否是standby cluster或者正常集群
在Replica节点上,以下Endpoint返回200:
- GET /replica:role是replica并且没有设置noloadbalance标签
- GET /replica?lag=
:检查服务延迟,并且在低于指定值时返回200。max-lag的值可以是整数或者16kB, 64MB, 1GB - GET /replica?tag_key1=value1&tag_key2=value2:检查replica的同时检查节点的label是否存在,不满足条件时返回503。PS:Master相关的状态检查不支持tag_key
其他Endpoint:
- GET /read-only
- GET /synchronous或者GET /sync:判断集群是否运行在synchronous状态
- GET /asynchronous或者GET /async:判断集群是否运行在asynchronous状态
- GET /asynchronous?lag=
:类似GET /replica?lag= - GET /health:PostgreSQL是否启动并运行
- GET /liveness:Patroni启动并运行
- GET /readiness:Patroni 节点作为领导者运行或 PostgreSQL 启动并运行时,返回 HTTP 状态代码 200。
2. 监控相关
Patroni虽然提供比较丰富的监控信息采集接口,但是其返回结果是json格式的,Promethues无法直接scrap。
为了和Promethues更好适配,官方提供了metrics端点,但是能获取的信息有限。
第三方服务:patroni-exporter
官方返回JSON采集信息的API参考:https://patroni.readthedocs.io/en/latest/rest_api.html#config-endpoint
3. 控制面API
主备切换
API允许通过leader/candidate参数,将将节点配置切换为Master/Replicas,包括:
POST /switchover:指定节点健康的状态下,Master立即/定时释放Lock, 下面请求中rccp-tiny-1是Master, 执行命令后rccp-tiny-1将释放Leader Lock。
|
|
不指定scheduled_at时,会生成一个同步请求立即发生切换。
|
|
立即释放leader,并且指定候选人为rccp-tiny-2,即rccp-tiny-1和rccp-tiny-2角色互换
|
|
通过DELETE /switchover可以清除节点切换调度。
POST /failover:允许执行手工立即执行一次主备切换,此时Master节点不是健康状态的。
|
|
Restart endpoint
POST /restart 可以用于重启Postgres服务,请求接受一个JSON Body参数如下:
- restart_pending:只有当PostgresSQL的配置文件变更,且需要重启生效时重启。
- role:指定重启的角色
- postgres_version:当postgres版本低于指定时才会重启
- timeout:请求被相应的超时时间
- schedule:重启调度时间
重启Master配置文件变更时重启Master节点:
|
|
Reload endpoint
- POST /reload:更新配置文件执行pg_ctl reload,相当于向 Patroni 进程发送 SIGHUP 信号。
- POST /reinitialize:只允许在replicas上执行,此时会删除节点的数据目录,并开始如pg_basebackup等类似操作。
Replication-modes
略
参考:https://patroni.readthedocs.io/en/latest/replication_modes.html#replication-modes
Watchdog
为了避免裂脑Patroni需要确保PostgreSQL在DCS中的Leader Lock过期后不会接受任何事务。在正常情况下,如果主备切换失败,Patroni会尝试通过停止PostgreSQL服务避免出现多个Master。
但是以下情况依然可能发生:
- Patroni意外退出
- PostgreSQL没有及时关闭
Patroni为了避免上述情况,提供了Watchdog能力。
Linux软件Watchdog:
Linux内核模块自带了watchdog实现,在程序通过/dev/watchdog设备与watchdog交互。 用户空间程序一旦打开/dev/watchdog,会导致在内核中启动一个1分钟的定时器(系统默认时间),此后用户空间程序需要保证在1分钟之内向这个设备写入数据,每次写操作会导致重新设定定时器。 如果用户空间程序在1分钟之内没有写操作,定时器到期会导致一次系统 reboot 操作。
相关配置如下:
|
|
当Patroni将节点提升为Master前,会同步启动该节点的watchdog。默认配置中,watchdog的投喂时间为5s
如果启动Master失败,并且watchdog.mode为required,那么该节点不能被升级成Master。当Patroni将Master降级时,会禁用该节点的watchdog。
参考:https://patroni.readthedocs.io/en/latest/watchdog.html
DCS为Kubernetes时,建议不要启动watchdog功能!
Pause/Resume
Patroni允许在维护场景下,暂时将PostgreSQL和Patroni分离,同时仍保留DCS中的集群状态再需要时重新接管PostgreSQL集群。
pause 命令:
|
|
resume 命令:
|
|
当Pause状态下,patroni的行为参考以下链接。
参考:https://patroni.readthedocs.io/en/latest/pause.html#the-implementation
参考
文章作者 yoaz
上次更新 2021-12-20
许可协议 MIT