在 Kubernetes 上快速测试 Citus 分布式 PostgreSQL 集群(分布式表,共置,引用表,列存储)

简介: 在 Kubernetes 上快速测试 Citus 分布式 PostgreSQL 集群(分布式表,共置,引用表,列存储)

 准备工作



这里假设,你已经在 k8s 上部署好了基于 Citus 扩展的分布式 PostgreSQL 集群。

查看 Citus 集群(kubectl get po -n citus),1Coordinator(协调器) 节点 +3Worker(工作器) 节点。


NAME                  READY   STATUS    RESTARTS   AGE
citus-coordinator-0   2/2     Running   0          3h55m
citus-worker-0        2/2     Running   0          22m
citus-worker-1        2/2     Running   0          21m
citus-worker-2        2/2     Running   0          21m


进入 coordinator 节点(kubectl -n citus exec -it citus-coordinator-0 -- bash),查看活动的 worker 节点(psql 'host=citus-coordinator user=postgres' -c "SELECT * FROM citus_get_active_worker_nodes();")。



node_name                      | node_port 
-----------------------------------------------------+-----------
 citus-worker-1.citus-worker.citus.svc.cluster.local |      6432
 citus-worker-2.citus-worker.citus.svc.cluster.local |      6432
 citus-worker-0.citus-worker.citus.svc.cluster.local |      6432
(3 rows)


一旦拥有 Citus 集群,就可以开始创建分布式表引用表和使用列存储


 创建分布式表



create_distributed_table 将在本地或工作节点之间透明地切分您的表。

进入命令行工具:psql 'host=citus-coordinator user=postgres'

建表


CREATE TABLE events (
  device_id bigint,
  event_id bigserial,
  event_time timestamptz default now(),
  data jsonb not null,
  PRIMARY KEY (device_id, event_id)
);
-- 将事件表分布在本地或工作节点上的分片上
SELECT create_distributed_table('events', 'device_id');


执行此操作后,对特定设备 ID 的查询将有效地路由到单个工作节点,而跨设备 ID 的查询将在集群中并行化。


插入一些事件


INSERT INTO events (device_id, data)
SELECT s % 100, ('{"measurement":'||random()||'}')::jsonb FROM generate_series(1,1000000) s;
-- INSERT 0 1000000


获取设备 1 的最后 3 个事件,路由到单个节点

命令行开启计时:postgres=# \timing


SELECT * FROM events WHERE device_id = 1 ORDER BY event_time DESC, event_id DESC LIMIT 3;


device_id | event_id |          event_time           |                data                 
-----------+----------+-------------------------------+-------------------------------------
         1 |   999901 | 2022-03-24 02:30:50.205478+00 | {"measurement": 0.8822990134507691}
         1 |   999801 | 2022-03-24 02:30:50.205478+00 | {"measurement": 0.5239176115816448}
         1 |   999701 | 2022-03-24 02:30:50.205478+00 | {"measurement": 0.9900647926398349}
(3 rows)
Time: 4.779 ms


解释跨分片并行化的查询的计划,以下显示了查询其中一个分片的计划以及如何完成跨分片的聚合

执行 sql 语句:


EXPLAIN (VERBOSE ON) SELECT count(*) FROM events;


QUERY PLAN                                                
---------------------------------------------------------------------------------------------------------
 Aggregate  (cost=250.00..250.02 rows=1 width=8)
   Output: COALESCE((pg_catalog.sum(remote_scan.count))::bigint, '0'::bigint)
   ->  Custom Scan (Citus Adaptive)  (cost=0.00..0.00 rows=100000 width=8)
         Output: remote_scan.count
         Task Count: 32
         Tasks Shown: One of 32
         ->  Task
               Query: SELECT count(*) AS count FROM public.events_102008 events WHERE true
               Node: host=citus-worker-0.citus-worker.citus.svc.cluster.local port=6432 dbname=postgres
               ->  Aggregate  (cost=725.00..725.01 rows=1 width=8)
                     Output: count(*)
                     ->  Seq Scan on public.events_102008 events  (cost=0.00..650.00 rows=30000 width=0)
                           Output: device_id, event_id, event_time, data
(13 rows)
Time: 5.427 ms


 使用共置创建分布式表


具有相同分布列的分布式表可以位于同一位置,以实现分布式表之间的高性能分布式连接(join)和外键。默认情况下,分布式表将根据分布列的类型位于同一位置,但您可以使用 create_distributed_table 中的 colocate_with 参数显式定义同一位置。

建表


