citus实战系列之四多CN部署

简介: citus的架构中正常只有1个CN节点,有时候CN会成为性能瓶颈。我们可以通过减少分片数,垂直扩容CN节点等手段缓解CN的性能问题,但这些都不能治本。某些业务场景部署多个CN节点是非常必要的。

citus实战系列之四多CN部署

背景

citus的架构中正常只有1个CN节点,有时候CN会成为性能瓶颈。我们可以通过减少分片数,垂直扩容CN节点等手段缓解CN的性能问题,但这些都不能治本。某些业务场景部署多个CN节点是非常必要的。

技术方案

如果CN上主要的负载来自查询,可以为CN节点配置多个备机,做读写分离,这些备机可以分担读负载。但是这种方案不能称为多CN,它不具有均衡写负载的能力。

怎么实现多CN呢?在citus的具体实现中,CN和worker的区别就在于是否存储了相关的元数据,如果把CN的元数据拷贝一份到worker上,那么worker也可以向CN一样工作,这个多CN的模式早期被称做masterless。

对于当前的citus版本,其实有一个开关,打开后,会自动拷贝CN的元数据到Worker上,让worker也可以当CN用。 这个功能官方被称做Citus MX,也就是下一代的Citus,目前仅在Cloud Beta版中使用。好消息是,社区版虽然没有公开说支持,但也没有从代码上限制这个功能。下面见证一下这个神奇的开关:)

在CN节点的postgresql.conf中添加下面的参数

citus.replication_model='streaming'

在CN节点(cituscn)上添加worker节点

SELECT * from master_add_node('cituswk1', 5432);
SELECT * from master_add_node('cituswk2', 5432);

从CN复制元数据到第一个worker节点

SELECT start_metadata_sync_to_node('cituswk1', 5432);

执行上面的函数后,citus CN上的元数据会被拷贝到指定的worker上,并且pg_dist_node表中对应worker的hasmetadata字段值为true,标识这个Worker存储了元数据,以后创建新的分片时,新产生的元素据也会自动同步到这个worker上。

postgres=# select * from pg_dist_node;
 nodeid | groupid | nodename | nodeport | noderack | hasmetadata | isactive | noderole | nodecluster 
--------+---------+----------+----------+----------+-------------+----------+----------+-------------
      1 |       1 | cituswk1 |     5432 | default  | t           | t        | primary  | default
      2 |       2 | cituswk2 |     5432 | default  | f           | t        | primary  | default
(2 rows)

下面看一下效果

在CN节点上创建一个测试分片表

create table tb1(id int primary key, c1 int);
set citus.shard_count=8;
select create_distributed_table('tb1','id');
insert into tb1 select id,random()*1000 from generate_series(1,100)id;

因为cituswk1带了元数据,可以当CN用,下面这个SQL可以在cituswk1上执行。

postgres=# explain select * from tb1;
                                  QUERY PLAN                                  
------------------------------------------------------------------------------
 Custom Scan (Citus Real-Time)  (cost=0.00..0.00 rows=0 width=0)
   Task Count: 8
   Tasks Shown: One of 8
   ->  Task
         Node: host=cituswk1 port=5432 dbname=postgres
         ->  Seq Scan on tb1_102092 tb1  (cost=0.00..32.60 rows=2260 width=8)
(6 rows)

为了说明方便,后面把这种带了元数据的worker称之为“扩展worker”。citus会限制某些SQL在扩展worker上执行,比如DDL。

分片位置的控制

扩展Worker其实把Worker和CN两个角色混在一个节点里,对维护不是很友好。有下面几个表现:

  1. 扩展Worker上的负载可能不均衡
  2. 如果出现性能问题增加了故障排查的难度
  3. CN和Worker将不能独立扩容
  4. 扩大了插件兼容问题的影响
    一个例子是,当前citus的CN节点和auto_explain插件是冲突的,但Worker和auto_explain相安无视。一旦所有worker都作为扩展worker,那么所有的worker也都不能幸免。auto_explain插件只是我们在实际部署时遇到的一个例子,其它插件可能会有类似情况。

为解决这些问题,我们可以专门定义少数几个节点作为扩展Worker,并且不在上面分配分片,使其纯粹担任CN的角色。具体作法如下:

首先,按通常的方式建好分片表,再使用前面《citus实战系列之三平滑扩容》中介绍的方法把"扩展Worker"上的分片挪走。

对于前面tb1的例子,有4个分片落在扩展worker(worker1)上

postgres=# select * from pg_dist_shard_placement where nodename='cituswk1';
 shardid | shardstate | shardlength | nodename | nodeport | placementid 
---------+------------+-------------+----------+----------+-------------
  102238 |          1 |           0 | cituswk1 |     5432 |         237
  102240 |          1 |           0 | cituswk1 |     5432 |         239
  102242 |          1 |           0 | cituswk1 |     5432 |         241
  102244 |          1 |           0 | cituswk1 |     5432 |         243
(4 rows)

创建分片表

create table tba(id int);
set citus.shard_count=8;
select create_distributed_table('tba','id');

此时,有6个分片落在"扩展Worker"上。

postgres=# select * from pg_dist_shard_placement where nodename='cituswk1';
 shardid | shardstate | shardlength |  nodename  | nodeport | placementid 
---------+------------+-------------+------------+----------+-------------
  103081 |          1 |           0 |  cituswk1  |     5432 |        1096
  103083 |          1 |           0 |  cituswk1  |     5432 |        1099
  103085 |          1 |           0 |  cituswk1  |     5432 |        1102
  103097 |          1 |           0 |  cituswk1  |     5432 |        1105
