Postgres 杀疯了,堪称 “六边形战士”,还要 Redis 干啥?

我们需要谈谈困扰我几个月的事情。我一直看到独立黑客和初创公司创始人疯狂地拼凑各种技术栈,用 Redis 做缓存,用 RabbitMQ 做队列,用 Elasticsearch 做搜索,还有用 MongoDB......为什么?

我也犯过这种错误。当我开始构建UserJot(我的反馈和路线图工具)时,我的第一反应是规划一个"合适的"架构,为所有功能提供独立的服务。然后我停下来问自己:如果我把所有功能都用 Postgres 来做会怎么样?

事实证明,房间里有一头大象,但没人愿意承认:

Postgres 几乎可以做到这一切。

而且它的效果比你想象的还要好。

"Postgres 无法扩展"的谬论正在让你损失金钱?

让我猜猜------有人告诉你,Postgres"只是一个关系数据库",需要专门的工具来完成专门的工作。我以前也是这么想的,直到我发现 Instagram 可以在单个 Postgres 实例上扩展到 1400 万用户。Discord 处理数十亿条消息。Notion 的整个产品都是基于 Postgres 构建的。

但问题是:他们不再像 2005 年那样使用 Postgres。

队列系统

别再为 Redis 和 RabbitMQ 付费了。Postgres 原生支持LISTEN/NOTIFY并且比大多数专用解决方案更好地处理作业队列:

sql 复制代码
-- Simple job queue in pure Postgres
CREATETABLE job_queue (
    id SERIAL PRIMARY KEY,
    job_type VARCHAR(50),
    payload JSONB,
    status VARCHAR(20) DEFAULT'pending',
    created_at TIMESTAMPDEFAULT NOW(),
    processed_at TIMESTAMP
);

-- ACID-compliant job processing
BEGIN;
UPDATE job_queue
SET status ='processing', processed_at = NOW()
WHERE id = (
    SELECT id FROM job_queue
    WHERE status ='pending'
    ORDERBY created_at
    FORUPDATESKIP LOCKED
    LIMIT 1
)
RETURNING *;
COMMIT;

这让你无需任何额外的基础设施就能实现 Exactly-Once 的处理。不妨试试用 Redis 来实现,会让你很抓狂。

在 UserJot 中,我正是使用这种模式来处理反馈提交、发送通知和更新路线图项目。只需一次事务,即可保证一致性,无需消息代理的复杂性。

键值存储

Redis 在大多数平台上的最低价格为 20 美元/月。Postgres JSONB 已包含在您现有的数据库中,可以满足您的大部分需求:

sql 复制代码
-- Your Redis alternative
CREATETABLE 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
WHEREvalue @>'{"user_id": 12345}';

运算符@>是 Postgres 的秘密武器。它比大多数 NoSQL 查询更快,并且数据保持一致。

全文搜索

Elasticsearch 集群价格昂贵且复杂。Postgres 内置的全文搜索功能非常出色:

sql 复制代码
-- Add search to any table
ALTERTABLE posts ADDCOLUMN search_vector tsvector;

-- Auto-update search index
CREATEOR REPLACE FUNCTION update_search_vector()
RETURNStriggerAS $
BEGIN
    NEW.search_vector := to_tsvector('english',
        COALESCE(NEW.title, '') ||' '||
        COALESCE(NEW.content, '')
    );
    RETURNNEW;
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
ORDERBY rank DESC;

这可以处理模糊匹配、词干提取和相关性排名。

对于 UserJot 的反馈搜索,此功能可让用户跨标题、描述和评论即时查找功能请求。无需 Elasticsearch 集群 - 只需使用 Postgres 即可发挥其优势。

实时功能

忘掉复杂的 WebSocket 基础架构吧。Postgres LISTEN/NOTIFY无需任何附加服务即可为您提供实时更新:

sql 复制代码
-- Notify clients of changes
CREATEOR REPLACE FUNCTION notify_changes()
RETURNStriggerAS $
BEGIN
    PERFORM pg_notify('table_changes',
        json_build_object(
            'table', TG_TABLE_NAME,
            'action', TG_OP,
            'data', row_to_json(NEW)
        )::text
    );
    RETURNNEW;
END;
$ LANGUAGE plpgsql;

您的应用程序会监听这些通知并向用户推送更新。无需 Redis 的发布/订阅机制。

"专业"工具的隐性成本

我们来算一下。一个典型的"现代"堆栈的成本是:

  • Redis:20美元/月
  • 消息队列:25美元/月
  • 搜索服务:50美元/月
  • 监控 3 项服务:30 美元/月
  • 总计:每月 125 美元

但这还只是托管成本。真正的痛点在于:

运营开销:

  • 三种不同的服务用于监控、更新和调试
  • 不同的缩放模式和故障模式
  • 需要维护多种配置
  • 单独的备份和灾难恢复程序
  • 每项服务的安全考虑因素不同

开发复杂性:

  • 客户端库和连接模式
  • 多个服务的部署
  • 间数据不一致
  • 的测试场景
  • 的性能调优方法

如果您自行托管,请添加服务器管理、安全补丁以及当 Redis 决定消耗所有内存时不可避免的凌晨 3 点调试会话。

Postgres 使用您已经管理的单一服务来处理所有这些。

扩展的单一数据库

大多数人可能没有意识到:单个 Postgres 实例就能处理海量数据。我们指的是每天数百万笔交易、数 TB 的数据以及数千个并发连接。

真实世界的例子:

  • Airbnb:单个 Postgres 集群处理数百万个预订
  • Robinhood:数十亿笔金融交易
  • GitLab:Postgres 上的整个 DevOps 平台

