Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design 使用Redis的Geo程序设计建议_Database Design_Redis_Geolocation_Geospatial_Nosql - Fatal编程技术网

Database design 使用Redis的Geo程序设计建议

Database design 使用Redis的Geo程序设计建议,database-design,redis,geolocation,geospatial,nosql,Database Design,Redis,Geolocation,Geospatial,Nosql,我正在学习Redis,正在为学习目的建立一个geo计划。我只想使用Redis来存储数据,并试图避免使用任何关系数据库。我的问题是如何最好地为程序设计数据库。这就是程序的运行方式: 1) 我将在世界各地创造数以百万计的随机机器人,它们可以漫游,因此它们可以有不同的地理坐标(有些机器人可以在完全相同的空间) 2) 每个机器人将随机向服务器发送帖子(平均可能每隔几个小时发送一次),其中包含: a) 机器人发送此数据的位置(坐标或geohash,取决于最佳实现方案) b) 一些小文本 3) 我将拥有一张

我正在学习Redis,正在为学习目的建立一个geo计划。我只想使用Redis来存储数据,并试图避免使用任何关系数据库。我的问题是如何最好地为程序设计数据库。这就是程序的运行方式:

1) 我将在世界各地创造数以百万计的随机机器人,它们可以漫游,因此它们可以有不同的地理坐标(有些机器人可以在完全相同的空间)

2) 每个机器人将随机向服务器发送帖子(平均可能每隔几个小时发送一次),其中包含: a) 机器人发送此数据的位置(坐标或geohash,取决于最佳实现方案) b) 一些小文本

3) 我将拥有一张所有机器人的地图,并希望能够点击机器人并获得以下信息: a) 所有张贴在我刚刚点击的机器人附近的帖子

4) 由于事实上,我将在AWS上托管这篇文章,我将需要每隔几个小时删除一次文章,以保持内存使用率低,因此某些类型的过期是强制性的

我主要关心的是性能,我对如何设计Redis数据库感兴趣

在一天之内(我将计算出随机帖子的数量),大约会生成500000000个帖子

到目前为止,我的想法还不完整:

想法1

1) 将按以下方式储存一个员额:

`HSET [Geohash of location] [timestamp] [small text] (<-- the value will be used in a later feature to increment the number of manual modification I make to a post).
然后返回字段([timestamp])和值(“0”)

3) 旧职位到期。因为我不能使用EXPIRE命令从hashset中删除字段,所以我需要定期扫描所有hashset字段,找到旧的时间戳并删除它们。因为Redis只允许模式搜索,所以当所有时间戳都不同时,这可能会很困难

想法2:

使用Redis geo()

1) 要存储我将运行的帖子,请执行以下操作:

geoadd globalSet [posts_long] [posts_lat] "small text";
2) 要获取附近机器人的所有post信息,请执行以下操作:

georadius globalSet [robots_long] [robots_lat] [X] km
这将在X公里内返回机器人附近的所有立柱


3) 那么,我现在陷入了如何删除旧帖子的困境

让我根据我如何理解您的问题来给您一个想法:

不要将值存储在散列中,只需将所有内容存储在redis中即可。 将密钥构造为GeoLocation:[Geohash-location of robot]:1[指示post的数量,每当新请求出现时,它将继续递增]:时间戳和值将是时间戳。 类似地,对于小文本地理位置:[机器人的地理哈希位置]:1[指示帖子数量]:smallText。 使用set expire可根据需要设置值和过期时间

Ex:setex地理位置:12.31939:1:时间戳14342232(时间戳)14400(4小时) setex地理位置:12.31939:1:smalltext罗纳尔多14400

因此,您可以从所有机器人那里获得任意数量的帖子,并使用不同的键进行访问,设置expire也变得很容易

现在,要获取特定机器人发布的所有信息,请使用键GeoLocation:(特定机器人的位置):*并获取每个机器人的值


这样,您就不需要扫描redis中的所有键。您将更快地获得信息,并且密钥将自行过期。

我从描述中得出的一个想法是,您将知道给定“机器人”的当前位置,并且您希望实时找到附近的其他移动用户,但您也希望获得一些历史位置信息

我喜欢将redis看作是用于创建更高级别数据库的原始构建块。考虑到这一点,您意识到需要构建和维护自己的更高级别的数据库功能,如索引等

由于这类数据主要是在您考虑特定机器人时访问的,因此我建议将机器人的位置历史记录和元数据存储在基于机器人的唯一标识符而不是其位置的密钥中

然后,通过在集合或散列中管理其ID来维护其相对于其他人的相对位置(或任何其他分组),这些集合或散列将机器人程序分组到给定位置。可以使用多个集合或嵌套数据结构来实现某种详细级别功能

作为redis的一部分,通过更新机器人记录和位置信息来保持数据的完整性。用于提高效率

您不需要使用旧帖子,因为您可以通过限制bot主记录中的历史条目数来管理数据库大小。当您要更新一个bot时,只要在它超过一定长度(llen、slen、hlen等)时对它执行某种清理操作,就可以为您提供一个可预测/可调整的聚合数据大小

如果有任何希望,你正在做的事情可能会成为生产,我强烈建议考虑走出大门。任何程度的成功都需要它,所以不妨提前做好。相信我。在这种情况下,我会按功能分区(位置与机器人状态……不同复制组上的不同数据库)以及按键分区(散列或其他方式……将500米划分为合理的块)

分区使事务变得困难,但对于您的用例,我怀疑这是一个破坏交易的因素。与事务一起使用可以让您通过编程方式执行各种更新来保持完整性

最后,我会考虑除了ReDIS之外的一些东西(假设你的案例中的弹性)。在支持并发性和执行复杂查询的能力方面,redis非常适合前者。因此,它非常适合跟踪会话或类似状态

您将需要大量的并发性,但它主要是附加的,而不是更新。所以不像进化的状态机。你至少需要一些搜索能力

如果您需要将对象相互关联(查询),能够支持分析等,拥有5亿用户,您将能够负担得起一个大型红移集群、dynamo或类似设备。可以通过为bul批处理小消息,将运动放在前面,以帮助实现并发性
georadius globalSet [robots_long] [robots_lat] [X] km
      GEOADD GEO:ROBOT:17 13.361389 38.115556 "<timestamp>:<message-data>"
ZRANGEBYSCORE ZSET:ROBOTS -inf <timestamp-of-week-before>
ZREM ZSET:ROBOTS 17
DEL HSET:ROBOT:17
DEL GEO:ROBOT:17
ZRANGE GEO:ROBOT:17 0 -1
ZDEL GEO:ROBOT:17 1234567:hello
ZADD key 0 ccc 0 bbb 0 aaa
ZRANGE key 0 -1
 1. "aaa"
 2. "bbb"
 3. "ccc"