偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

告別Redis!如何在PostgreSQL 18實現(xiàn)無緩存架構(gòu)的平滑落地?

數(shù)據(jù)庫 Redis
我并不是反對緩存。如果你需要跨請求協(xié)調(diào)、速率窗口,或者跨服務(wù)的扇出扇入操作,緩存或消息總線仍然有其用武之地。我僅在它掩蓋了規(guī)劃器錯誤并增加了方差的地方移除了它。一個誠實的承認(rèn):我曾嘗試通過降低 synchronous_commit 來榨取更多性能,但后來撤銷了,因為對于這條路徑來說,寫入語義的風(fēng)險不值得去冒。

我在生產(chǎn)環(huán)境關(guān)掉了 Redis,而且沒有回滾。”

這句話現(xiàn)在仍讓我心里發(fā)緊,因為緩存就像一條安全帶。但在 PostgreSQL 18 上經(jīng)過慎重試驗后,p95 降低了,系統(tǒng)變簡單了,值班負(fù)擔(dān)也減輕了。

風(fēng)險是真實的:用戶會話、結(jié)賬流程、我們的口碑。

收益也是真實的:更少的活動部件,更少的告警短信。

下面是我走過的路徑、我修復(fù)的查詢、唯一關(guān)鍵的圖,以及幾個起決定作用的小配置。

一、我撥動開關(guān)的那一天

我們的熱路徑是一個參數(shù)化的產(chǎn)品查詢,并帶有一點個性化。

緩存為我們帶來了命中,但未命中很嘈雜,而且序列化增加了工作量。

我對該路徑進(jìn)行了端到端的分析,然后嘗試了一個直接的數(shù)據(jù)庫方案,使用更緊湊的索引和一個預(yù)先計算好的投影。

第一次運行很嚇人——然后數(shù)據(jù)穩(wěn)定下來了。

我讓緩存停用了一個完整的周期,看著圖表平靜下來。

二、Postgres 里到底發(fā)生了什么

沒有玄學(xué),只有兩件落地的事:

1、覆蓋度與選擇性

一個覆蓋索引 + 一個生成列,讓優(yōu)化器只拿我們要的字段,不再碰堆表。

2、預(yù)計算形態(tài)

物化視圖(并發(fā)刷新)把原來靠緩存藏起來的昂貴聚合扛了過來。

PostgreSQL 18 用更理智的執(zhí)行計劃 + 可預(yù)測的 I/O 完成了其余工作。

三、那個讓 Redis 變得多余的查詢

下面的表結(jié)構(gòu)反映了一條常見的 Feed 或目錄切片:商品、軟刪除、新鮮度、個性化鍵。

重點不是字段名,而是“生成列 + 覆蓋索引”的組合正好匹配返回結(jié)果。

-- Schema and plan helpers (run in a maintenance window)
CREATE TABLE catalog_item (
  item_id           BIGSERIAL PRIMARY KEY,
  category_id       BIGINT NOT NULL,
  tenant_id         BIGINT NOT NULL,
  price_cents       INTEGER NOT NULL,
  rating_avg        NUMERIC(3,2) NOT NULL DEFAULT 0.0,
  tags              TEXT[] NOT NULL DEFAULT '{}',
  updated_at        TIMESTAMPTZ NOT NULL DEFAULT now(),
  deleted           BOOLEAN NOT NULL DEFAULT FALSE
);


-- Generated column to precompute a simple personalization bucket
ALTER TABLE catalog_item
  ADD COLUMN p_bucket SMALLINT GENERATED ALWAYS AS (
    (rating_avg * 10)::smallint
  ) STORED;


-- Covering index that matches the query (note the INCLUDE list)
CREATE INDEX CONCURRENTLY idx_catalog_lookup
  ON catalog_item (tenant_id, category_id, p_bucket, deleted)
  WHERE deleted = FALSE
  INCLUDE (item_id, price_cents, rating_avg, updated_at, tags);


