SWE / Infrastructure · System Design

亿级POI附近搜索:地理分区、类型过滤和精确TopN

先召回地理候选,再按距离排序,必须证明何时可以停止扩大范围。

题目重点:先召回地理候选,再按距离排序,必须证明何时可以停止扩大范围。

题意与假设

这道练习题保留了面经中值得训练的核心约束,并将需要澄清的条件单独列出。现场拿到变体时,先和面试官确认这些条件。

  • 全球数亿place,location经纬度、place_type;查询某位置某类型最近N个。训练距离用球面大圆距离,非驾车ETA。
  • 允许索引延迟与读副本弱一致,精确TopN或近似TopN须先选。geohash/H3只是召回划分,不等于距离排序;不强制某具体库版本。

解题路线

  1. place主表保存ID、type、location/version;空间cell倒排按cell+type保存place ID与坐标。查询定位cell与周边rings,类型过滤减少候选,主表/索引版本需要保证删除及坐标迁移不返回旧数据。
  2. 候选用Haversine距离并维护大小N最大堆。精确停止需对未扫描cell求到查询点的距离下界,当所有未扫cell下界≥当前第N距离才停;“扩一圈找到N项”仅是启发式,不能保证最近。
  3. 高密城区用更细cell或自适应树,稀疏区域扩圈可能扫描巨量范围。type稀少时预按类型建空间索引;按cell仅分片会使热门商业区热点,读缓存/多副本和类型子分区分担。
  4. 全球查询注意180°经线wrap及极区,经纬度差不能直接当欧氏公里数;球面距离输入需夹住浮点舍入的合法范围。候选limit触发时返回近似标识/继续分页,不能截断后仍承诺精确。
  5. 缓存key含量化location、type、N和索引版本/TTL;量化会改变精确结果,可缓存候选而实时算距离,或明确近似。读后过滤已关闭place可能使N不足,需要再补候选。

手动走一遍

查询点靠cell边,隔壁cell的place可能比本cell更近,所以本cell有N项也不能停止。179.9°与−179.9°经度附近实际很近,不应算359.8°差。若每条索引记录64B,1亿条约6.4GB原始单份,实际树/倒排、副本和属性远超此数字,需分别估算。

规模与取舍

召回K项距离O(K)、TopN heap O(KlogN)、内存O(N+候选页)。精确扩展最坏可扫全库,低延迟需空间分布/索引与可接受近似预算,不能承诺任意稀疏数据常数查询。

易错点与追问

容易失分的边界

  • 把cell字符串字典序当距离远近。
  • 城市平面近似直接用于全球和极区。
  • 移动place只写新cell未删旧cell造成重复/旧位置。

继续深挖

  • 要求驾车时间最近时,球面距离能作怎样的候选下界?
  • 实时营业状态过滤和地理TopN索引分离时怎样避免结果数不足?
✓已复制微信号!