当前位置: 首页 > news >正文

别堆砌中间件充门面:我们砍掉Redis/Kafka/ES,整套业务只用PostgreSQL落地实践

引言

很多技术团队存在一种技术误区:把基础设施的丰富性当成炫耀项目的资本,架构里塞满Redis、Kafka、Elasticsearch,觉得技术栈越丰富、组件越多,项目越专业、越有扩展性。但现实往往截然相反——多一套中间件,就多一套监控、备份、故障预案、版本升级、运维告警,系统复杂度指数级上涨。

其实同时维护Redis、Kafka、ES、PostgreSQL四套存储,每月34次告警、3000元基础设施开销,三名工程师大半精力耗费在维护中间件,而非开发客户核心功能。最终团队做出颠覆性决策:移除三大中间件,所有能力全部交由已存在的PostgreSQL承载。迁移后成本腰斩、告警锐减,每周凭空多出14个小时研发人力投入业务迭代。

本文结合该个人团队真实迁移方案,重新封装业务数据表、拆解替换逻辑,结合后端开发视角分析「过早引入专业中间件」的行业通病,同时客观界定PostgreSQL的能力边界,区分什么场景适合简化架构、什么场景必须保留专用组件。

一、臃肿架构的隐性代价:多存储带来的系统性隐患

原四层存储架构:应用服务同时对接Redis、Kafka、ES、PostgreSQL,覆盖缓存、消息推送、异步任务、全文检索四大能力,看似分工清晰,实则埋下多重长期隐患。

  1. 多数据源数据一致性无法保障
    数据库、缓存、索引、消息队列各自持有一份业务数据,无法在同一事务内完成变更。写入数据库后缓存更新延迟、ES索引同步滞后、消息丢失等问题频发,衍生大量偶发、难以复现的隐性bug,长期消耗团队排查精力。
  2. 运维人力被大量占用
    四套存储独立部署、独立监控、独立备份策略、独立故障处理流程。Redis内存溢出、Kafka分区堆积、ES分片失衡、集群断连等问题轮番触发告警,工程师每周固定拿出18小时处理基础设施问题,积压需求长期无法推进。
  3. 无意义的性能冗余
    团队峰值消息仅800条/分钟、检索数据量40万条,完全达不到Kafka、ES、Redis的性能上限,引入高性能中间件只是提前背负复杂度,性能优势完全无法发挥。

多数创业公司、中小型SaaS、内部业务系统都会陷入同类误区:盲目对标大厂技术栈,忽略自身真实业务流量,为了“架构好看”提前引入重型中间件,属于典型过早优化。

二、分模块迁移方案:PostgreSQL替代三大中间件

2.1 Redis 替换:缓存+实时消息推送

原Redis承担两大核心工作:查询结果缓存、用户会话存储、基于Pub/Sub的前端实时通知。

1)缓存层:物化视图+进程内存缓存替代Redis缓存

放弃独立缓存库,高频统计、列表分页数据采用定时刷新物化视图,低频会话数据使用Go内置sync.Map带内存TTL本地缓存,规避网络IO;无需维护Redis集群、解决缓存雪崩、内存溢出、缓存与数据库双写不一致等经典问题。

2)实时通知:LISTEN/NOTIFY 触发器替代Pub/Sub

自定义通知触发器表biz_real_notify,数据插入后自动触发pg_notify推送事件,应用端通过pgx长连接监听频道,实现低延迟实时推送。

CREATEORREPLACEFUNCTIONtrigger_push_notify_event()RETURNStriggerAS$$BEGINPERFORM pg_notify('notify_channel_'||NEW.target_uid::text,row_to_json(NEW)::text);RETURNNEW;END;$$LANGUAGEplpgsql;CREATETRIGGERafter_notify_insertAFTERINSERTONbiz_real_notifyFOR EACH ROWEXECUTEFUNCTIONtrigger_push_notify_event();

Go应用监听逻辑:

ctx:=context.Background()conn,err:=pgx.Connect(ctx,dsn)iferr!=nil{returnerr}deferconn.Close(ctx)// 监听指定用户频道_,_=conn.Exec(ctx,fmt.Sprintf("LISTEN notify_channel_%s",userId))for{notify,err:=conn.WaitForNotification(ctx)iferr!=nil{break}handleUserNotify(notify.Payload)}

