a.Blender Page cache:由于京东搜索符合互联网的二八原则,百分之二十热门查询频度非常之高,占用每天的搜索数据请求量百分之八十,针对这一点特点,京东搜索第一级缓存以查询请求为KEY,将返回给用户的页面作为value。对于完成相同的请求,直接从缓冲页面返回结果。页面的缓存策略上线意识,缓冲命中率就接近了30%,基本解决了当时的性能问题。
b.Merge Page cache:随着业务的发展,京东排序结果需要针对不同京东用户个性化订制,导致请求中会包含用户的user pin。如果将user pin放入缓存作为key,会导致blender cache的key数量暴增,不但京东服务器需要超大的缓存空间,同时服务器缓存的命中率也会极低,最终会导致线上京东个性化服务系统的体验满意度降低。为了解决这个系统问题,将user_pin加入key,但是value只保存京东排序好的商品id,这样需要的缓存空间远远小于blender cache。当命中缓存后,调用detail直接进行结果包装。为了进一步提高缓存命中率,利用用户京东搜索的翻页习惯,即离线统计出用户的翻页数TP99,然后在value中缓存这些页面涉及到所有的商品id,从实践效果来看,用户后续的翻页请求大部分会命中cache。
c.在深入分析了业务的京东排序需求之后,我们发现拉取倒排的结果只和“查询词”&筛选条件“,作为KEY的方式对其进行一次缓存。
虽然拉取京东倒排结果缓存的key很快就解决了,但是我们在解决Value的存储时遇到了两个问题:1)拉取倒排的结果非常之多,导致缓存过大;2)对此结果的缓存数据,会降低京东实时索引的时效性性质。
对于问题1),在分析了京东业务之后,对需要缓存的信息进行了大量面积的精简并采用压缩存储,最终将一个查询的缓存控制在0.5M以下,这样京东搜索缓存数据就响应时间很快。 对于问题2),我们将拉取倒排结果数据分为两部分,第一部分是从全量索引拉取倒排结果,第二部分是从实时索引拉取倒排的结果。为了和全量索引的更新频率保持同步,我们把第一部分的京东数据进行缓存的周期置一天。对于第二部分数据,由于是京东增量结果永远少于全量结果(一般增量只有全量5%不到),每次缓存都进行了实时计算规则。这就是图3中的doc cache机制。从实践中来看,命中doc cache的响应时间比未命中的降低了1-2个数量级。将来随着增量结果的积累,如果实时拉取倒排结果成为性能瓶颈,可以对增量索引分段也进行缓存。
2. 截断策略
对于有些京东比较热门的查询,由于其搜索结果比较多的情况下:比如”男鞋“、之类的query,原始查询结果几千万个请求,如果对这些结果挨个进行处理,性能会大大降低非常差。同时,从用户角度去分析,一个查询只有排在最前面的的结果用户才有意义。通过分析京东用户的翻页次数,可能得到阶段保留的TOPN结果,如何保证阶段不影响用户的体验的呢?首先我们对商品建立一个离线的系统模型,即为每个商品计算出一定的质量分数据,然后在索引阶段,将所有商品按照质量分高低进行一次排序,保证在倒数链条中,排在前面的商品质量分总是高于后面的商品。在线前往后拉取倒排过程中,如果结果数达到10*TOPN时,停止拉取倒排,随后对结果计算文本相关性,按照文本相关性啦出TOPN个,截断算法上线前后,虽然KPI质量无明显很大变化,但是对的查询结果性能提升了一个数量级别差异。