多租户应用程序

在本教程中,我们将使用示例广告分析数据集来演示如何使用 Citus 来支持您的多租户应用程序。

注意

本教程假设您已经安装并运行了 Citus。 如果您没有运行 Citus,则可以使用单节点 Citus 中的选项之一在本地设置 Citus

https://docs.citusdata.com/en/v10.2/installation/single_node.html#development

数据模型和示例数据

我们将演示为广告分析应用程序构建数据库,公司可以使用该应用程序来查看、更改、分析和管理他们的广告和活动(请参阅示例应用程序)。这样的应用程序具有典型的多租户系统的良好特性。 来自不同租户的数据存储在一个中央数据库中,每个租户都有自己数据的独立视图。

我们将使用三个 Postgres 表来表示这些数据。 要开始使用,您需要下载这些表的示例数据:

curl https://examples.citusdata.com/tutorial/companies.csv > companies.csv
curl https://examples.citusdata.com/tutorial/campaigns.csv > campaigns.csv
curl https://examples.citusdata.com/tutorial/ads.csv > ads.csv

如果您使用 Docker,则应使用 docker cp 命令将文件复制到 Docker 容器中。

docker cp companies.csv citus:.
docker cp campaigns.csv citus:.
docker cp ads.csv citus:.

创建表

首先,您可以先使用 psql 连接到 Citus coordinator

如果您使用原生 Postgres,如我们的单节点 Citus 指南中安装的那样,coordinator 节点将在端口 9700 上运行。

psql -p 9700

如果您使用 Docker,您可以通过使用 docker exec 命令运行 psql 进行连接:

docker exec -it citus_master psql -U postgres

然后,您可以使用标准 PostgreSQL CREATE TABLE 命令创建表。

CREATE TABLE companies (
id bigint NOT NULL,
name text NOT NULL,
image_url text,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
); CREATE TABLE campaigns (
id bigint NOT NULL,
company_id bigint NOT NULL,
name text NOT NULL,
cost_model text NOT NULL,
state text NOT NULL,
monthly_budget bigint,
blacklisted_site_urls text[],
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
); CREATE TABLE ads (
id bigint NOT NULL,
company_id bigint NOT NULL,
campaign_id bigint NOT NULL,
name text NOT NULL,
image_url text,
target_url text,
impressions_count bigint DEFAULT 0,
clicks_count bigint DEFAULT 0,
created_at timestamp without time zone NOT NULL,
updated_at timestamp without time zone NOT NULL
);

接下来,您可以像在 PostgreSQL 中一样在每个表上创建主键索引:

ALTER TABLE companies ADD PRIMARY KEY (id);
ALTER TABLE campaigns ADD PRIMARY KEY (id, company_id);
ALTER TABLE ads ADD PRIMARY KEY (id, company_id);

分布表和加载数据

我们现在将继续告诉 Citus 将这些表分布在集群中的不同节点上。为此,您可以运行 create_distributed_table 并指定要分片的表和要分片的列。在这种情况下,我们将对 company_id 上的所有表进行分片。

SELECT create_distributed_table('companies', 'id');
SELECT create_distributed_table('campaigns', 'company_id');
SELECT create_distributed_table('ads', 'company_id');

对公司标识符上的所有表进行分片允许 Citus 将表放在一起,并允许跨集群使用主键、外键和复杂连接等功能。您可以在此处了解有关此方法的好处的更多信息。

然后,您可以继续使用标准 PostgreSQL \COPY 命令将我们下载的数据加载到表中。 如果您将文件下载到其他位置,请确保指定正确的文件路径。

\copy companies from 'companies.csv' with csv
\copy campaigns from 'campaigns.csv' with csv
\copy ads from 'ads.csv' with csv

运行查询

现在我们已经将数据加载到表中,让我们继续运行一些查询。 Citus 支持标准的 INSERTUPDATEDELETE 命令,用于在分布式表中插入和修改行,这是面向用户的应用程序的典型交互方式。

例如,您可以通过运行插入一个新公司:

INSERT INTO companies VALUES (5000, 'New Company', 'https://randomurl/image.png', now(), now());

如果您想将公司所有活动的预算翻倍,您可以运行 UPDATE 命令:

UPDATE campaigns
SET monthly_budget = monthly_budget*2
WHERE company_id = 5;