延迟从Redis 1ms提升至3~5ms,但业务场景为前端定时刷新仪表盘,毫秒级差异用户完全无感知,省去Redis客户端、集群扩容、内存告警全套运维成本。

2.2 Kafka 替换:任务队列表实现异步消费

以前我们主观认为消息队列必须使用专业流处理组件。实际业务峰值仅800条/分钟,完全可以依靠PostgreSQL行级锁实现可靠任务队列。
新建异步任务表biz_async_task,通过SKIP LOCKED实现多worker无阻塞并发抢占任务,天然规避重复消费、消息丢失,依托数据库事务保证任务与业务数据一致性。

CREATETABLEbiz_async_task(id BIGSERIALPRIMARYKEY,task_typeTEXTNOTNULL,task_payload JSONBNOTNULL,task_statusTEXTNOTNULLDEFAULT'pending',execute_at TIMESTAMPTZDEFAULTNOW(),lock_time TIMESTAMPTZ,worker_tagTEXT);-- 联合索引加速待消费任务筛选CREATEINDEXidx_task_pendingONbiz_async_task(task_type,task_status,execute_at)WHEREtask_status='pending';

worker原子抢占任务SQL,多进程并发无竞争阻塞:

UPDATEbiz_async_taskSETtask_status='running',lock_time=NOW(),worker_tag=$1WHEREid=(SELECTidFROMbiz_async_taskWHEREtask_type=$2ANDtask_status='pending'ANDexecute_at<=NOW()ORDERBYexecute_atASCFORUPDATESKIP LOCKEDLIMIT1)RETURNINGid,task_payload;

测试单库双worker每分钟稳定处理1200条任务,远超业务峰值,具备充足性能冗余。相比Kafka,省去分区、消费者组、消息堆积、日志清理、同步备份一系列运维工作。

2.3 Elasticsearch 替换:原生全文检索+模糊匹配

原有ES仅用于商品名称、描述检索、分类价格过滤、相关性排序,无复杂多维聚合、自定义分词器等高阶需求,PostgreSQL内置tsvector+pg_trgm完全覆盖。
给商品业务表biz_product生成持久化检索向量,搭配GIN索引大幅提升检索速度:

ALTERTABLEbiz_productADDCOLUMNsearch_index_vec tsvector GENERATED ALWAYSAS(to_tsvector('english',COALESCE(name,'')||' '||COALESCE(desc,'')))STORED;-- 全文检索索引CREATEINDEXidx_product_search_vecONbiz_productUSINGGIN(search_index_vec);-- 模糊匹配索引CREATEINDEXidx_product_name_trgmONbiz_productUSINGGIN(name gin_trgm_ops);

检索查询语句,支持关键词匹配、分类过滤、相关性权重排序:

SELECTid,name,ts_rank(search_index_vec,query)ASmatch_rankFROMbiz_product,to_tsquery('english',$1)queryWHEREsearch_index_vec @@ queryANDcategory_id=$2ORDERBYmatch_rankDESCLIMIT20;

40万条商品冷查询平均30ms,缓存热数据下中位数8ms,虽然p99延迟高于ES,但完全满足后台检索、商户查询业务需求。

三、简化架构落地后真实数据对比

新旧架构并行运行六周后完全下线中间件,量化收益直观体现简化架构的价值:

指标多中间件架构纯PostgreSQL架构变化分析
月度基础设施成本4200美元1800美元砍掉Redis、Kafka、ES三套集群服务器,成本削减57%
月度告警次数34次7次仅保留数据库基础监控,消除中间件各类异常告警
每周运维耗时18小时4小时每周释放14小时研发人力,回归业务功能开发
检索p99延迟22ms41ms小幅性能衰减,业务无感知
通知推送p99延迟1ms6ms延迟小幅上涨,不影响前端交互

团队工程负责人最在意的并非成本降低,而是每周多出的14小时研发时间。迁移完成后,团队直接落地积压8个月的客户核心需求,客户反馈显著提升——这是单纯性能指标无法衡量的长期收益。

简化后架构极简:应用服务仅对接一套PostgreSQL,缓存、消息、任务、检索全部依托数据库内置能力实现,统一备份、统一监控、统一故障排查流程,出现问题无需跨多组件定位。

四、客观边界:不是所有场景都适合砍掉中间件

