日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
分布式 PostgreSQL 集群(Citus)官方示例 -實(shí)時儀表盤

本文轉(zhuǎn)載自微信公眾號「黑客下午茶」,作者為少。轉(zhuǎn)載本文請聯(lián)系黑客下午茶公眾號。

站在用戶的角度思考問題,與客戶深入溝通,找到?jīng)鲋菥W(wǎng)站設(shè)計(jì)與涼州網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗(yàn)好的作品,建站類型包括:做網(wǎng)站、成都網(wǎng)站建設(shè)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、申請域名、網(wǎng)頁空間、企業(yè)郵箱。業(yè)務(wù)覆蓋涼州地區(qū)。

Citus 提供對大型數(shù)據(jù)集的實(shí)時查詢。我們在 Citus 常見的一項(xiàng)工作負(fù)載涉及為事件數(shù)據(jù)的實(shí)時儀表板提供支持。

例如,您可以是幫助其他企業(yè)監(jiān)控其 HTTP 流量的云服務(wù)提供商。每次您的一個客戶端收到 HTTP 請求時,您的服務(wù)都會收到一條日志記錄。您想要攝取所有這些記錄并創(chuàng)建一個 HTTP 分析儀表板,為您的客戶提供洞察力,例如他們的網(wǎng)站服務(wù)的 HTTP 錯誤數(shù)量。重要的是,這些數(shù)據(jù)以盡可能少的延遲顯示出來,這樣您的客戶就可以解決他們網(wǎng)站的問題。儀表板顯示歷史趨勢圖也很重要。

或者,也許您正在建立一個廣告網(wǎng)絡(luò),并希望向客戶展示其廣告系列的點(diǎn)擊率。在此示例中,延遲也很關(guān)鍵,原始數(shù)據(jù)量也很高,歷史數(shù)據(jù)和實(shí)時數(shù)據(jù)都很重要。

在本節(jié)中,我們將演示如何構(gòu)建第一個示例的一部分,但該架構(gòu)同樣適用于第二個和許多其他用例。

  • real-time-analytics-Hands-On-Lab-Hyperscale-Citus

https://github.com/citusdata/real-time-analytics-Hands-On-Lab-Hyperscale-Citus

  • Architecting Real-Time Analytics for your Customers

https://github.com/citusdata/postgres-analytics-tutorial

數(shù)據(jù)模型

我們正在處理的數(shù)據(jù)是不可變的日志數(shù)據(jù)流。我們將直接插入 Citus,但這些數(shù)據(jù)首先通過 Kafka 之類的東西進(jìn)行路由也很常見。這樣做具有通常的優(yōu)勢,并且一旦數(shù)據(jù)量變得難以管理,就可以更容易地預(yù)先聚合數(shù)據(jù)。

我們將使用一個簡單的 schema 來攝取 HTTP 事件數(shù)據(jù)。這個 schema 作為一個例子來展示整體架構(gòu);一個真實(shí)的系統(tǒng)可能會使用額外的列。

-- this is run on the coordinator

CREATE TABLE http_request (
site_id INT,
ingest_time TIMESTAMPTZ DEFAULT now(),

url TEXT,
request_country TEXT,
ip_address TEXT,

status_code INT,
response_time_msec INT
);

SELECT create_distributed_table('http_request', 'site_id');

當(dāng)我們調(diào)用 create_distributed_table 時,我們要求 Citus 使用 site_id 列對 http_request 進(jìn)行 hash 分配。這意味著特定站點(diǎn)的所有數(shù)據(jù)都將存在于同一個分片中。

  • create_distributed_table

https://docs.citusdata.com/en/v10.2/develop/api_udf.html#create-distributed-table

UDF 使用分片計(jì)數(shù)的默認(rèn)配置值。我們建議在集群中使用 2-4 倍于 CPU 核的分片。使用這么多分片可以讓您在添加新的工作節(jié)點(diǎn)后重新平衡集群中的數(shù)據(jù)。

  • 2-4 倍于 CPU 核的分片

https://docs.citusdata.com/en/v10.2/faq/faq.html#faq-choose-shard-count

Azure Database for PostgreSQL — 超大規(guī)模 (Citus) 使用流式復(fù)制來實(shí)現(xiàn)高可用性,因此維護(hù)分片副本將是多余的。在任何流復(fù)制不可用的生產(chǎn)環(huán)境中,您應(yīng)該將 citus.shard_replication_factor 設(shè)置為 2 或更高以實(shí)現(xiàn)容錯。

  • Azure Database for PostgreSQL

https://docs.microsoft.com/azure/postgresql/hyperscale/

  • 流式復(fù)制

https://www.postgresql.org/docs/current/static/warm-standby.html

