知识卡片

Deprecated但仍可用的API埋下的隐藏坑:兼容性妥协容易让人沿用旧写法而踩坑

普通读书笔记卡

内容

Elasticsearch 2.x把Filtered Query标记为不推荐使用(deprecated),官方建议改用bool查询里的must和filter参数来实现同样的效果,但deprecated不等于完全禁用——2.x版本里Filtered Query依然是可以正常使用的,这个”能用但不建议用”的过渡状态,恰恰成了百姓网升级过程中一个很深的坑。原因在于百姓网当时面临的是1.x和2.x集群同时共存、滚动式升级的场景,为了实现平滑升级、减少对现有查询代码的改动,团队很自然地选择继续沿用Filtered Query这个写法(反正2.x里还能正常跑),结果这个选择成为了导致前述GC死循环问题的两个深坑之一——切换到bool查询代替filtered之后,GC问题得到了明显缓解。团队自己也坦言,这类问题”算不上是Bug”,Filtered Query官方文档也只写了deprecated而不是不可用,正是这种表面上”技术上没有任何阻拦”的暧昧状态,反而最容易让人在需要平滑过渡、图省事的场景下,无意识地继续沿用一个实际上已经暗藏问题的旧写法。这个案例给出了一条对待”deprecated但仍可用”这类API状态的重要警示:deprecated这个标记本身传递的信息,往往不只是”未来某个版本会被移除”这么简单,很多时候它同时也在暗示”这个旧实现路径在底层已经和新版本的其他优化路径产生了摩擦或不兼容”,即使当前版本里它依然能跑通、看起来没有报错,也不代表它的运行时行为和性能特征和被推荐的新写法是等价的——尤其是在版本升级、需要兼顾新旧兼容的场景下,”能不能继续用旧写法”和”应不应该继续用旧写法”是两个完全不同的问题,图省事沿用deprecated但仍可用的旧接口,恰恰是升级过程中最容易被忽视、却可能造成深层次问题的雷区。

参考来源

- 位置:《高可用架构(第1卷)》第6章《大数据与数据库》"6.3 百姓网Elasticsearch2.x升级之路"节,"6.3.2 升级之路"(源文件:_epub-src/OEBPS/Text/Chapter6_3_3.xhtml) - 结论依据:原文说明"我们对1.x和2.x集群加上了版本区分。在2.x的情况下,我们对查询进行了强制修改。修改办法就是上面提到的Filtered Query变更……GC问题得到缓解……虽然它们算不上是Bug,然而在filtered query只是deprecated,而不是不能使用的情况,也是十分坑人的,如果遇到需要多集群滚动式升级的情况……可能就会沿用filtered query,以便能平滑升级,然后就会掉进深坑而不能自拔",直接支撑本卡片结论。 - 原始内容:虽然它们算不上是Bug,然而在filtered query只是deprecated,而不是不能使用的情况,也是十分坑人的,如果遇到需要多集群滚动式升级的情况(比如我们),可能就会沿用filtered query,以便能平滑升级,然后就会掉进深坑而不能自拔。