CREATE TABLE devices (
  device_id bigint primary key,
  device_name text,
  device_type_id int
);
CREATE INDEX ON devices (device_type_id);
-- 将设备表与事件表放在一起
SELECT create_distributed_table('devices', 'device_id', colocate_with := 'events');


插入设备元数据


INSERT INTO devices (device_id, device_name, device_type_id)
SELECT s, 'device-'||s, 55 FROM generate_series(0, 99) s;


可选:确保应用程序只能插入已知设备的事件


ALTER TABLE events ADD CONSTRAINT device_id_fk
FOREIGN KEY (device_id) REFERENCES devices (device_id);


获得跨分片并行的所有类型 55 设备的平均测量值


SELECT avg((data->>'measurement')::double precision)
FROM events JOIN devices USING (device_id)
WHERE device_type_id = 55;


avg         
--------------------
 0.4997412230952178
(1 row)
Time: 122.548 ms


Co-location 还可以帮助您扩展 INSERT..SELECT、存储过程和分布式事务。


  • INSERT..SELECT
  • 存储过程
  • 分布式事务


 创建引用表


当您需要不包含分布列的快速 join 或外键时,您可以使用 create_reference_table 在集群中的所有节点之间复制表。

建表


CREATE TABLE device_types (
  device_type_id int primary key,
  device_type_name text not null unique
);


跨所有节点复制表以在任何列上启用外键和 join


SELECT create_reference_table('device_types');


插入设备类型


INSERT INTO device_types (device_type_id, device_type_name) VALUES (55, 'laptop');


可选:确保应用程序只能插入已知类型的设备


ALTER TABLE devices ADD CONSTRAINT device_type_fk
FOREIGN KEY (device_type_id) REFERENCES device_types (device_type_id);


获取类型名称以笔记本电脑开头的设备的最后 3 个事件,跨分片并行


SELECT device_id, event_time, data->>'measurement' AS value, device_name, device_type_name
FROM events JOIN devices USING (device_id) JOIN device_types USING (device_type_id)
WHERE device_type_name LIKE 'laptop%' ORDER BY event_time DESC LIMIT 3;


device_id |          event_time           |        value        | device_name | device_type_name 
-----------+-------------------------------+---------------------+-------------+------------------
        31 | 2022-03-24 02:30:50.205478+00 | 0.9994211581289107  | device-31   | laptop
        31 | 2022-03-24 02:30:50.205478+00 | 0.13771543211483106 | device-31   | laptop
        88 | 2022-03-24 02:30:50.205478+00 | 0.5585740912470349  | device-88   | laptop
(3 rows)
Time: 96.537 ms


引用表使您能够扩展复杂的数据模型并充分利用关系数据库的功能。


 使用列式存储创建表


要在 PostgreSQL 数据库中使用列式存储,您只需将 USING columnar 添加到 CREATE TABLE 语句中,您的数据将使用列式访问方法自动压缩。


建表


CREATE TABLE events_columnar (
  device_id bigint,
  event_id bigserial,
  event_time timestamptz default now(),
  data jsonb not null
)
USING columnar;


插入一些数据


INSERT INTO events_columnar (device_id, data)
SELECT d, '{"hello":"columnar"}' FROM generate_series(1,10000000) d;


创建一个基于行的表进行比较


CREATE TABLE events_row AS SELECT * FROM events_columnar;


查看表大小


postgres=# \d+
                                                  List of relations
 Schema |             Name             |   Type   |  Owner   | Persistence | Access method |    Size    | Description 
--------+------------------------------+----------+----------+-------------+---------------+------------+-------------
 public | citus_tables                 | view     | postgres | permanent   |               | 0 bytes    | 
 public | device_types                 | table    | postgres | permanent   | heap          | 8192 bytes | 
 public | devices                      | table    | postgres | permanent   | heap          | 8192 bytes | 
 public | events                       | table    | postgres | permanent   | heap          | 8192 bytes | 
 public | events_columnar              | table    | postgres | permanent   | columnar      | 25 MB      | 
 public | events_columnar_event_id_seq | sequence | postgres | permanent   |               | 8192 bytes | 
 public | events_event_id_seq          | sequence | postgres | permanent   |               | 8192 bytes | 
 public | events_row                   | table    | postgres | permanent   | heap          | 806 MB     | 
(8 rows)


注意 events_row(806 MB)events_columnar(25 MB) 的对比。压缩了几十倍,效果非常的惊人,大大节省了存储空间。


您可以单独使用列存储,也可以在分布式表中使用,以结合压缩和分布式查询引擎的优势。


使用列式存储时,您应该只使用 COPYINSERT..SELECT 批量加载数据以实现良好的压缩。柱状表目前不支持更新、删除和外键。但是,您可以使用分区表,其中较新的分区使用基于行的存储,而较旧的分区使用列存储进行压缩。