(4 rows)

把"扩展Worker"上的分片挪走。

select citus_move_shard_placement(102238,'cituswk1',5432,'cituswk2',5432,'drop');
select citus_move_shard_placement(102240,'cituswk1',5432,'cituswk2',5432,'drop');
select citus_move_shard_placement(102242,'cituswk1',5432,'cituswk2',5432,'drop');
select citus_move_shard_placement(102244,'cituswk1',5432,'cituswk2',5432,'drop');

这是CN的元数据已经更新了,但扩展Worker(worker1)还没有,需要在扩展Worker(worker1)上更新分片位置

postgres=# update pg_dist_shard_placement set nodename='cituswk2' where shardid in (102238,102240,102242,102244);
UPDATE 4

先定义后迁移的方式不是特别方便,对于有亲和关系(分片位置分布完全一致)的表,只有第一张表需要这样定义,后续的表可以利用亲和关系指定分片的部署位置。

比如

create table tb2(id int);
select create_distributed_table('tb2','id', colocate_with=>'tb1');

上面的colocate_with有3种取值

  • default: 分配数,副本数,分片字段类型相同的表自动分配到一个亲和组
  • none:开始一个新的亲和组
  • 表名:希望与之亲和的另一个表的表名

注意事项

稳妥起见,在扩展worker上尽量避免会产生分布式事务或死锁的操作。建议只执行这几类SQL,并且不使用事务。

  • SELECT
  • INSERT
  • 条件中带分片字段的SQL
相关文章
|
前端开发 Serverless UED
iconfont渐变色实现方案总结
iconfont渐变色实现方案总结
1216 0
|
缓存 Shell Linux
【Shell 命令集合 链接器(linker)工具】Linux ld命令 将目标文件与库链接为可执行文件或库文件
【Shell 命令集合 链接器(linker)工具】Linux ld命令 将目标文件与库链接为可执行文件或库文件
856 0
|
Java Spring
Spring Cloud OpenFeign 远程调用传递请求头信息
import feign.RequestInterceptor; import feign.RequestTemplate; import lombok.extern.slf4j.Slf4j; import org.springframework.util.Assert; import org.springframework.web.context.request.RequestContextHolder; import org.springframework.web.context.request.ServletRequestAttributes;
703 0
|
7月前
|
存储 数据挖掘 关系型数据库
更高效的数据处理解决方案:基于 MinIO 部署 Apache Doris 存算分离版本实践
现代数据处理在多维度面临严峻挑战,一方面,数据量的持续增长致使传统存储成本居高不下,非结构化数据所占比例日益攀升,进一步加重了存储负担,且数据质量问题推高了存储和清洗成本;另一方面,企业内部往往存在多套系统,数据难以集成,这对数据分析的成本和时效性也提出了更高的要求。Apache Doris 作为一款具备高性能的实时分析数据库,拥有湖仓一体的能力。当它与 MinIO 这样高性能且 S3 兼容的对象存储系统相结合时,能够构建出一个高效且具备低成本特性的数据分析系统。本文将介绍基于 Apache Doris 和 MinIO 的存算分离部署教程与使用实践。
690 0
|
12月前
|
存储 关系型数据库 分布式数据库
【赵渝强老师】基于PostgreSQL的分布式数据库:Citus
Citus 是基于 PostgreSQL 的开源分布式数据库,采用 shared nothing 架构,具备良好的扩展性。它以插件形式集成,部署简单,适用于处理大规模数据和高并发场景。本文介绍了 Citus 的基础概念、安装配置步骤及其在单机环境下的集群搭建方法。
991 2
|
SQL 存储 运维
从Citus深度解密如何基于PostgreSQL做分布式数据库
从源码级别揭秘Citus如何基于PostgreSQL做一款分布式数据库,解决分布式场景的数据分片、分布式SQL、分布式事务、数据倾斜、数据迁移等难点问题,理解分布式领域设计的“取”与“舍”。
3131 3
从Citus深度解密如何基于PostgreSQL做分布式数据库
|
SQL 存储 关系型数据库
Citus 多CN部署与Citus MX
Citus MX是Citus集群中横向扩展CN能力的技术,本文件聊一下Citus MX使用的话题
2969 140
|
JSON JavaScript 数据格式
【深入探究C++ JSON库】解析JSON元素的层级管理与遍历手段
【深入探究C++ JSON库】解析JSON元素的层级管理与遍历手段
2866 2
|
开发工具 git
ROS 环境下 安装 turtlebot3 功能包及其仿真包 并测试 —— 全流程(报错及解决)
ROS 环境下 安装 turtlebot3 功能包及其仿真包 并测试 —— 全流程(报错及解决)
ROS 环境下 安装 turtlebot3 功能包及其仿真包 并测试   —— 全流程(报错及解决)
|
SQL 关系型数据库 分布式数据库
从Citus深度解密如何基于PostgreSQL做分布式数据库
前言分布式数据库能够解决海量数据存储、超高并发吞吐、大表瓶颈以及复杂计算效率等单机数据库瓶颈难题,当业务体量即将突破单机数据库承载极限和单表过大导致性能、维护问题时,分布式数据库是解决上述问题的高性价比方案。数据库作为分布式改造的最大难点,就是"和使用单机数据库一样使用分布式数据库",这也一直是广大...
6242 0
从Citus深度解密如何基于PostgreSQL做分布式数据库