-- A precomputed projection for “trending” that used to be cached
CREATE MATERIALIZED VIEW mv_trending AS
SELECT tenant_id, category_id,
       item_id, price_cents, rating_avg, tags,
       row_number() OVER (PARTITION BY tenant_id, category_id ORDER BY rating_avg DESC, updated_at DESC) AS rk
FROM catalog_item
WHERE deleted = FALSE;


-- Keep it fresh without blocking writers
CREATE UNIQUE INDEX CONCURRENTLY mv_trending_pk
  ON mv_trending (tenant_id, category_id, item_id);


-- In a job runner or cron:
-- REFRESH MATERIALIZED VIEW CONCURRENTLY mv_trending;

應(yīng)用程序調(diào)用隨后變成了單次往返:

-- Serve top N without touching Redis
PREPARE fetch_slice (bigint, bigint, smallint, int) AS
SELECT item_id, price_cents, rating_avg, tags
FROM   catalog_item
WHERE  tenant_id = $1
  AND  category_id = $2
  AND  p_bucket >= $3
  AND  deleted = FALSE
ORDER  BY rating_avg DESC, updated_at DESC
LIMIT  $4;


-- When trending is requested
PREPARE fetch_trending (bigint, bigint, int) AS
SELECT item_id, price_cents, rating_avg, tags
FROM   mv_trending
WHERE  tenant_id = $1 AND category_id = $2 AND rk <= $3;

簡而言之:規(guī)劃器停留在索引上,堆保持"冷卻",視圖從熱路徑中移除了沉重的聚合操作。

四、從源頭削減延遲

兩個小的配置調(diào)整起到了作用。它們并非萬能藥;但它們確實讓 I/O 保持穩(wěn)定,并讓規(guī)劃器能夠可靠地利用索引和并行性。

# postgresql.conf (16 GB VM example)
shared_buffers = '4GB'
effective_cache_size = '11GB'
work_mem = '64MB'
maintenance_work_mem = '1GB'
track_io_timing = on
jit = on
max_worker_processes = 8
max_parallel_workers_per_gather = 2
random_page_cost = 1.1
default_statistics_target = 500

如果你在更快的本地 NVMe 上運行,較低的 random_page_cost 能保持索引掃描的吸引力。track_io_timing 會在你對自己磁盤性能判斷有誤時告訴你。

五、我是如何測量的

我運行了一個簡單的客戶端,它發(fā)出了我們通常緩存的那組參數(shù)。下表來自我的環(huán)境,3 次預(yù)熱運行,顯示的是中位數(shù)。網(wǎng)絡(luò)跳數(shù)和序列化開銷比人們預(yù)期的要多。

+--------------------------------------+-------+-------+-------+-------------------------------+
| Path                                 |  p50  |  p95  |  p99  | Notes                         |
+--------------------------------------+-------+-------+-------+-------------------------------+
| Redis (hit)                          |  6 ms |  18 ms|  28 ms| fast but extra hop            |
| Redis (miss → DB)                    | 24 ms |  80 ms| 120 ms| hop + serialization + origin  |
| Postgres 18 direct (covering index)  | 18 ms |  55 ms|  95 ms| fewer hops, stable tail       |
| Postgres 18 via mv_trending (warm)   | 12 ms |  38 ms|  70 ms| precomputed hot slice         |
+--------------------------------------+-------+-------+-------+-------------------------------+

在我們的信息流端點上,直接的數(shù)據(jù)庫路徑擊敗了緩存未命名的尾部延遲,并消除了命中與未命中之間的斷崖式差距。那個差距過去常常出現(xiàn)在用戶追蹤記錄和支持工單中。

六、前后對比,用 ASCII 圖繪制

一個說服團(tuán)隊的流程圖:

BEFORE
┌────────┐    ┌──────────────┐    ┌───────────┐
│ Client │───?│ Redis/Codec  │───?│ Postgres  │
└────────┘    └──────────────┘    └───────────┘
    ▲              │                  ▲
    └──── misses ──┘                  └── invalidates ─┘