本文方案核心思想是拒绝无意义的架构复杂化,而非全盘否定Redis、Kafka、Elasticsearch,必须清晰划分适用边界:

适合仅用PostgreSQL的场景

  1. 中小型SaaS、内部管理系统、数据监测平台(如雷达PDF业务),峰值流量数千/分钟以内;
  2. 对延迟无亚毫秒硬性要求,可接受5~50ms区间响应;
  3. 追求低运维成本、小团队,无专职中间件运维工程师;
  4. 需要强数据一致性,无法容忍多数据源数据偏差。

必须保留专用中间件的场景

  1. Kafka:海量事件流、多独立消费者、需要长期消息回放、每秒数万条消息峰值;
  2. Elasticsearch:海量日志检索、复杂多维聚合、自定义分词、上亿级数据全文检索;
  3. Redis:核心前台高并发秒杀、百万QPS、硬性要求亚毫秒延迟、大规模内存计数器。

绝大多数中小团队的业务流量,远达不到需要专用中间件支撑的规模,提前引入只会徒增负担。盲目照搬大厂架构,本质是没有基于自身业务负载做技术选型。

结语

基础设施的价值是支撑业务,而非用来展示技术广度。不用为了架构看上去“专业”堆砌Redis、Kafka、Elasticsearch。当业务体量尚未达到专用中间件的性能门槛,PostgreSQL完全可以一站式承载缓存、消息、异步任务、全文检索全部能力,大幅降低运维复杂度、释放研发人力。

技术优雅的本质不是组件繁多,而是恰到好处的简单。只有当业务负载明确证明单库无法支撑时,再按需引入专业中间件,才是成熟、务实的架构选型思路。

http://www.jsqmd.com/news/1211100/

相关文章:

  • 居住体验与环保健康的新体验-----SPC地板
  • 雷达中国官方售后服务中心|服务热线及全部网点地址权威信息通知(2026年7月最新) - 亨得利钟表维修中心
  • 人形机器人技术瓶颈解析:从感知控制到实用化的核心挑战
  • 六位半万用表:高精度电子测量的核心技术解析
  • Flow-X:AI驱动的SDLC全流程自动化实践
  • 2026 年更新:东胜优秀的公园景观草坪厂商哪家可靠,别再乱浇水了!草坪保鲜的秘密都在这 - 企业推荐管【认证】
  • Mythos能力跃迁:动态推理图谱与跨文档验证技术解析
  • Mapbox控件系统开发指南与实战技巧
  • C++实现管道过滤器架构:从数据处理到日志处理实战
  • Spark分布式时序预测实战:从特征工程到模型服务
  • XULA迅莱 XLMG-101全数字加密5G WIFI会议系统核心功能与场景实测
  • FastAPI依赖注入实战:提升Python Web开发效率
  • 美度中国官方售后服务中心|服务热线及门店地址权威信息公示(2026年7月更新) - 亨得利官方服务中心
  • Windows蓝屏死机(BSOD)故障诊断与解决方案大全
  • 【2027最新】基于SpringBoot+Vue的三国之家网站管理系统源码+MyBatis+MySQL
  • PHP开发者进阶:从基础到架构的成长路线
  • Prometheus 监控 NSQ 全栈实战:从消息堆积到心跳超时的实时可观测性
  • ABAP 里的请求路由版图,为什么它不像 Spring MVC 只有一个 HandlerMapping
  • 亲身探访重庆百达翡丽官方售后服务中心|最新维修地址与客服电话(2026年7月最新) - 百达翡丽官方售后中心
  • PHP开发全攻略:从入门到精通的必备资源与工具
  • 从软件到硬件:H桥电路设计实战与PCB布局优化指南
  • AI模型提取攻击全解析:从白盒到黑盒的实战技术与防御措施
  • 第二篇:《测试指挥官:可视化单题自测框架(含 assert 实操)》
  • 高通汽车域控制器电源设计:挑战与解决方案
  • 第8讲:批量格式转换与尺寸调整——统一你的图片规格
  • 一线观察:合肥宣传片品牌的真实表现
  • UniApp开发Android TV应用全攻略
  • 超声波液位差计选型指南与技术趋势解析
  • 数据工程师的SVD实战指南:从矩阵分解到生产部署
  • 浪琴中国官方售后服务中心|全部地址与售后服务热线权威信息公示(2026年7月最新) - 浪琴服务中心