位置请求的缓存策略

7

我正在构建返回特定区域数据(比如事件)的REST API。REST URL 是一个简单的GET。

/api/v1/events?lat=<lat>&lng=<lng>&radius=<radius>.

使用参数latlngradius(默认为10英里),其中纬度和经度是设备或浏览器API返回的。现在不用说,随着用户移动,纬度和经度会不断变化,而且两个用户可能在同一位置但纬度/经度不同。最佳方法是如何将这种请求缓存到服务器上,以便我不必每次都涉及业务逻辑。由于纬度/经度的更改,URL不会唯一。

谢谢


你是指在应用程序代码中进行缓存,还是使用缓存服务器来允许缓存带有查询字符串参数的请求? - Pedro Werneck
让我来澄清一下,如果有两个人请求在Yelp上获取特定纬度和经度以及半径内餐厅信息。假设他们之间的绝对距离小于0.1英里或某个阈值。那么你如何编写系统代码,以便从缓存中返回结果,而不是从后端数据库中获取等等... - rOrlig
1
好的,你的意思是缓存你的地理位置算法和数据库的结果,这样当你获取附近的另一个位置时,它使用缓存而不是http请求。让我想一想。 - Pedro Werneck
确切地说,我认为这是一个普遍的问题...似乎在任何地方都找不到关于它的讨论或想法。 - rOrlig
看看 R 树。它不是地球上最快的数据结构,但可能会解决你的问题。 - Plínio Pantaleão
3个回答

3

假设您有某种“网格”,当用户请求特定坐标时,您会返回该位置周围的网格瓦片。因此,您拥有无限的URL空间(坐标),映射到有限数量的瓷砖。一种解决方案是将每个请求重定向到该瓷砖的“规范”,缓存友好的URL,例如:

GET /api/v1/events?lat=123&lng=456
=>
302 Found
Location: /api/v1/events?tile=abc

或者,如果你想在URL中保留经纬度信息,你可以使用瓦片中心的位置。


2
我认为最好的方法是将结果存储在一个缓存中,以中心坐标作为键,并稍后查询圆内的点以获取新请求。
我不知道是否有任何缓存引擎可以执行空间查询,因此我认为您需要使用允许轻松查询和索引空间数据的数据库。您可以使用该数据库来缓存结果,或者至少在其他地方存储对该结果的键,并稍后可以使用空间坐标查询它们,请求与您的新请求具有一定距离阈值的所有点。
PostgreSQL 有PostGis,它应该非常简单,因为它完全支持纬度/经度距离计算。一旦您设置了适当的索引,它应该就像这样简单:
SELECT * FROM your_cache_table 
WHERE ST_Distance_Sphere(the_geom, ST_MakePoint(new_lon, new_lat)) <= 160.934

MySQL支持OpenGis扩展,但不支持纬度/经度距离计算。也许您需要自己进行一些计算,或者简单的笛卡尔距离适用于您。请查看此处的文档,这个答案也应该有所帮助。
我也相信即使是MySQL 5.6仍然只支持在MyISAM表中使用空间索引,但这不应该是问题,因为您仅将它们用于缓存。
管理缓存可能比通常要复杂一些。如果您需要过期时间,您应该只在数据库中存储键,并在缓存服务器上设置一个过期参数。当您访问数据库点时,如果没有有效的键,您应该从数据库中清除它。您可能需要一种方法来使主数据更改时使缓存无效,从数据库和缓存服务器中删除它们。

-1

我一直在数据建模一个业余应用程序,该应用程序还需要处理地理位置数据,并且不得不尝试解决类似的问题。解决方案当然取决于您拥有的约束条件以及对应用程序目的至关重要的实际用例。我假设您具有设计灵活性,可以更改应用程序的所有方面,即技术堆栈。

注意:

...这样我就不必每次都涉及业务逻辑。由于纬度/经度会发生变化,因此URL不会是唯一的。

上述是一个含糊不清的陈述,因为不涉及业务逻辑可能意味着很多事情。我假设它意味着您不想进行任何数据库查询以检索可能与缓存中已有的数据相似的新数据。同时假设您只想在服务器上进行缓存,则有以下方法:

  1. 在数据库和应用程序之间缓存数据。

    数据库 ---> 缓存 ---> 应用程序 ---> 用户

在这种方法中,您的应用程序处理所有其余的rest api调用,然后决定是否可以使用缓存中的结果或者需要另一个数据库访问。

缓存应用程序与用户之间的数据。数据库--> 应用--> 缓存--> 用户
考虑到URL始终在变化,这种方法有点棘手。因此,您可能需要一个“智能缓存机制”,它将处理传入的URL,然后决定缓存数据是否相关。根据您的应用程序实现方式的不同,可以使用类似mongodb的东西作为JSON缓存,然后可以预处理每个传入请求,以查看是否可以直接从该缓存返回数据,或者将其重定向到主应用程序。因此,结构可能如下所示:
数据库--> 应用--> (某些逻辑(例如NodeJS应用程序)+ Mongodb)--> 用户
结论:
如果不了解您的解决方案架构、关键用例和全面设计限制,我们无法真正提供完整的解决方案来解决此问题。您可能需要重新考虑某些要提供的功能,并做出艰难的妥协才能使事情正常运行。希望这里不同人提供的建议能够对您有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接