AFTER
┌────────┐    ┌──────────────────────────────────────────┐
│ Client │─────?│              Postgres 18                │
└────────┘    │  ? Covering index (tenant, category, p)  │
              │  ? Materialized view for trending        │
              │  ? Parallel plan where it helps          │
              └──────────────────────────────────────────┘

我們?nèi)匀槐A袅艘粋€只讀副本以確保安全,但熱路徑現(xiàn)在只有一個依賴項。

七、何時緩存仍然占優(yōu)

我并不是反對緩存。如果你需要跨請求協(xié)調(diào)、速率窗口,或者跨服務(wù)的扇出扇入操作,緩存或消息總線仍然有其用武之地。我僅在它掩蓋了規(guī)劃器錯誤并增加了方差的地方移除了它。一個誠實的承認(rèn):我曾嘗試通過降低 synchronous_commit 來榨取更多性能,但后來撤銷了,因為對于這條路徑來說,寫入語義的風(fēng)險不值得去冒。

八、我保留的可直接復(fù)用的更改

這些是實驗結(jié)束后保留的兩個應(yīng)用層面的部分。

1、應(yīng)用查詢形態(tài)(SQL 預(yù)處理語句),而非 ORM 猜測

參數(shù)順序穩(wěn)定的預(yù)處理語句使得執(zhí)行計劃穩(wěn)定且解析快速。它們也明確了需要索引什么。前面的代碼塊展示了 fetch_slice 和 fetch_trending;那就是實際部署的代碼。

2、適度、常規(guī)的刷新節(jié)奏

刷新 mv_trending 的作業(yè)每隔幾分鐘運行一次,使用 CONCURRENTLY 以保持讀取端的順暢。沒有復(fù)雜的 cron 技巧,沒有失效風(fēng)暴。

九、這對你的團(tuán)隊意味著什么

如果你的緩存只是為了掩蓋源站慢讀,請先嘗試修好源站。

把查詢蓋全,只預(yù)計算真正昂貴的部分。

度量 p95,別看平均。

如果直接走數(shù)據(jù)庫能打敗緩存未命中的長尾,還能減少運維痛苦,就讓更簡單的架構(gòu)贏。

作者丨The Atomic Architect    編譯丨Rio

來源丨網(wǎng)址:https://medium.com/@the_atomic_architect/postgresql-18-killed-my-cache-layer-and-i-am-not-bringing-it-back-764496b2a9a5

責(zé)任編輯:武曉燕 來源: dbaplus社群
相關(guān)推薦

2019-08-14 15:08:51

緩存存儲數(shù)據(jù)

2019-11-11 15:33:34

高并發(fā)緩存數(shù)據(jù)

2024-09-20 21:09:42

2023-03-28 07:59:57

ReactReconciler

2014-06-06 09:52:42

大數(shù)據(jù)

2015-09-01 13:58:25

大數(shù)據(jù)企業(yè)

2022-09-20 14:46:17

PostgreSQL存儲工具

2023-07-14 13:34:34

StableDiffusion模型

2017-06-13 10:15:50

人工智能深度學(xué)習(xí)神經(jīng)網(wǎng)絡(luò)

2020-12-21 09:57:33

無鎖緩存并發(fā)緩存

2017-04-24 11:40:26

大數(shù)據(jù)制造企業(yè)

2024-01-17 09:10:19

2013-04-02 13:04:07

ListView平滑滾

2019-10-21 13:28:38

UbuntuPostgreSQL命令

2020-06-14 09:04:00

前端云計算無服務(wù)器

2024-04-03 09:46:03

無服務(wù)架構(gòu)Web

2024-12-03 14:38:07

CaffeineRedis二級緩存

2016-08-29 21:36:55

nginxWeb緩存

2018-09-12 19:46:53

數(shù)據(jù)庫MySQLRedis

2021-01-30 17:57:23

Python緩存開發(fā)
點贊
收藏

51CTO技術(shù)棧公眾號