为客户提供地理空间新闻
Posted
技术标签:
【中文标题】为客户提供地理空间新闻【英文标题】:Serve clients with geospatial news 【发布时间】:2014-06-25 22:11:49 【问题描述】:我正在开发一个应用程序,用户将根据他的位置接收基于地理位置的信息。服务器应该能够处理超过 100k 的大量已连接客户端。
现在我想出了 4 种处理用户位置的方法。
方法 - 没有地理空间索引:
应用服务器只保存一个已连接客户端的列表以及它们的位置。 只要有可用的信息,服务器就会遍历整个列表并检查客户端是否在给定的半径内。
怀疑:非常昂贵
方法 - 在应用服务器中处理地理空间索引:
应用服务器确实维护了一个包含所有连接客户端的 R 树,并且它们是位置。 所以我在看JSI Java Spatial Index
疑问:用 JSI 更新地理空间索引非常昂贵
方法——让数据库“mongoDb”做地理空间索引/计算:
应用服务器只保存对已连接客户端(连接)的引用,并将该引用的密钥连同其位置一起保存到 mondoDb。 当有新信息可用时,服务器可以查询数据库以从附近的所有客户端获取密钥。
专业人士:我猜 mongoDb 的地理空间索引实现确实比我在应用服务器中做的要好得多。
疑问:客户四处奔波,这迫使我经常更新地理空间索引。我可以这样做还是遇到了性能问题?
方法 - 使用二维数组自己的“索引”
今天我正在考虑使用二维数组创建一个非常简单的索引。虽然外部数组用于经度,但内部数组用于纬度。 可以说3个经度/海拔高度就足够了。 我可以通过
接收给定区域中的用户列表ArrayList userList = data[91][35] //91.2548980712891, 35.60869979858; // 我还需要获取周围数组中的用户 90;35, 92;35 ... // 如果我需要更高的精度,我可以多使用一个十进制数据[912][356]
专业人士:我可以在不查询数据库的情况下进行快速读写访问
疑问:两极的半径更短。丑陋的黑客?
如果有人能指出“正确的”方向,我将不胜感激。
【问题讨论】:
【参考方案1】:MongoDB用于地理空间索引的索引是基于geohash的,本质上是将二维空间转换为一维key,适用于B-tree索引。虽然这比 R-tree 索引效率稍低,但它会比您的方案 1 高效得多。我还认为,使用空间查询在 db 级别过滤数据将比创建您更有效且更易于维护顶部有自己的空间索引策略。
使用 MongoDB 需要注意的主要事项是,您不能将几何列用作分片键,尽管您可以使用另一个键对包含几何字段的集合进行分片。此外,如果您希望进行任何聚合查询(从您的问题中不清楚)几何字段必须是第一个通过管道的字段。
还有一个 geohaystack 索引,它基于小桶并针对基于小区域的搜索进行了优化,请参阅 http://docs.mongodb.org/manual/core/geohaystack/,这可能对您的情况有用。
就速度而言,在 B-Tree 索引上的插入和搜索基本上是 O(log n),请参阅 Wikipedia B-Tree 而没有索引您的搜索将是 O(n),因此不会花费太多时间早在有和没有索引之间的性能差异很大之前。
如果您担心大量写入会减慢速度,您可以调整write concern in MongoDB,这样您就不必等待大多数副本响应每次写入(默认),但代价是如果你失去你的主人,可能会出现不一致的数据。
【讨论】:
感谢您的回答,我想 geohaystack 索引适合我的情况。 MongoDB 文档没有回答我的问题是更新索引会如何影响性能以及这样做是否是个好主意。 最终,没有什么可以替代测试,但即使索引对写入性能有影响,这也会被读取性能所抵消。使用 MongoDB,您可以调整所谓的写入问题,即,如果您不等待大多数副本响应,写入将更快返回,但如果您丢失主副本,则可能会导致数据不一致。 @user3211074。我已经用关于 B-Tree 的一些信息更新了我的答案,并在 Mongo 中写下关注点,这可能有助于回答您的问题。 我本来打算询问有关您实际查询的更多信息,以便更好地了解情况 4,但请看您已接受答案。那么,你选择了场景 3 吗? 我尝试了场景 3,但性能测试的结果并不令人惊讶。今天我尝试了场景4。它非常简单,性能很好。我使用了一个以“long;lat”作为键的 hashMap(四舍五入为 1 位小数),该键的值是已连接用户的列表。它非常适合我的用例。以上是关于为客户提供地理空间新闻的主要内容,如果未能解决你的问题,请参考以下文章
通过 GeoServer 在 MongoDB 中提供地理空间数据