PostgreSQL分布式架构之——PL/Proxy

本文涉及的产品
云原生数据库 PolarDB MySQL 版,通用型 2核8GB 50GB
云原生数据库 PolarDB PostgreSQL 版,标准版 2核4GB 50GB
简介:

PostgreSQL分布式架构之——PL/Proxy

  1. PL/Proxy的介绍
    1.1 PL/Proxy概述

  PL/Proxy是一款能在PostgreSQL数据库实现数据库水平拆分的软件;可以理解分布式架构(shared nothing);但是不是真正的分布式数据库软件;也是一款能在PostgreSQL数据库实现SQL语言复制(replication)
  分布式架构图如下:

1.2 PL/Proxy集群配置

  PL/Proxy既能配置成“CONNECT”模式又能配置成“CLUSTER”模式

在"CONNECT"模式中;PL/Proxy直接把请求路由(run on n)到指定的数据库。
在"CLUSTER"模式中;PL/Proxy可以支持数据水平分区,即shared nothing。也可以实现SQL语言复制(run on all)。
  在配置“CLUSTER”模式有两种方式:

集群configuration API
SQL/MED
1.3 PL/Proxy特性介绍

PL/Proxy把需要对数据库SQL访问转换为对PostgreSQL函数调用。
PL/Proxy后端数据库节点数必须是2的N次方。

  1. PL/Proxy安装
    2.1 编译安装

  执行“source /home/postgres/.bashrc”加载环境变量;目的确保来自postgresql bin目录的pgconfig在您的路径中

tar -zxvf plproxy-2.7.tar.gz
cd plproxy-2.7
source /home/postgres/.bashrc
make
make install
2.2 创建PL/Proxy扩展

  在这里我选“proxy”数据库作为路由代理数据库。

复制代码
[postgres@Postgres201 ~]$ psql
psql (9.6.0)
Type "help" for help.

postgres=# create database proxy;
CREATE DATABASE
postgres=# c proxy
You are now connected to database "proxy" as user "postgres".
proxy=# create extension plproxy;
CREATE EXTENSION
proxy=# dx

                           List of installed extensions
Name Version Schema Description
plpgsql 1.0 pg_catalog PL/pgSQL procedural language
plproxy 2.7.0 public Database partitioning implemented as procedural language

(2 rows)
复制代码

  1. PL/Proxy的配置
      本实验的配置环境如下:

主机名 IP 角色 数据库名 用户
PostgreSQL201 192.168.1.201 proxy node proxy lottu
PostgreSQL202 192.168.1.202 data node pl_db0 lottu
PostgreSQL202 192.168.1.202 data node pl_db1 lottu
PostgreSQL202 192.168.1.202 data node pl_db2 lottu
PostgreSQL202 192.168.1.202 data node pl_db3 lottu

  修改数据节点的pg_hba.conf

要确保PL/Proxy节点能访问所有数据库。
host all all 192.168.1.0/24 trust
当然在线上数据库大家可以这样配置,例如:
host all lottu 192.168.1.201/24 md5
  采用SQL/MED方式配置集群【在PL/Proxy节点操作】
  创建一个使用plproxy FDW的服务器来完成的。服务器的选项是PL/Proxy配置设置和集群分区列表。

复制代码
[postgres@Postgres201 ~]$ psql proxy lottu
psql (9.6.0)
Type "help" for help.

