Elasticsearch本为搜索而生,非事务型数据库,强行作为主数据源将导致一致性缺失、运维复杂、查询受限等问题,应回归其索引定位,选用合适系统保障数据正确性。
我知道“数据库”“Elasticsearch”听起来像是程序员才懂的黑话,但其实它跟咱们每天刷的淘宝、点的外卖、看的小红书都息息相关。
来自一个叫詹姆斯·布莱克伍德-塞维尔的技术大牛,在2025年9月18日发表在ParadeDB官网的一篇爆款长文——《Elasticsearch从来就不是数据库》。这位老哥可不是普通码农,他是ParadeDB的联合创始人之一,之前在多家硅谷科技公司做过分布式系统架构师,对搜索和数据存储有着非常深的理解。他写这篇文章,是想给那些“误把搜索引擎当数据库用”的团队敲个警钟。
先说重点:Elasticsearch从出生那天起,就不是一个用来当主数据库的工具。
它的本质是什么?
是一个建立在Apache Lucene之上的全文搜索引擎API。
你可以把它想象成图书馆里的索引卡片系统——它能帮你飞快找到某本书在哪一排哪一架,但它本身并不负责保管这本书的完整性、版本更新或者借阅记录的事务处理。可现实是什么呢?过去十年里,太多团队为了图省事,干脆就把Elasticsearch当成唯一的数据存储点了。
一开始只是做个搜索功能,后来发现数据已经在里面了,干嘛还要再存一遍到MySQL或PostgreSQL呢?于是他们悄悄地把系统的“真相来源”换成了Elasticsearch,结果埋下了无数坑。
你可能会问,那到底什么叫“数据库”?这里说的数据库,指的是能作为你应用核心数据源的那种系统,也就是所谓的“系统之真理所在”。比如你现在下单买一杯奶茶,订单信息、用户资料、库存扣减这些操作,必须保证要么全部成功,要么全部失败,不能出现“钱扣了但奶茶没做”的情况。这就叫事务交易一致性,而这正是传统关系型数据库如PostgreSQL(连续三年被评为开发者最爱的数据库)、MySQL这些家伙最擅长的地方。而Elasticsearch呢?它压根就没设计这个能力。
问题最早出现在哪里?就在“同步”这两个字上。
理想情况下,你的数据应该存在PostgreSQL这样的正经数据库里,然后通过某种机制(比如CDC、Kafka、Logstash)把数据复制一份到Elasticsearch里做搜索用。这时候Elasticsearch只是个“影子索引”,出了问题也不怕,大不了重新同步一次。
但很多团队嫌麻烦,觉得两边写太复杂,干脆只往Elasticsearch里写,认为这样架构更简单。殊不知,这一下就把整个系统的根基动摇了。
我们来看看具体有哪些雷区:
1、首先是事务支持几乎为零。
在PostgreSQL中,你可以开启一个事务,同时插入订单和减少库存,如果其中一步失败,整个操作都会回滚。但在Elasticsearch里,每个文档的写入是独立的,没有原子性保障。假如你有两个相关的文档需要一起更新,其中一个成功另一个失败,系统不会自动纠正,也不会告诉你出错了。时间一长,数据就会慢慢变得混乱不堪,这种“半截子操作”积累起来,轻则报表不准,重则资损百万。
2、再说读取的问题。
Elasticsearch有两种读方式:一种是通过ID精确获取文档,这还算靠谱;另一种是通过搜索查询,这就坑了。因为搜索查的是Lucene的段(segment),而这些段是每隔一秒或几秒才刷新一次。也就是说,你刚写进去的数据,可能要等一会儿才能被搜到。这在搜索场景下可以接受,毕竟用户体验上延迟几百毫秒没关系。但如果这是你的主数据库,用户下单后刷新页面却看不到自己的订单,那可是要出大事的!
3、接下来是 schema变更的噩梦。
你想改个字段类型?在PostgreSQL里一句ALTER TABLE搞定。但在Elasticsearch里,一旦索引 mapping 定下来就不能改了,唯一的办法是新建一个索引,把所有数据重新导入一遍,也就是所谓的reindex。如果你的数据量很大,这个过程不仅耗时耗资源,还容易出错。更可怕的是,当你把Elasticsearch当作唯一数据源时,这次迁移就是在刀尖上跳舞,没有任何退路,只能祈祷别断电、别宕机。
4、然后是查询能力的局限。
你以为能在Elasticsearch里写SQL那样的复杂查询?太天真了。它虽然有Query DSL、ES|QL、SQL接口等各种语法,但本质上还是基于倒排索引的检索模型,根本不支持真正的JOIN操作。
比如你要查“评分超过4.5分且评论数大于50的商品”,正常做法应该是把商品表和评论表连起来算平均值。但在Elasticsearch里,你只能提前把评论数据冗余进商品文档里,每次有人评论就得去更新对应的商品记录,效率极低还容易冲突。这不是数据库该干的事,而是典型的“为了适应工具而扭曲业务逻辑”。
5、还有可靠性问题。
数据库都有WAL(预写日志)机制,确保一旦提交就不会丢数据。Elasticsearch也有translog,但它只保证单个文档的持久化,并不提供跨文档的事务边界。一旦集群崩溃重启,没法像数据库那样精准恢复到最后一个一致状态。这意味着你的“系统之真理”其实是脆弱的,一场故障就能让你的数据进入未知领域。
6、运维方面更是挑战重重。
Elasticsearch依赖JVM,内存调优极其敏感;分片不平衡会导致性能骤降;升级过程中稍有不慎就会卡住请求;大规模reindex还会挤占生产流量。相比之下,PostgreSQL这类数据库的设计哲学就是稳定可靠,哪怕性能不是最快,也要保证数据不出错。而Elasticsearch的优先级是“速度与相关性”,这是搜索引擎的需求,不是数据库的要求。
所以说,把Elasticsearch当成主数据库,表面上看省了一层同步,实际上换来的是更高的工程成本、更大的运维压力、更低的数据可信度。你以为简化了架构,其实是把复杂性转移到了最不该复杂的地方——你的核心数据层。
那正确的姿势是什么?答案很简单:让专业的人做专业的事。
用PostgreSQL或MySQL当你的主数据库,保证数据正确性和事务完整;
用Elasticsearch作为只读索引,专攻搜索和分析。
总结一下:Elasticsearch是个伟大的搜索工具,但它不是数据库。把它当数据库用,就像拿冲锋枪去绣花——威力十足,精度全无。技术选型不能只看短期便利,更要考虑长期可维护性和数据安全。