Postgres 的架构魅力非凡。它被设计成具备极佳的垂直扩展能力,而当你最终需要水平扩展时,它也有以下成熟的方案可供选择:

  • 用于查询扩展的读取副本
  • 大表分区
  • 并发连接池
  • 分布式设置的逻辑复制

大多数企业从未达到过这些限制。在处理数百万用户或复杂的分析工作负载之前,单个实例可能就足够了。

将此与管理所有以不同方式扩展的单独服务进行比较 - 您的 Redis 可能会耗尽内存,而您的消息队列则会遇到吞吐量问题,并且您的搜索服务需要完全不同的硬件。

从第一天起就停止过度设计

现代开发中最大的陷阱是架构式的"宇航员"。我们设计系统时,面对的是我们从未遇到过的问题,我们面对的是从未见过的流量,我们可能永远无法达到的规模。

过度设计循环:

  1. "我们可能有一天需要扩大规模"
  2. 添加 Redis、队列、微服务、多个数据库
  3. 花费数月时间调试集成问题
  4. 向 47 位用户推出
  5. 每月支付 200 美元购买可在 5 美元 VPS 上运行的基础设施

与此同时,您的竞争对手的发货速度更快,因为他们在需要分布式系统之前并没有管理它。

更好的方法:

  • 从 Postgres 开始
  • 监控实际的瓶颈,而不是想象的瓶颈
  • 当达到实际极限时扩展特定组件
  • 仅在解决实际问题时才增加复杂性

你的用户并不关心你的架构。他们关心的是你的产品是否有效,是否能解决他们的问题。

当你真正需要专用工具时

别误会我的意思------专用工具自有其用处。但你可能在以下情况之前不需要它们:

  • 您每分钟处理 100,000 多个作业
  • 您需要亚毫秒级的缓存响应
  • 您正在对数 TB 的数据进行复杂的分析
  • 您有数百万并发用户
  • 您需要具有特定一致性要求的全局数据分布

如果您在公众号上阅读强哥这篇文章,那么您可能还没有到达那一步。

为什么这真的很重要

让我大吃一惊的是:Postgres 可以同时充当您的主数据库、缓存、队列、搜索引擎和实时系统。同时还能在所有方面保持 ACID 事务。

sql 复制代码
-- One transaction, multiple operations
BEGIN;
    INSERT INTO users (email) VALUES ('[email protected]');
    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 并不引人注目。它没有华丽的网站,也没有在 TikTok 上爆红。但几十年来,在其他数据库兴衰更迭之际,它一直默默地支撑着互联网。

选择简单、可靠且有效的技术是有道理的。

下一个项目的行动步骤

  1. 仅从 Postgres 开始- 抵制添加其他数据库的冲动
  2. 使用 JSONB 实现灵活性- 借助 SQL 的强大功能,您可以获得无架构的优势
  3. 在 Postgres 中实现队列------节省资金和复杂性
  4. 仅当达到实际极限时才添加专用工具- 而不是想象中的极限

我的真实经历

UserJot 的构建是这一理念的完美测试案例。它是一个反馈和路线图工具,需要:

  • 提交反馈时实时更新
  • 针对数千个功能请求进行全文搜索
  • 发送通知的后台作业
  • 缓存经常访问的路线图
  • 用于用户偏好和设置的键值存储

我的整个后端只有一个 Postgres 数据库。没有 Redis,没有 Elasticsearch,没有消息队列。从用户身份验证到实时 WebSocket 通知,一切都由 Postgres 处理。

结果如何?我的功能交付速度更快,需要调试的部件更少,而且基础设施成本也降到了最低。当用户提交反馈、搜索功能或获取路线图变更的实时更新时,一切都由 Postgres 完成。

这不再只是理论上的。它正在实际生产中,通过真实的用户和真实的数据发挥作用。

令人不安的结论

Postgres 或许好得过头了。它功能强大,以至于大多数其他数据库对于 90% 的应用程序来说都显得多余。业界一直说服我们,所有事情都需要专门的工具,但或许我们只是把事情弄得比实际需要的更难。

你的初创公司不必成为分布式系统的样板。它需要为真正的人解决真正的问题。Postgres 让你专注于此,而不是照看基础设施。

因此,下次有人建议添加 Redis 来"提高性能"或添加 MongoDB 来"提高灵活性"时,请问他们:"您是否真的先尝试过在 Postgres 中执行此操作?"

答案可能会让你大吃一惊。我知道,当我完全在 Postgres 上构建UserJot时,它就一直运行顺畅。

本文为译文,英文原文地址(可能需要使用魔法访问):dev.to/shayy/postg...
相关推荐
wmze36 分钟前
InnoDB存储引擎
后端
lifallen1 小时前
Java BitSet类解析:高效位向量实现
java·开发语言·后端·算法
子恒20052 小时前
警惕GO的重复初始化
开发语言·后端·云原生·golang
daiyunchao2 小时前
如何理解"LLM并不理解用户的需求,只是下一个Token的预测,但他能很好的完成任务,比如写对你想要的代码"
后端·ai编程
Android洋芋3 小时前
SettingsActivity.kt深度解析
后端
onejason3 小时前
如何利用 PHP 爬虫按关键字搜索 Amazon 商品
前端·后端·php
令狐冲不冲3 小时前
常用设计模式介绍
后端
Java水解3 小时前
深度解析MySQL中的Join算法:原理、实现与优化
后端·mysql
一语长情3 小时前
关于Netty的DefaultEventExecutorGroup使用
java·后端·架构
易元3 小时前
设计模式-状态模式
后端·设计模式