这种操作的另一个例子是运行跨越多个表的事务。 假设您要删除一个广告系列及其所有相关广告,您可以通过运行以原子方式执行:

BEGIN;
DELETE FROM campaigns WHERE id = 46 AND company_id = 5;
DELETE FROM ads WHERE campaign_id = 46 AND company_id = 5;
COMMIT;

事务中的每个语句都会导致多节点 Citus 中的 coordinatorworker 之间的往返。 对于多租户工作负载,在分布式函数中运行事务效率更高。 对于较大的事务,效率提升变得更加明显,但我们可以使用上面的小事务作为示例。

首先创建一个执行删除的函数:

CREATE OR REPLACE FUNCTION
delete_campaign(company_id int, campaign_id int)
RETURNS void LANGUAGE plpgsql AS $fn$
BEGIN
DELETE FROM campaigns
WHERE id = $2 AND campaigns.company_id = $1;
DELETE FROM ads
WHERE ads.campaign_id = $2 AND ads.company_id = $1;
END;
$fn$;

接下来使用 create_distributed_function 指示 Citus 直接在 worker 上而不是在 coordinator 上运行该函数(除了在单节点 Citus 安装上,它在 coordinator 上运行所有东西)。它将在任何持有与值 company_id 相对应的 adscampaigns 表的分片的 worker 上运行该函数。

SELECT create_distributed_function(
'delete_campaign(int, int)', 'company_id',
colocate_with := 'campaigns'
); -- you can run the function as usual
SELECT delete_campaign(5, 46);

除了事务操作,您还可以使用标准 SQL 运行分析查询。 公司运营的一个有趣查询是查看有关其具有最大预算的活动的详细信息。

SELECT name, cost_model, state, monthly_budget
FROM campaigns
WHERE company_id = 5
ORDER BY monthly_budget DESC
LIMIT 10;

我们还可以跨多个表运行连接查询,以查看有关运行获得最多点击次数和展示次数的广告系列的信息。

SELECT campaigns.id, campaigns.name, campaigns.monthly_budget,
sum(impressions_count) as total_impressions, sum(clicks_count) as total_clicks
FROM ads, campaigns
WHERE ads.company_id = campaigns.company_id
AND campaigns.company_id = 5
AND campaigns.state = 'running'
GROUP BY campaigns.id, campaigns.name, campaigns.monthly_budget
ORDER BY total_impressions, total_clicks;

至此,我们结束了使用 Citus 为简单的多租户应用程序提供支持的教程。 下一步,您可以查看多租户应用程序部分,了解如何为自己的多租户数据建模。

实时应用程序分析

在本教程中,我们将演示如何使用 Citus 获取事件数据并在人类实时的数据上运行分析查询。 为此,我们将使用一个示例 Github 事件数据集。

数据模型和样本数据

我们将演示为实时分析应用程序构建数据库。 该应用程序将插入大量事件数据,并以亚秒级延迟对这些数据进行分析查询。在我们的示例中,我们将使用 Github 事件数据集。该数据集包括 Github 上的所有公共事件,例如提交(commits)分叉(forks)新问题(new issues)以及对这些问题的评论(comments)

我们将使用两个 Postgres 表来表示这些数据。要开始使用,您需要下载这些表的示例数据:

curl https://examples.citusdata.com/tutorial/users.csv > users.csv
curl https://examples.citusdata.com/tutorial/events.csv > events.csv

如果您使用 Docker,则应使用 docker cp 命令将文件复制到 Docker 容器中。

docker cp users.csv citus:.
docker cp events.csv citus:.

创建表

首先,您可以先使用 psql 连接到 Citus 协调器。

如果您使用原生 Postgres,如我们的单节点 Citus 指南中安装的那样,coordinator 节点将在端口 9700上运行。

psql -p 9700

如果您使用的是 Docker,则可以通过使用 docker exec 命令运行 psql 进行连接:

docker exec -it citus psql -U postgres

然后,您可以使用标准 PostgreSQL CREATE TABLE 命令创建表。

CREATE TABLE github_events
(
event_id bigint,
event_type text,
event_public boolean,
repo_id bigint,
payload jsonb,
repo jsonb,
user_id bigint,
org jsonb,
created_at timestamp
); CREATE TABLE github_users
(
user_id bigint,
url text,
login text,
avatar_url text,
gravatar_id text,
display_login text
);