有了這個,系統(tǒng)就可以接受數(shù)據(jù)并提供查詢了!在繼續(xù)執(zhí)行本文中的其他命令時,讓以下循環(huán)在后臺的 psql 控制臺中運(yùn)行。它每隔一兩秒就會生成假數(shù)據(jù)。

DO $$
BEGIN LOOP
INSERT INTO http_request (
site_id, ingest_time, url, request_country,
ip_address, status_code, response_time_msec
) VALUES (
trunc(random()*32), clock_timestamp(),
concat('http://example.com/', md5(random()::text)),
('{China,India,USA,Indonesia}'::text[])[ceil(random()*4)],
concat(
trunc(random()*250 + 2), '.',
trunc(random()*250 + 2), '.',
trunc(random()*250 + 2), '.',
trunc(random()*250 + 2)
)::inet,
('{200,404}'::int[])[ceil(random()*2)],
5+trunc(random()*150)
);
COMMIT;
PERFORM pg_sleep(random() * 0.25);
END LOOP;
END $$;

攝取數(shù)據(jù)后,您可以運(yùn)行儀表板查詢,例如:

SELECT
site_id,
date_trunc('minute', ingest_time) as minute,
COUNT(1) AS request_count,
SUM(CASE WHEN (status_code between 200 and 299) THEN 1 ELSE 0 END) as success_count,
SUM(CASE WHEN (status_code between 200 and 299) THEN 0 ELSE 1 END) as error_count,
SUM(response_time_msec) / COUNT(1) AS average_response_time_msec
FROM http_request
WHERE date_trunc('minute', ingest_time) > now() - '5 minutes'::interval
GROUP BY site_id, minute
ORDER BY minute ASC;

上述設(shè)置有效,但有兩個缺點(diǎn):

  • 每次需要生成圖表時,您的 HTTP 分析儀表板都必須遍歷每一行。例如,如果您的客戶對過去一年的趨勢感興趣,您的查詢將從頭開始匯總過去一年的每一行。
  • 您的存儲成本將隨著攝取率和可查詢歷史的長度成比例增長。在實(shí)踐中,您可能希望將原始事件保留較短的時間(一個月)并查看較長時間(年)的歷史圖表。

匯總

您可以通過將原始數(shù)據(jù)匯總為預(yù)聚合形式來克服這兩個缺點(diǎn)。在這里,我們將原始數(shù)據(jù)匯總到一個表中,該表存儲 1 分鐘間隔的摘要。在生產(chǎn)系統(tǒng)中,您可能還需要類似 1 小時和 1 天的間隔,這些都對應(yīng)于儀表板中的縮放級別。當(dāng)用戶想要上個月的請求時間時,儀表板可以簡單地讀取并繪制過去 30 天每一天的值。

CREATE TABLE http_request_1min (
site_id INT,
ingest_time TIMESTAMPTZ, -- which minute this row represents

error_count INT,
success_count INT,
request_count INT,
average_response_time_msec INT,
CHECK (request_count = error_count + success_count),
CHECK (ingest_time = date_trunc('minute', ingest_time))
);

SELECT create_distributed_table('http_request_1min', 'site_id');

CREATE INDEX http_request_1min_idx ON http_request_1min (site_id, ingest_time);

這看起來很像前面的代碼塊。最重要的是:它還在 site_id 上進(jìn)行分片,并對分片計(jì)數(shù)和復(fù)制因子使用相同的默認(rèn)配置。因?yàn)檫@三個都匹配,所以 http_request 分片和 http_request_1min 分片之間存在一對一的對應(yīng)關(guān)系,Citus 會將匹配的分片放在同一個 worker 上。這稱為協(xié)同定位(co-location);它使諸如聯(lián)接(join)之類的查詢更快,并使我們的匯總成為可能。

  • 協(xié)同定位(co-location)

https://docs.citusdata.com/en/v10.2/sharding/data_modeling.html#colocation

為了填充 http_request_1min,我們將定期運(yùn)行 INSERT INTO SELECT。這是可能的,因?yàn)檫@些表位于同一位置。為方便起見,以下函數(shù)將匯總查詢包裝起來。

-- single-row table to store when we rolled up last
CREATE TABLE latest_rollup (
minute timestamptz PRIMARY KEY,

-- "minute" should be no more precise than a minute
CHECK (minute = date_trunc('minute', minute))
);

-- initialize to a time long ago
INSERT INTO latest_rollup VALUES ('10-10-1901');

