希望能从那些曾经参与其中的人那里得到一些明智的建议,并能帮助我更好地理解在Redis中何时将数据集群在一起,以及何时将其拆分。
我在一个多租户平台上工作,对于我跟踪的每个资产,GPS数据每3-5秒传入一次。在处理数据时,我们存储与资产相关的附加信息(即是否准时、是否迟到等)。
每个资产都属于一个或多个租户。例如,当跟踪一辆家用汽车时,这辆车可能为丈夫和妻子而存在。每个人都需要知道它相对于他们的需求在哪里。例如,这辆车可能正由青少年使用,并在下午3:00准时供丈夫使用,但在下午2:30晚到妻子使用。
作为附加要求,单个租户可能希望拥有对其他租户的读访问权限。也就是说,这位父亲想看看家里的车,还有任何青少年的车。因此,继承制可以开始看起来像这样:
超级租户--
--Super Tenant (Family)
--Tenant (Dad)
--Vehicle 1
--Gps:123.456,15.123
--Status:OnTime
--Vehicle 2
--Gps:123.872,15.563
--Status:Unused
--Tenant (Mom)
--Vehicle 1
--Gps:123.456,15.123
--Status:Late
--Vehicle 2
--Gps:123.872,15.563
--Status:Unused
--Tenant (Teenager)
--Vehicle 1
--Gps:123.456,15.123
--Status:Unused
--Vehicle 2
--Gps:123.872,15.563
--Status:Unused
我的问题是关于在Redis中存储它的最好方法。
我可以按租户存储--也就是说,我可以为爸爸使用一把钥匙,然后收集他可以使用的所有车辆。每当有新的GPS定位进入(无论是车辆1还是车辆2),我都会更新集合的内容。我担心的是,如果有几十辆车,我们会经常更新他的收藏方式。
或
我可以先按租户存储,然后再按车辆存储。这意味着当Vehicle 1的GSP位置到来时,我将更新3个不同租户的信息。还不错。
让我犹豫的是,我正在开发一个网站,让爸爸可以看到他所有的车辆。那个电话会打进来,要求得到爸爸所有租户名下的车辆。如果我将数据拆分成按租户/车辆存储,那么我将不得不存储爸爸有2辆车的事实,然后向Redis索要(key1、key2等)中的所有内容。
如果我将所有内容都存储在一个集合中,那么我对Redis的请求将会简单得多,并且将请求密钥爸爸下的所有内容。
实际上,每个租户将拥有5-100辆车,而我们有100个租户。
根据您的经验,您首选的方法是什么(请随时提供此处未提供的任何方法)。
发布于 2021-11-29 14:56:28
从您的问题看,您似乎希望将所需的一切存储在一个密钥下。Redis不支持按原样嵌套哈希。这篇answer中有一些关于如何解决的建议。
根据GPS数据的更新节奏,最好将所需的总写入次数降至最低。这可能会增加构造读取响应的操作数量;但是,添加只读从实例应该允许您扩展读取。您可以通过一些流水线更新来调整您的写入。
从你所描述的情况看,更新似乎仅限于用户的GPS和车辆状态。读取时请求的数据将用于单个用户查看他们的车辆位置和状态集。
我将从一个租户开始,该租户存储为具有用户名的散列,以及一个引用与该用户关联的车辆和会话的字段。如果您采用类似的命名约定,这实际上并不是必需的,但如果需要缓存其他用户数据,则显示为一个选项。
- Tenant user-1 (Hash)
-- name: Dad (String)
-- vehicles: user-1:vehicles (String) reference to key for set of vehicles assigned.
-- sessions: user-1:sessions (String) reference to key for set of user-vehicle sessions.
如果不需要任何其他租户数据,则可以使用关键字格式化来查找车辆。成员将是对车辆密钥的引用。
- UserVechicles user-1:vehicles (Set)
-- member: vehicle-1 (String)
这将允许查找车辆的详细信息。车辆会有他们自己的位置。您可以包括一个字段来引用以车辆为中心的会话计划,类似于下面的用户会话。此外,如果响应也需要车辆名称或其他数据,则可以放置这些数据。
- Vehicle: vehicle-1 (Hash)
-- gps: "123.456,15.123" (String)
将特定于用户的会话存储在已排序的集合中。成员将是对存储会话信息的密钥的引用。分数将被设置为允许对该用户的最近和即将到来的会话进行范围查找的时间戳值。
- Schedule user-1:sessions
-- member: user-1:vehicle-1:session-1 (String)
-- score: 1638216000 (Float)
租户会话在车辆上您可以简单地使用字符串中的状态列表。这里显示了一个替代方案,如果您需要支持以车辆为中心的时间表视图,则允许存储计划和可用时间的额外状态。将这一点与车辆会话的排序集结合起来,就可以完善这一点。
- Session user-1:vehicle-1:session-1 (Hash)
-- status: OnTime (String)
-- scheduled_start: 1638216000 (String) [optional]
-- scheduled_end: 1638216600 (String) [optional]
-- earliest_available: 1638215000 (String) [optional]
如果您没有在其他地方跟踪状态,则可以使用散列来存储缓存对象的计数器,以便在发出新的缓存对象时使用。在添加新的缓存对象时读取并递增这些值。
- Globals: global (Hash)
-- user: 0
-- vehicle: 0
-- session: 0
对于更新,您将拥有:每个更新周期200k次写入操作。100k租户-车辆(1000个租户* 100辆/租户),每个租户
流水线和调整流水线中的请求数量可以提高写性能,但我预计您应该能够在<2秒内完成所有写操作。
对于一次读取,你可能会有这样的结果:每个用户每个请求大约300次操作。
Considerations:
在会话和它们的引用通过后定期删除它们的进程将防止内存无限增长和性能一致。
添加一些脚本,以便在添加新用户或车辆时更容易地更新缓存,并将您所描述的需要显示的状态返回给用户,这将使这一切变得更加完整。
https://stackoverflow.com/questions/70145233
复制