Uber利用Golang构建高性能地理查询服务实践( 三 )

其次 , 计算密集型服务 。 地理围栏查找需要占用大量CPU的多边形点算法 。 尽管Node.js可以很好地用于他I/O密集型服务 , 但由于Node具有解释型和动态类型化的性质 , 因此并不是很适合计算密集型的服务 。

最后 , 需要无中断后台加载 。 为确保拥有最新的地理围栏数据来执行查找 , 服务必须不断在后台刷新来自多个数据源内存中的地理围栏数据 。 由于Node.js是单线程的 , 因此后台刷新会占用较长时间的CPU(例如 , CPU密集型JSON解析工作) , 从而导致查询响应时间突增 。 而Golang的协程可以支持多CPU运行 , 配合前台查询并行运行后台作业 。

查询索引问题

给定一个指定为经纬度对的位置 , 如何找到该位置属于数万个地理围栏中的哪个?暴力遍历的方法很简单:遍历所有地理围栏 , 并用诸如光线投射算法之类的算法进行多边形点检查 。 问题 , 这种方法太慢 , 不能满足服务性能要求 。

Uber抛弃了业界常用的用R-tree或S2为地理围栏建立索引的方法 , 使用基Uber商业模式以城市为中心 , 选择了一条更简单的路线;商业规则和其定义的基础地理围栏通常与城市相关联 。 所以架构上将地理围栏组织成两级层次结构 , 其中第一级是城市地理围栏(定义城市边界的地理围栏) , 第二级是每个城市内的地理围栏 。

推荐阅读