搞了7年Geo,我才敢告诉你:ES geo 架构不是万能药,用错就是灾难

搞了7年Geo,我才敢告诉你:ES geo 架构不是万能药,用错就是灾难

干这行七年,见过太多老板和技术总监为了炫技,或者为了应付面试,强行上 ES geo 架构。结果呢?查询慢得像蜗牛,集群崩得连亲妈都不认识。今天我不讲那些虚头巴脑的理论,就聊聊我踩过的坑,还有那些真金白银买来的教训。

很多人一听到“地理空间”,脑子里就是地图、定位、附近的人。没错,Elasticsearch 确实能干这个,但它不是为高频复杂的地理计算设计的。如果你要做的是简单的“附近5公里”,ES 还能应付;要是搞复杂的轨迹分析、多边形叠加,趁早换数据库,别在这棵树上吊死。

先说价格。别一听 ES 就想到免费开源,那是陷阱。为了支撑稳定的 geo 查询,你得开高级订阅,还得买足够的机器。我见过一个项目,数据量不大,但为了追求低延迟,搞了个 10 节点的集群,每月云费用直接飙到两万块。其实,如果只是简单的经纬度匹配,用 PostGIS 配合 PostgreSQL,硬件成本能省下一大半,性能还更稳。ES 的优势在于全文检索和 geo 的结合,比如“搜索附近的咖啡店”,这时候它的倒排索引优势才出来。如果你只查坐标,那就是杀鸡用牛刀,还刀卷刃了。

再聊聊避坑。第一个大坑,就是字段类型选错。很多人把 geo_point 当成普通 double 存,结果查询全乱套。geo_point 必须用特定的格式,经纬度顺序不能反,单位不能乱。第二个坑,是索引结构。别把所有数据都塞进一个索引里。geo 数据更新频率低,但查询频率高,建议冷热分离。热数据放 SSD,冷数据放 HDD,这样既省钱又快。我有个客户,以前把所有历史轨迹都压在同一个索引,查询一次要 5 秒,后来按月份分片,查询速度直接提升到 200 毫秒以内。

还有一个容易被忽视的点,就是聚合查询。很多人喜欢用 geo_distance_aggregation 来统计附近有多少人,这在数据量小的时候还行,一旦数据过亿,CPU 直接爆满。这时候,你得考虑预计算。比如,提前把数据按网格(Grid)分好,查询时直接查网格,而不是实时计算距离。虽然精度会损失一点点,但速度提升是指数级的。对于大多数业务场景,这点精度损失完全可以接受。

说到 es geo 架构,很多人忽略了一个核心问题:数据一致性。geo 数据往往来自移动端,网络不稳定,数据乱序是常态。ES 不是强一致性数据库,如果你要求每条轨迹必须按时间顺序严格排列,那 ES 可能会让你失望。这时候,你需要在应用层做排序,或者使用 ES 的 sort 功能,但这会增加查询开销。我的建议是,在写入时尽量保证时间戳准确,查询时再二次校验。

最后,谈谈心态。别迷信技术栈。ES 很强,但它不是银弹。在决定上 es geo 架构之前,先问自己三个问题:数据量有多大?查询频率多高?对精度的要求有多严?如果答案都是“小、低、高”,那 ES 可能不是你的菜。反之,如果数据量大、查询复杂、且需要结合全文检索,那 ES 才是你的最佳拍档。

我见过太多团队,为了赶进度,随便搭个 ES 集群就上线,结果上线第一天就崩了。修复这种问题,比从头开发还累。所以,前期规划一定要做足。别等到线上出事了,才想起来找专家救火。那时候,你的业务已经停摆,损失惨重。

总之,es geo 架构是个好工具,但用不好就是毒药。希望我的这些经验,能帮你少踩几个坑,多省点钱。毕竟,技术是为业务服务的,不是为了炫技的。