-- function to do the rollup
CREATE OR REPLACE FUNCTION rollup_http_request() RETURNS void AS $$
DECLARE
curr_rollup_time timestamptz := date_trunc('minute', now());
last_rollup_time timestamptz := minute from latest_rollup;
BEGIN
INSERT INTO http_request_1min (
site_id, ingest_time, request_count,
success_count, error_count, average_response_time_msec
) SELECT
site_id,
date_trunc('minute', ingest_time),
COUNT(1) as request_count,
SUM(CASE WHEN (status_code between 200 and 299) THEN 1 ELSE 0 END) as success_count,
SUM(CASE WHEN (status_code between 200 and 299) THEN 0 ELSE 1 END) as error_count,
SUM(response_time_msec) / COUNT(1) AS average_response_time_msec
FROM http_request
-- roll up only data new since last_rollup_time
WHERE date_trunc('minute', ingest_time) <@
tstzrange(last_rollup_time, curr_rollup_time, '(]')
GROUP BY 1, 2;

-- update the value in latest_rollup so that next time we run the
-- rollup it will operate on data newer than curr_rollup_time
UPDATE latest_rollup SET minute = curr_rollup_time;
END;
$$ LANGUAGE plpgsql;

上述函數(shù)應(yīng)該每分鐘調(diào)用一次。您可以通過在 coordinator 節(jié)點(diǎn)上添加一個 crontab 條目來做到這一點(diǎn):

* * * * * psql -c 'SELECT rollup_http_request();'

或者,諸如 pg_cron 之類的擴(kuò)展允許您直接從數(shù)據(jù)庫安排周期性查詢。

  • pg_cron

https://github.com/citusdata/pg_cron

之前的儀表板查詢現(xiàn)在好多了:

SELECT site_id, ingest_time as minute, request_count,
success_count, error_count, average_response_time_msec
FROM http_request_1min
WHERE ingest_time > date_trunc('minute', now()) - '5 minutes'::interval;

過期的舊數(shù)據(jù)

匯總使查詢更快,但我們?nèi)匀恍枰古f數(shù)據(jù)過期以避免無限的存儲成本。只需決定您希望為每個粒度保留數(shù)據(jù)多長時間,然后使用標(biāo)準(zhǔn)查詢刪除過期數(shù)據(jù)。在以下示例中,我們決定將原始數(shù)據(jù)保留一天,將每分鐘的聚合保留一個月:

DELETE FROM http_request WHERE ingest_time < now() - interval '1 day';
DELETE FROM http_request_1min WHERE ingest_time < now() - interval '1 month';

在生產(chǎn)中,您可以將這些查詢包裝在一個函數(shù)中,并在 cron job 中每分鐘調(diào)用一次。

通過在 Citrus 哈希分布之上使用表范圍分區(qū),數(shù)據(jù)過期可以更快。有關(guān)詳細(xì)示例,請參閱時間序列數(shù)據(jù)部分。

  • 時間序列數(shù)據(jù)

https://docs.citusdata.com/en/v10.2/use_cases/timeseries.html#timeseries

這些是基礎(chǔ)!我們提供了一種架構(gòu),可以攝取 HTTP 事件,然后將這些事件匯總到它們的預(yù)聚合形式中。這樣,您既可以存儲原始事件,也可以通過亞秒級查詢?yōu)槟姆治鰞x表板提供動力。

接下來的部分將擴(kuò)展基本架構(gòu),并向您展示如何解決經(jīng)常出現(xiàn)的問題。

近似不同計(jì)數(shù)

HTTP 分析中的一個常見問題涉及近似的不同計(jì)數(shù):上個月有多少獨(dú)立訪問者訪問了您的網(wǎng)站?準(zhǔn)確地回答這個問題需要將所有以前見過的訪問者的列表存儲在匯總表中,這是一個令人望而卻步的數(shù)據(jù)量。然而,一個近似的答案更易于管理。

  • 近似的不同計(jì)數(shù)

https://docs.citusdata.com/en/v10.2/develop/reference_sql.html#count-distinct

一種稱為 hyperloglog 或 HLL 的數(shù)據(jù)類型可以近似地回答查詢;要告訴您一個集合中大約有多少個獨(dú)特元素,需要的空間非常小。其精度可以調(diào)整。我們將使用僅使用 1280 字節(jié)的那些,將能夠以最多 2.2% 的錯誤計(jì)算多達(dá)數(shù)百億的唯一訪問者。

如果您要運(yùn)行全局查詢,則會出現(xiàn)類似的問題,例如在上個月訪問您客戶的任何站點(diǎn)的唯一 IP 地址的數(shù)量。在沒有 HLL 的情況下,此查詢涉及將 IP 地址列表從 worker 傳送到 coordinator 以進(jìn)行重復(fù)數(shù)據(jù)刪除。這既是大量的網(wǎng)絡(luò)流量,也是大量的計(jì)算。通過使用 HLL,您可以大大提高查詢速度。

首先你必須安裝 HLL 擴(kuò)展;github repo 有說明。接下來,您必須啟用它:

  • postgresql-hll

https://github.com/citusdata/postgresql-hll

CREATE EXTENSION hll;

這在 Hyperscale 上是不必要的,它已經(jīng)安裝了 HLL 以及其他有用的擴(kuò)展。