接下来,您可以像在 PostgreSQL 中那样为事件数据创建索引。在本例中,我们还将创建一个 GIN 索引以更快地查询 jsonb 字段。

CREATE INDEX event_type_index ON github_events (event_type);
CREATE INDEX payload_index ON github_events USING GIN (payload jsonb_path_ops);

分布表和加载数据

我们现在将继续告诉 Citus 将这些表分布到集群中的节点上。为此,您可以运行 create_distributed_table 并指定要分片的表和要分片的列。在这种情况下,我们将对 user_id 上的所有表进行分片。

SELECT create_distributed_table('github_users', 'user_id');
SELECT create_distributed_table('github_events', 'user_id');

对用户标识符上的所有表进行分片允许 Citus 将这些表放在一起,并允许有效的连接和分布式汇总。

然后,您可以继续使用标准 PostgreSQL \COPY 命令将我们下载的数据加载到表中。 如果您将文件下载到其他位置,请确保指定正确的文件路径。

\copy github_users from 'users.csv' with csv
\copy github_events from 'events.csv' with csv

运行查询

现在我们已经将数据加载到表中,让我们继续运行一些查询。 首先,让我们检查一下分布式数据库中有多少用户。

SELECT count(*) FROM github_users;

现在,让我们分析一下我们数据中的 Github 推送事件。 我们将首先通过使用每个推送事件中不同提交的数量来计算每分钟的提交数量。

SELECT date_trunc('minute', created_at) AS minute,
sum((payload->>'distinct_size')::int) AS num_commits
FROM github_events
WHERE event_type = 'PushEvent'
GROUP BY minute
ORDER BY minute;

我们还有一个用户表。我们还可以轻松地将用户加入事件,并找到创建最多存储库的前十名用户。

SELECT login, count(*)
FROM github_events ge
JOIN github_users gu
ON ge.user_id = gu.user_id
WHERE event_type = 'CreateEvent' AND payload @> '{"ref_type": "repository"}'
GROUP BY login
ORDER BY count(*) DESC LIMIT 10;

Citus 还支持用于摄取和修改数据的标准 INSERTUPDATEDELETE 命令。 例如,您可以通过运行以下命令来更新用户的显示登录:

UPDATE github_users SET display_login = 'no1youknow' WHERE user_id = 24305673;

至此,我们的教程结束了。下一步,您可以查看实时应用程序部分,了解如何为自己的数据建模并为实时分析应用程序提供动力。

更多