相关实践学习
深入解析Docker容器化技术
Docker是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化,容器是完全使用沙箱机制,相互之间不会有任何接口。Docker是世界领先的软件容器平台。开发人员利用Docker可以消除协作编码时“在我的机器上可正常工作”的问题。运维人员利用Docker可以在隔离容器中并行运行和管理应用,获得更好的计算密度。企业利用Docker可以构建敏捷的软件交付管道,以更快的速度、更高的安全性和可靠的信誉为Linux和Windows Server应用发布新功能。 在本套课程中,我们将全面的讲解Docker技术栈,从环境安装到容器、镜像操作以及生产环境如何部署开发的微服务应用。本课程由黑马程序员提供。     相关的阿里云产品:容器服务 ACK 容器服务 Kubernetes 版(简称 ACK)提供高性能可伸缩的容器应用管理能力,支持企业级容器化应用的全生命周期管理。整合阿里云虚拟化、存储、网络和安全能力,打造云端最佳容器化应用运行环境。 了解产品详情: https://www.aliyun.com/product/kubernetes
相关文章
|
Kubernetes Cloud Native 网络安全
云原生|kubernetes|CKA模拟测试-2022(1---10题)(一)
云原生|kubernetes|CKA模拟测试-2022(1---10题)(一)
441 0
|
存储 关系型数据库 数据库
【赵渝强老师】PostgreSQL的逻辑存储结构
PostgreSQL的逻辑存储结构包括数据库集群、数据库、表空间、段、区、块等。每个对象都有唯一的对象标识符OID,并存储于相应的系统目录表中。集群由单个服务器实例管理,包含多个数据库、用户及对象。表空间是数据库的逻辑存储单元,用于组织逻辑相关的数据结构。段是分配给表、索引等逻辑结构的空间集合,区是段的基本组成单位,而块则是最小的逻辑存储单位。
530 2
【赵渝强老师】PostgreSQL的逻辑存储结构
|
关系型数据库 分布式数据库 数据库
PostgreSQL+Citus分布式数据库
PostgreSQL+Citus分布式数据库
730 15
|
Kubernetes Go API
|
存储 SQL 关系型数据库
【赵渝强老师】PostgreSQL的物理存储结构
PostgreSQL在初始化时通过环境变量$PGDATA指定的目录下生成各类文件,构成其物理存储结构,包括数据文件、日志文件(如运行日志、WAL预写日志、事务日志和服务器日志)、控制文件及参数文件等,确保数据库的高效运行与数据安全。
551 1
|
Kubernetes Linux API
CentOS 7.6使用kubeadm部署k8s 1.17.2测试集群实战篇
该博客文章详细介绍了在CentOS 7.6操作系统上使用kubeadm工具部署kubernetes 1.17.2版本的测试集群的过程,包括主机环境准备、安装Docker、配置kubelet、初始化集群、添加节点、部署网络插件以及配置k8s node节点管理api server服务器。
740 0
CentOS 7.6使用kubeadm部署k8s 1.17.2测试集群实战篇
|
缓存 NoSQL Ubuntu
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
大数据-39 Redis 高并发分布式缓存 Ubuntu源码编译安装 云服务器 启动并测试 redis-server redis-cli
321 3
|
存储 数据采集 分布式计算
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
Hadoop-17 Flume 介绍与环境配置 实机云服务器测试 分布式日志信息收集 海量数据 实时采集引擎 Source Channel Sink 串行复制负载均衡
380 1
|
关系型数据库 MySQL 数据库
测试部署PolarDB-X 分布式与集中式
在本文中,作者详述了在CentOS 7.9上部署测试PolarDB-X分布式与集中式数据库的过程。PolarDB-X作为阿里云优化的分布式数据库,提供高稳定性和与MySQL的兼容性,是应对单体数据库扩展性和性能瓶颈的解决方案,同时也符合国产化需求。文章介绍了部署环境准备,包括关闭防火墙和SELinux,设置系统参数,安装Python3和Docker,以及配置MySQL客户端。接着,通过PXD工具部署了PolarDB-X的集中式和分布式版,遇到的问题包括阿里云镜像源异常导致的部署失败以及指定版本安装的困扰。最后,作者进行了初步的压力测试,并对文档完善、生态工具建设以及提供更多使用案例提出了建议。
49119 10
测试部署PolarDB-X 分布式与集中式
|
资源调度 Java 调度
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决
339 0
项目环境测试问题之Schedulerx2.0通过分布式分片任务解决单机计算瓶颈如何解决