proxy=# c
You are now connected to database "proxy" as user "lottu".
proxy=# CREATE SERVER cluster_srv1 FOREIGN DATA WRAPPER plproxy
proxy-# OPTIONS (
proxy(# connection_lifetime '1800',
proxy(# disable_binary '1',
proxy(# p0 'dbname=pl_db0 host=192.168.1.202',
proxy(# p1 'dbname=pl_db1 host=192.168.1.202',
proxy(# p2 'dbname=pl_db2 host=192.168.1.202',
proxy(# p3 'dbname=pl_db3 host=192.168.1.202'
proxy(# );
CREATE SERVER
proxy=# des

       List of foreign servers
 Name     | Owner | Foreign-data wrapper 
cluster_srv1 lottu plproxy

(1 row)

proxy=# grant usage on FOREIGN server cluster_srv1 to lottu;
GRANT

创建用户映射

proxy=# create user mapping for lottu server cluster_srv1 options (user 'lottu');
CREATE USER MAPPING
proxy=# deu
List of user mappings

Server    | User name 
cluster_srv1 lottu

(1 row)
复制代码
  配置完成!在"CLUSTER"模式中;才需要上述配置;在"CONNECT"模式中是不需要的。

  1. PL/Proxy测试
      PL/Proxy把需要对数据库SQL访问转换为对PostgreSQL函数调用;这就需要使用者有良好的编程功底。

  在数据节点创建测试样本表

create table users(userid int, name text);
4.1 "CLUSTER"模式测试

4.1.1 数据水平拆分测试

在每个数据节点创建insert函数接口
复制代码
pl_db0=> CREATE OR REPLACE FUNCTION insert_user(i_id int, i_name text)
pl_db0-> RETURNS integer AS

$$ pl_db0$> INSERT INTO users (userid, name) VALUES ($1,$2); pl_db0$> SELECT 1; pl_db0$> $$

LANGUAGE SQL;
CREATE FUNCTION
复制代码
在PL/Proxy数据库创建同名的insert函数接口
复制代码
proxy=# CREATE OR REPLACE FUNCTION insert_user(i_id int, i_name text)
proxy-# RETURNS integer AS

$$ proxy$# CLUSTER 'cluster_srv1'; proxy$# RUN ON ANY; proxy$# $$

LANGUAGE plproxy;
CREATE FUNCTION
复制代码
  为什么要同名的函数呢?若不是同名的话;需要在函数里面添加一个"TRAGET INSERT_USER";表明从数据节点调用函数"INSERT_USER"。

在PL/Proxy数据库创建读的函数get_user_name()
复制代码
proxy=# CREATE OR REPLACE FUNCTION get_user_name()
RETURNS TABLE(userid int, name text) AS

$$ CLUSTER 'cluster_srv1'; RUN ON ALL ; SELECT userid,name FROM users; $$

LANGUAGE plproxy;
CREATE FUNCTION
复制代码
  Ok;现在函数接口开发完成;我现在来调用函数插入10条记录

复制代码
SELECT insert_user(1001, 'Sven');
SELECT insert_user(1002, 'Marko');
SELECT insert_user(1003, 'Steve');
SELECT insert_user(1004, 'lottu');
SELECT insert_user(1005, 'rax');
SELECT insert_user(1006, 'ak');
SELECT insert_user(1007, 'jack');
SELECT insert_user(1008, 'molica');
SELECT insert_user(1009, 'pg');
SELECT insert_user(1010, 'oracle');
复制代码
  由于函数执行的是"RUN ON ANY";表明插入数据是随机选取数据节点。我们看看每个数据节点的数据。

复制代码
pl_db0=> select * from users;

userid name
1005 rax
1006 ak
1008 molica
1009 pg

(4 rows)

pl_db1=> select * from users;

userid name
1002 Marko
1004 lottu

(2 rows)

pl_db2=> select * from users;

userid name
1007 jack
1010 oracle

(2 rows)

pl_db3=> select * from users;

userid name
1001 Sven
1003 Steve

(2 rows)
复制代码
  可以看出10条数据已经切分到每个数据节点。(10条取样太少,导致数据不均匀)。我们在proxy节点查询下。

复制代码
proxy=# SELECT USERID,NAME FROM GET_USER_NAME();

userid name
1005 rax
1006 ak
1008 molica
1009 pg
1002 Marko
1004 lottu
1007 jack
1010 oracle
1001 Sven
1003 Steve

(10 rows)
复制代码
4.1.2数据复制(replication)测试

选择users表作为实验对象;我们先清理表users数据;在数据节点创建truncatet函数接口
复制代码
pl_db0=> CREATE OR REPLACE FUNCTION trunc_user()
pl_db0-> RETURNS integer AS

$$ pl_db0$> truncate table users; pl_db0$> SELECT 1; pl_db0$> $$

LANGUAGE SQL;
CREATE FUNCTION
复制代码
在PL/Proxy数据库创建同名的truncate函数接口
复制代码
proxy=# CREATE OR REPLACE FUNCTION trunc_user()
proxy-# RETURNS SETOF integer AS

$$ proxy$# CLUSTER 'cluster_srv1'; proxy$# RUN ON ALL; proxy$# $$

LANGUAGE plproxy;
CREATE FUNCTION
复制代码
执行之后trunc_user();数据已经清理了。
复制代码
proxy=# SELECT TRUNC_USER();

trunc_user

      1
      1
      1
      1

(4 rows)
复制代码
  其实在这里我们已经验证数据复制(replication)测试。为了更好解释;我们选择insert函数接口来。

在PL/Proxy数据库创建函数接口 insert_user_2
复制代码
proxy=# CREATE OR REPLACE FUNCTION insert_user_2(i_id int, i_name text)
proxy-# RETURNS SETOF integer AS

$$ proxy$# CLUSTER 'cluster_srv1'; proxy$# RUN ON ALL; proxy$# TARGET insert_user; proxy$# $$

LANGUAGE plproxy;
CREATE FUNCTION
复制代码
  我们选择这几条语句

proxy=# SELECT insert_user_2(1004, 'lottu');
proxy=# SELECT insert_user_2(1005, 'rax');
proxy=# SELECT insert_user_2(1006, 'ak');
proxy=# SELECT insert_user_2(1007, 'jack');
我们看看每个数据节点的数据。
复制代码
pl_db0=> select * from users;

userid name
1004 lottu
1005 rax
1006 ak
1007 jack

(4 rows)

pl_db1=> select * from users;

userid name
1004 lottu
1005 rax
1006 ak
1007 jack

(4 rows)

pl_db2=> select * from users;

userid name
1004 lottu
1005 rax
1006 ak
1007 jack

(4 rows)

pl_db3=> select * from users;

userid name
1004 lottu
1005 rax
1006 ak
1007 jack

(4 rows)
复制代码
  每个节点的数据都是一样的。完成了数据复制(replication)测试。

我们在proxy节点查询下。只要在任意数据节点读取数据即可;我们先编辑函数。
复制代码
proxy=# CREATE OR REPLACE FUNCTION get_user_name_2()
proxy-# RETURNS TABLE(userid int, name text) AS

$$ proxy$# CLUSTER 'cluster_srv1'; proxy$# RUN ON ANY ; proxy$# SELECT userid,name FROM users; proxy$# $$

LANGUAGE plproxy;
CREATE FUNCTION
proxy=# SELECT USERID,NAME FROM GET_USER_NAME_2();

userid name
1004 lottu
1005 rax
1006 ak
1007 jack

(4 rows)
复制代码
4.2 "CONNECT"模式测试

  使用"CONNECT"模式;PL/Proxy不需要上述的配置;直接使用即可。

复制代码
proxy=# CREATE OR REPLACE FUNCTION get_user_name_3()
proxy-# RETURNS TABLE(userid int, name text) AS

$$ proxy$# CONNECT 'dbname=pl_db0 host=192.168.1.202'; proxy$# CONNECT 'dbname=pl_db1 host=192.168.1.202'; proxy$# SELECT userid,name FROM users; proxy$# $$

LANGUAGE plproxy;
ERROR: PL/Proxy function lottu.get_user_name_3(0): Compile error at line 3: Only one CONNECT statement allowed
proxy=# CREATE OR REPLACE FUNCTION get_user_name_3()
proxy-# RETURNS TABLE(userid int, name text) AS

$$ proxy$# CONNECT 'dbname=pl_db0 host=192.168.1.202'; proxy$# SELECT userid,name FROM users; proxy$# $$

LANGUAGE plproxy;
CREATE FUNCTION
proxy=# SELECT USERID,NAME FROM GET_USER_NAME_3();

userid name
1004 lottu
1005 rax
1006 ak
1007 jack

(4 rows)
复制代码
  只允许一个“CONNECT statement”;用法很简单;作用很鸡肋。

  1. 总结
      PL/Proxy的语法本文差不多都涉及到了。至于通过“集群configuration API”方式配置集群,本文不讲解了;其实配置也很简单。
  2. 参考文档
      https://yq.aliyun.com/articles/59372?spm=a2c4e.11153940.blogcont59345.17.46039916yDaqtq
相关实践学习
使用PolarDB和ECS搭建门户网站
本场景主要介绍如何基于PolarDB和ECS实现搭建门户网站。
阿里云数据库产品家族及特性
阿里云智能数据库产品团队一直致力于不断健全产品体系,提升产品性能,打磨产品功能,从而帮助客户实现更加极致的弹性能力、具备更强的扩展能力、并利用云设施进一步降低企业成本。以云原生+分布式为核心技术抓手,打造以自研的在线事务型(OLTP)数据库Polar DB和在线分析型(OLAP)数据库Analytic DB为代表的新一代企业级云原生数据库产品体系, 结合NoSQL数据库、数据库生态工具、云原生智能化数据库管控平台,为阿里巴巴经济体以及各个行业的企业客户和开发者提供从公共云到混合云再到私有云的完整解决方案,提供基于云基础设施进行数据从处理、到存储、再到计算与分析的一体化解决方案。本节课带你了解阿里云数据库产品家族及特性。
相关文章
|
4月前
|
监控 Linux 应用服务中间件
Linux多节点多硬盘部署MinIO:分布式MinIO集群部署指南搭建高可用架构实践
通过以上步骤,已成功基于已有的 MinIO 服务,扩展为一个 MinIO 集群。该集群具有高可用性和容错性,适合生产环境使用。如果有任何问题,请检查日志或参考MinIO 官方文档。作者联系方式vx:2743642415。
1240 57
|
8月前
|
存储 缓存 NoSQL
分布式系统架构8:分布式缓存
本文介绍了分布式缓存的理论知识及Redis集群的应用,探讨了AP与CP的区别,Redis作为AP系统具备高性能和高可用性但不保证强一致性。文章还讲解了透明多级缓存(TMC)的概念及其优缺点,并详细分析了memcached和Redis的分布式实现方案。此外,针对缓存穿透、击穿、雪崩和污染等常见问题提供了应对策略,强调了Cache Aside模式在解决数据一致性方面的作用。最后指出,面试中关于缓存的问题多围绕Redis展开,建议深入学习相关知识点。
579 8
|
4月前
|
消息中间件 缓存 算法
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
226 0
分布式开发:数字时代的高性能架构革命-为什么要用分布式?优雅草卓伊凡
|
6月前
|
并行计算 PyTorch 算法框架/工具
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
本文探讨了如何通过技术手段混合使用AMD与NVIDIA GPU集群以支持PyTorch分布式训练。面对CUDA与ROCm框架互操作性不足的问题,文章提出利用UCC和UCX等统一通信框架实现高效数据传输,并在异构Kubernetes集群中部署任务。通过解决轻度与强度异构环境下的挑战,如计算能力不平衡、内存容量差异及通信性能优化,文章展示了如何无需重构代码即可充分利用异构硬件资源。尽管存在RDMA验证不足、通信性能次优等局限性,但该方案为最大化GPU资源利用率、降低供应商锁定提供了可行路径。源代码已公开,供读者参考实践。
455 3
融合AMD与NVIDIA GPU集群的MLOps:异构计算环境中的分布式训练架构实践
|
12月前
|
安全 应用服务中间件 API
微服务分布式系统架构之zookeeper与dubbo-2
微服务分布式系统架构之zookeeper与dubbo-2
|
12月前
|
负载均衡 Java 应用服务中间件
微服务分布式系统架构之zookeeper与dubbor-1
微服务分布式系统架构之zookeeper与dubbor-1
|
6月前
|
人工智能 运维 监控
领先AI企业经验谈:探究AI分布式推理网络架构实践
当前,AI行业正处于快速发展的关键时期。继DeepSeek大放异彩之后,又一款备受瞩目的AI智能体产品Manus横空出世。Manus具备独立思考、规划和执行复杂任务的能力,其多智能体架构能够自主调用工具。在GAIA基准测试中,Manus的性能超越了OpenAI同层次的大模型,展现出卓越的技术实力。
|
8月前
|
存储 Prometheus Cloud Native
分布式系统架构6:链路追踪
本文深入探讨了分布式系统中的链路追踪理论,涵盖追踪与跨度的概念、追踪系统的模块划分及数据收集的三种方式。链路追踪旨在解决复杂分布式系统中请求流转路径不清晰的问题,帮助快速定位故障和性能瓶颈。文中介绍了基于日志、服务探针和边车代理的数据收集方法,并简述了OpenTracing、OpenCensus和OpenTelemetry等链路追踪协议的发展历程及其特点。通过理解这些概念,可以更好地掌握开源链路追踪框架的使用。
658 41
|
8月前
|
存储 缓存 安全
分布式系统架构7:本地缓存
这是小卷关于分布式系统架构学习的第10篇文章,主要介绍本地缓存的基础理论。文章分析了引入缓存的利弊,解释了缓存对CPU和I/O压力的缓解作用,并讨论了缓存的吞吐量、命中率、淘汰策略等属性。同时,对比了几种常见的本地缓存工具(如ConcurrentHashMap、Ehcache、Guava Cache和Caffeine),详细介绍了它们的访问控制、淘汰策略及扩展功能。
194 6
|
8月前
|
存储 关系型数据库 分布式数据库
[PolarDB实操课] 01.PolarDB分布式版架构介绍
《PolarDB实操课》之“PolarDB分布式版架构介绍”由阿里云架构师王江颖主讲。课程涵盖PolarDB-X的分布式架构、典型业务场景(如实时交易、海量数据存储等)、分布式焦点问题(如业务连续性、一致性保障等)及技术架构详解。PolarDB-X基于Share-Nothing架构,支持HTAP能力,具备高可用性和容错性,适用于多种分布式改造和迁移场景。课程链接:[https://developer.aliyun.com/live/253957](https://developer.aliyun.com/live/253957)。更多内容可访问阿里云培训中心。
200 0
[PolarDB实操课] 01.PolarDB分布式版架构介绍

热门文章

最新文章

推荐镜像

更多