分布式 PostgreSQL 集群(Citus),官方快速入门教程的更多相关文章

  1. 分布式 PostgreSQL 集群(Citus)官方示例 - 时间序列数据

    在时间序列工作负载中,应用程序(例如一些实时应用程序查询最近的信息,同时归档旧信息. https://docs.citusdata.com/en/v10.2/sharding/data_modelin ...

  2. 分布式 PostgreSQL 集群(Citus)官方安装指南

    单节点 Citus Docker (Mac 与 Linux) Docker 镜像仅用于开发/测试目的, 并且尚未准备好用于生产用途. 您可以使用一个命令在 Docker 中启动 Citus: # st ...

  3. 分布式 PostgreSQL 集群(Citus)官方教程 - 迁移现有应用程序

    将现有应用程序迁移到 Citus 有时需要调整 schema 和查询以获得最佳性能. Citus 扩展了 PostgreSQL 的分布式功能,但它不是扩展所有工作负载的直接替代品.高性能 Citus ...

  4. 分布式 PostgreSQL 集群(Citus)官方示例 - 实时仪表盘

    Citus 提供对大型数据集的实时查询.我们在 Citus 常见的一项工作负载涉及为事件数据的实时仪表板提供支持. 例如,您可以是帮助其他企业监控其 HTTP 流量的云服务提供商.每次您的一个客户端收 ...

  5. 分布式 PostgreSQL 集群(Citus)官方示例 - 多租户应用程序实战

    如果您正在构建软件即服务 (SaaS) 应用程序,您可能已经在数据模型中内置了租赁的概念. 通常,大多数信息与租户/客户/帐户相关,并且数据库表捕获这种自然关系. 对于 SaaS 应用程序,每个租户的 ...

  6. 分布式 PostgreSQL 集群(Citus),分布式表中的分布列选择最佳实践

    确定应用程序类型 在 Citus 集群上运行高效查询要求数据在机器之间正确分布.这因应用程序类型及其查询模式而异. 大致上有两种应用程序在 Citus 上运行良好.数据建模的第一步是确定哪些应用程序类 ...

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

    准备工作 这里假设,你已经在 k8s 上部署好了基于 Citus 扩展的分布式 PostgreSQL 集群. 查看 Citus 集群(kubectl get po -n citus),1 个 Coor ...

  8. Citus 分布式 PostgreSQL 集群 - SQL Reference(查询分布式表 SQL)

    如前几节所述,Citus 是一个扩展,它扩展了最新的 PostgreSQL 以进行分布式执行.这意味着您可以在 Citus 协调器上使用标准 PostgreSQL SELECT 查询进行查询. Cit ...

  9. Citus 分布式 PostgreSQL 集群 - SQL Reference(创建和修改分布式表 DDL)

    创建和分布表 要创建分布式表,您需要首先定义表 schema. 为此,您可以使用 CREATE TABLE 语句定义一个表,就像使用常规 PostgreSQL 表一样. CREATE TABLE ht ...

随机推荐

  1. nginx的优化和防盗链

    nginx的优化和防盗链 目录 nginx的优化和防盗链 一.nginx的优化 1. 隐藏版本号 (1)隐藏版本号的原因 (2)查看版本号的方法 (3)隐藏方法一:修改配置文件 (4)隐藏方法二:修改 ...

  2. C++输入多行数据

    动机 编程题常用需求,比如输入两行数据. 解决思路:使用getline 程序 #include <iostream> #include <vector> #include &l ...

  3. 一款免费在线转pdf的工具 和 window免费镜像

    PDF爱好者的在线工具 完全免费的PDF文件在线管理工具,其功能包括:合并PDF文件.拆分PDF文件.压缩PDF文件.Office文件转换为PDF文件.PDF文件转换为JPG图片.JPG图片转换为PD ...

  4. 微服务6:通信之网关 Ready

    ★微服务系列 微服务1:微服务及其演进史 微服务2:微服务全景架构 微服务3:微服务拆分策略 微服务4:服务注册与发现 微服务5:服务注册与发现(实践篇) 微服务6:通信之网关 1 概述 回顾下前面几 ...

  5. SQL注入蠕虫分析//未完待续

    蠕虫代码: DECLARE @S VARCHAR(4000);SET @S=CAST(0x4445434C415245204054205641524348415228323535292C4043205 ...

  6. JVM基础学习(一):JVM内存模型

    在Java进阶知识的学习中,JVM都是避不过去的一关,我个人对于JVM的理解其实就是相当于在操作系统的外层再加了一层中间层,从来屏蔽了具体硬件之间的不同实现,使得Java实现了最重要的特性:一次编译, ...

  7. tip1:学习使用mybatis中使用mysql数据库的基本操作

    1.查看mysql服务是否启动: 2.root用户链接数据库:mysql -u root -p,随后输入正确的密码即可. 3.root用户创建数据库: 4.查看已建数据库:show databases ...

  8. ZCC2410同步升压变换芯片

    ZCC2410???? 22V/25A同步升压变换器  ZCC2410是一种高效率.高功率密度.宽输入范围.电流模式升压变换器.该转换器集成了一个10mΩ.24V电源开关和一个同步门高转换器效率的驱动 ...

  9. 数据分析实际案例之:pandas在餐厅评分数据中的使用

    目录 简介 餐厅评分数据简介 分析评分数据 简介 为了更好的熟练掌握pandas在实际数据分析中的应用,今天我们再介绍一下怎么使用pandas做美国餐厅评分数据的分析. 餐厅评分数据简介 数据的来源是 ...

  10. [数据结构]一元n次多项式的抽象数据类型

    一.问题描述 一元n次多项式是代数学中经常出现的代数式,对于一元n次多项式的操作有很重要的实际意义.由于一个一元n次多项式最多有n+1项,且互不相关,所以可以用一个线性表来保存一个多项式,从前至后次数 ...