現(xiàn)在我們準(zhǔn)備好在 HLL 匯總中跟蹤 IP 地址。首先向匯總表添加一列。

ALTER TABLE http_request_1min ADD COLUMN distinct_ip_addresses hll;

接下來使用我們的自定義聚合來填充列。只需將它添加到我們匯總函數(shù)中的查詢中:

@@ -1,10 +1,12 @@
INSERT INTO http_request_1min (
site_id, ingest_time, request_count,
success_count, error_count, average_response_time_msec
+ , distinct_ip_addresses
) SELECT
site_id,
minute,
COUNT(1) as request_count,
SUM(CASE WHEN (status_code between 200 and 299) THEN 1 ELSE 0 END) as success_count,
SUM(CASE WHEN (status_code between 200 and 299) THEN 0 ELSE 1 END) as error_count,
SUM(response_time_msec) / COUNT(1) AS average_response_time_msec
+ , hll_add_agg(hll_hash_text(ip_address)) AS distinct_ip_addresses
FROM http_request

儀表板查詢稍微復(fù)雜一些,您必須通過調(diào)用 hll_cardinality 函數(shù)讀出不同數(shù)量的 IP 地址:

SELECT site_id, ingest_time as minute, request_count,
success_count, error_count, average_response_time_msec,
hll_cardinality(distinct_ip_addresses) AS distinct_ip_address_count
FROM http_request_1min
WHERE ingest_time > date_trunc('minute', now()) - interval '5 minutes';

HLL 不僅速度更快,還可以讓你做以前做不到的事情。假設(shè)我們進(jìn)行了匯總,但我們沒有使用 HLL,而是保存了確切的唯一計(jì)數(shù)。這很好用,但您無法回答諸如在過去的一周內(nèi),我們丟棄了原始數(shù)據(jù)有多少不同的會話?之類的問題。

使用 HLL,這很容易。您可以使用以下查詢計(jì)算一段時間內(nèi)的不同 IP 計(jì)數(shù):

SELECT hll_cardinality(hll_union_agg(distinct_ip_addresses))
FROM http_request_1min
WHERE ingest_time > date_trunc('minute', now()) - '5 minutes'::interval;

您可以在項(xiàng)目的 GitHub 存儲庫中找到有關(guān) HLL 的更多信息。

  • postgresql-hll

https://github.com/aggregateknowledge/postgresql-hll

使用 JSONB 的非結(jié)構(gòu)化數(shù)據(jù)

Citus 與 Postgres 對非結(jié)構(gòu)化數(shù)據(jù)類型的內(nèi)置支持配合得很好。為了證明這一點(diǎn),讓我們跟蹤來自每個國家/地區(qū)的訪客數(shù)量。使用半結(jié)構(gòu)數(shù)據(jù)類型可以讓您不必為每個國家添加一列,并最終得到具有數(shù)百個稀疏填充列的行。我們有一篇博文解釋了半結(jié)構(gòu)化數(shù)據(jù)使用哪種格式。這篇文章推薦使用 JSONB,在這里我們將演示如何將 JSONB 列合并到您的數(shù)據(jù)模型中。

  • 博文

https://www.citusdata.com/blog/2016/07/14/choosing-nosql-hstore-json-jsonb

首先,將新列添加到我們的匯總表中:

ALTER TABLE http_request_1min ADD COLUMN country_counters JSONB;

接下來,通過修改匯總函數(shù)將其包含在匯總中:

@@ -1,14 +1,19 @@
INSERT INTO http_request_1min (
site_id, ingest_time, request_count,
success_count, error_count, average_response_time_msec
+ , country_counters
) SELECT
site_id,
minute,
COUNT(1) as request_count,
SUM(CASE WHEN (status_code between 200 and 299) THEN 1 ELSE 0 END) as success_count
SUM(CASE WHEN (status_code between 200 and 299) THEN 0 ELSE 1 END) as error_count
SUM(response_time_msec) / COUNT(1) AS average_response_time_msec
- FROM http_request
+ , jsonb_object_agg(request_country, country_count) AS country_counters
+ FROM (
+ SELECT *,
+ count(1) OVER (
+ PARTITION BY site_id, date_trunc('minute', ingest_time), request_country
+ ) AS country_count
+ FROM http_request
+ ) h

現(xiàn)在,如果您想在儀表板中獲取來自美國的請求數(shù)量,您可以將儀表板查詢修改為如下所示:

SELECT
request_count, success_count, error_count, average_response_time_msec,
COALESCE(country_counters->>'USA', '0')::int AS american_visitors
FROM http_request_1min
WHERE ingest_time > date_trunc('minute', now()) - '5 minutes'::interval;

新聞標(biāo)題:分布式 PostgreSQL 集群(Citus)官方示例 -實(shí)時儀表盤
文章來源:http://www.dlmjj.cn/article/cdicoio.html