小小 Postgres,何以替代 Redis、MongoDB 甚至 ES?

大家好,我是MAI麦造

最近又把之前做到一半的一个小网站维护了起来

之前停下的原因是因为这本来只是一个很小的功能,

但我需要分别写前后端

然后用 redis 做缓存、mongo 做存储、mysql 做后端存储、Elasticsearch 做全文索引的时候...

我是有点蚌埠住了

不过最近我找到了一个优雅的解决方案:postgres!!!

本文部分内容翻译自:Postgres is Too Good (And Why That's Actually a Problem)。 结尾点击阅读原文跳转。

Postgres 能搞定所有这些事

在固有的认知中,一直认为 Postgres "只是一个关系型数据库"。

必须为消息队列、全文检索使用"专业的工具"

但如果你知道:

  • Instagram 在单个 Postgres 实例上扩展到 1400 万用户

  • Discord 处理着数十亿的消息

  • Notion 整个产品都是基于 Postgres 构建的。

这个点的关键在于:他们不再像 2005 年那样使用 Postgres 了。

"专业工具"的隐藏成本

一个典型的"现代"技术栈成本如下:

  • Redis:每月 20 美元

  • 消息队列(Kafka/RebbitMQ):每月 25 美元

  • 搜索服务(Elasticsearch):每月 50 美元

  • 监控 3 个服务:每月 30 美元

  • 总计:$125/月

但这只是托管费用, 真正痛苦是,

维护成本:

  • 三个不同的服务用于监控、更新和调试

  • 不同的扩展模式和故障模式

  • 同时更新多种配置

  • 分离备份和灾难恢复流程

  • 每个服务都有不同的安全考虑因素

开发复杂性:

  • 不同的客户端库和连接模式

  • 处理多个服务之间的部署

  • 系统之间数据不一致

  • 复杂的测试场景

  • 不同的性能调优方法

如果选择自行托管,还需加上服务器管理、安全补丁,以及当 Redis 爆内存时,凌晨 3 点的维护...

而现在,你可以通过管理Postgres服务来处理所有这些!

这听起来有点疯狂,但接下来我将告诉你具体怎么实现:

队列系统

停止额外为 Redis 和 RabbitMQ 的云服务付费。

Postgres 原生支持 LISTEN / NOTIFY ,并且处理任务队列比大多数专用解决方案更出色:

python 复制代码
-- 简单的队列示例

CREATE TABLE job_queue (

id SERIAL PRIMARY KEY,

job_type VARCHAR(50),

payload JSONB,

status VARCHAR(20) DEFAULT 'pending',

created_at TIMESTAMP DEFAULT NOW(),

processed_at TIMESTAMP

);

-- ACID 任务处理

BEGIN;

UPDATE job_queue

SET status = 'processing', processed_at = NOW()

WHERE id = (

SELECT id FROM job_queue

WHERE status = 'pending'

ORDER BY created_at

FOR UPDATE SKIP LOCKED

LIMIT 1

)

RETURNING *;

COMMIT;

这个符合 ACID 标准的任务状态更新功能,

要是用 Redis 去搞,看看要掉多少头发?😏

我用这个方法处理反馈提交、发通知、更新路线图,

一个事务搞定,保证数据一致,不用操心消息代理那些破事儿。

Key-Value 键值存储

Redis 在大多数平台上最低也要 $20/月。

Postgres JSONB 直接用你现有的数据库就行,基本上你需要的功能它都涵盖了:

复制代码
-- Your Redis alternative

CREATE TABLE kv_store (

key VARCHAR(255) PRIMARY KEY,

value JSONB,

expires_at TIMESTAMP

);

-- GIN index for blazing fast JSON queries

CREATE INDEX idx_kv_value ON kv_store USING GIN (value);

-- Query nested JSON faster than most NoSQL databases

SELECT * FROM kv_store

WHERE value @> '{"user_id": 12345}';

这个 @> 操作符是 Postgres 的秘密武器!

比大多数 NoSQL 查询都快,而且数据也稳。

全文搜索

受不了 Elasticsearch 集群的又贵又复杂,那一定要试试Postgres 自带的全文搜索:

sql 复制代码
-- Add search to any table

ALTER TABLE posts ADD COLUMN search_vector tsvector;

-- Auto-update search index

CREATE OR REPLACE FUNCTION update_search_vector()

RETURNS trigger AS $$

BEGIN

NEW.search_vector := to_tsvector('english',

COALESCE(NEW.title, '') || ' ' ||

COALESCE(NEW.content, '')

);

RETURN NEW;

END;

$$ LANGUAGE plpgsql;

-- Ranked search results

SELECT title, ts_rank(search_vector, query) as rank

FROM posts, to_tsquery('startup & postgres') query

WHERE search_vector @@ query

ORDER BY rank DESC;

直接就能搞定模糊匹配词干提取相关性排序,简直不要太方便。

对于搜索,用户能瞬间在标题、描述和评论里找到所需。

根本不用 Elasticsearch 集群,纯粹靠 Postgres 就能发挥它最拿手的功能。

实时功能

还有那些复杂的 WebSocket 基础设施,也可以抛一边。

Postgres LISTEN / NOTIFY 直接给你实时更新,零额外服务:

sql 复制代码
-- Notify clients of changes

CREATE OR REPLACE FUNCTION notify_changes()

RETURNS trigger AS $$

BEGIN

PERFORM pg_notify('table_changes',

json_build_object(

'table', TG_TABLE_NAME,

'action', TG_OP,

'data', row_to_json(NEW)

)::text

);

RETURN NEW;

END;

$$ LANGUAGE plpgsql;

你的用程序监听这些通知,然后向用户推送更新。

完全不需要 Redis 的 pub/sub

ACID 事务

让我震撼的是:Postgres 强到能同时当你的主数据库、缓存、队列、搜索引擎,还搞实时系统。

最牛的是,啥都能保持 ACID 事务!

sql 复制代码
-- 一个事务,多个操作

BEGIN;

INSERT INTO users (email) VALUES ('user@example.com');

INSERT INTO job_queue (job_type, payload)

VALUES ('send_welcome_email', '{"user_id": 123}');

UPDATE kv_store SET value = '{"last_signup": "2024-01-15"}'

WHERE key = 'stats';

COMMIT;

要在 Redis、RabbitMQ 和 Elasticsearch 上搞这些操作,不哭都难。

可扩容的单个数据库

大部分人都不知道:单个 Postgres 实例真能扛住大场面。我指的是每天几百万笔交易,TB 级别的数据量,还有成千上万并发连接。

真实的案例

  • Airbnb:单个 Postgres 集群搞定上百万次预订

  • Robinhood:处理了数十亿笔金融交易

  • GitLab:整个 DevOps 平台都基于 Postgres

而真正厉害的地方是Postgres的架构。

它的垂直拓展做的很棒,但当你需要水平拓展的时候,也有这样成熟的方案可选:

  • Read replicas 只读副本 用来拓展查询

  • Partitioning 大表分区

  • 并发连接池

  • 分布式环境下的逻辑复制

大多数企业根本达不到这些限制。

你可以一直用单个实例,直到你要处理上百万用户或者复杂的分析工作负载,再考虑拓展架构。

从一开始就别瞎折腾了

现在开发里最大的坑就是搞那些花里胡哨的架构。

设计的系统,

要么是为了解决根本没出现过的难题,

要么是按着从未见过的流量去设计,

要么是想着可能永远也达不到的规模。

过度设计的死亡循环:

  1. "咱们总有一天得扩规模呢!"

  2. "快加上 Redis、队列、微服务、多个数据库试试!"

  3. 花几个月时间调试集成问题

  4. 上线后只有 47 个用户

  5. 凉凉...

每月花 200 美元买的基础设施,其实 5 美元的 VPS 就能搞定!

更好的方法是:

  • 用 Postgres 从简单开始试试!

  • 盯着真瓶颈,别瞎折腾那些假的!

  • 碰到真·瓶颈了,就针对性地给某些部件加码!

  • 只在你真的需要解决实际问题的时候才增加复杂性

要知道,你的用户根本不在乎你的架构。

他们关心的是你的产品能不能用,能不能解决他们的问题。

"我"的真实使用体验

我整个后端就一个 Postgres 数据库。

没 Redis,没 Elasticsearch,没消息队列。

就靠 Postgres 从用户认证到实时 WebSocket 通知全搞定!

它给我的系统提供了:

  • 实时更新用户提交的反馈

  • 数千个功能中的全文搜索

  • 后台任务用于发送通知

  • 缓存经常访问的路线图

  • 用键值对存储用户偏好和设置

结果呢?我发布新功能更快了,调试的环节也少了,基础设施成本几乎可以忽略不计。用户提交反馈、搜索功能或者获取路线图更新的实时信息------背后全都是 Postgres 在默默支撑着

这不是空谈了,是实际生产环境中的真实用户和真实数据。

什么时候 Postgres 不够用了?

当然,这不是说那些工具没用!

但当你真的需要的时候,这时你的系统可能是:

  • 每分钟处理超过 10 万个任务啊!

  • 得要亚毫秒级别的缓存响应速度

  • 你正在对 TB 级别的海量数据做复杂分析

  • 你们同时有成千上万用户呢!

  • 你这得全球数据分布还得有特定一致性要求啊

相关推荐
Zzz 小生3 小时前
Claude Code学习笔记(四)-助你快速搭建首个Python项目
大数据·数据库·elasticsearch
斯普信专业组8 小时前
使用Reindex迁移Elasticsearch集群数据详解(下)
大数据·elasticsearch
蓝婴天使11 小时前
基于 React + Go + PostgreSQL + Redis 的管理系统开发框架
react.js·postgresql·golang
Jabes.yang11 小时前
Java求职面试: 互联网医疗场景中的缓存技术与监控运维应用
java·redis·spring security·grafana·prometheus·oauth2·互联网医疗
摇滚侠12 小时前
Spring Boot 3零基础教程,yml配置文件,笔记13
spring boot·redis·笔记
神的孩子都在歌唱12 小时前
PostgreSQL 向量检索方式(pgvector)
数据库·人工智能·postgresql
焰火199913 小时前
[Java][SpringBoot]集成Redis实现Session共享
java·redis
摇滚侠13 小时前
Spring Boot 3零基础教程,整合Redis,笔记12
spring boot·redis·笔记
荣淘淘13 小时前
互联网大厂Java求职面试全景实战解析(涵盖Spring Boot、微服务及云原生技术)
java·spring boot·redis·jwt·cloud native·microservices·interview