有效地验证和处理 Redis 排序集中的数据
validate and processing data in Redis sorted set efficiently
我们有微服务(用 Go lang
编写),它的主要目的是从多个物联网设备获取日志并对它们进行一些处理,然后将结果放入 PostgreSQL table。系统的工作方式是每个设备都有自己的排序集,日志将保存在那里,并且对于每个日志,分数将是一个时间戳(当然我知道时间序列是一个更好的决定,但我们目前希望与排序集)。知道此日志每 1 秒来自每台设备。
我想每 5 秒处理一次这些集合中的数据,但是对于每个集合,里面的日志应该通过一些测试:
- 集合中应该有不止一个日志
- 如果时间戳之间的时间差为 1 秒,则可以从集合中删除两个日志
验证日志后,它们可以传递给其他方法或函数以进行其余处理。如果日志无效(存在与其他日志时间差超过1秒的日志)则返回集合等待下一次迭代再次检查。
问题:
我的问题基本上是我不知道如何从列表中取出数据、验证它们并再次放回去!为了让每组更清楚,可以删除所有或 none 里面的日志,这发生在新数据内容进来的时候,因为我不能用 redis 自己验证数据我不知道该怎么办。我目前的解决方案如下:
每 5 秒,应从 Redis 中删除每个集合中的所有数据并保存在代码中的某个数据结构中(如列表...)验证后,应放置一些尚未验证的日志回到 Redis。如您所见,这些解决方案需要从代码中访问两个数据库,并且在放置无效日志时,它们应该由 Redis 排序......
当日志如此之多且设备众多时,我认为这种解决方案不是最好的方法。我对 Redis 不是很有经验,所以很感谢您就这个问题发表意见。谢谢
既然您决定使用排序集,请先了解以下事项
- "there should be more than one log inside the set"。如果排序集中没有元素,则
set
/key
不存在。您可以通过两个不同的命令检查排序集中是否有任何日志; zcard and exists - 两者都在 O(1) 中工作。
- 排序集中不能有相同的日志(真正相同的)不止一次。您需要一个标识符(例如
timestamp
、uuid
、hash
等)以在单个排序集中将每个单独的日志彼此分开。它将更新现有元素的score
(它可能不是你想要的)
127.0.0.1:6379> zadd mydevice 1234 "log-a"
(integer) 1
127.0.0.1:6379> zadd mydevice 12345 "log-a"
(integer) 0
127.0.0.1:6379> zrange mydevice 0 -1 withscores
1) "log-a"
2) "12345"
127.0.0.1:6379>
没有单一的方法可以使用内置方法在数据层上执行此操作。您将需要具有业务逻辑的应用层来完成您的需要。
我的建议是将每个 IOT 设备 + 分钟的组合保持在不同的排序集中。所以每一分钟每个设备都会有一个不同的密钥,你将在设备标识符密钥后附加分钟 2020:06:06:21:21
,它最多会放 60 条日志。你可以用 zcard
查看
会是这样的;
127.0.0.1:6379> zadd device:1:2020:06:06:21:21 1591442137 my-iot-payload
(integer) 1
127.0.0.1:6379> zadd device:1:2020:06:06:21:21 1591442138 my-iot-payload-another
(integer) 1
127.0.0.1:6379> zadd device:1:2020:06:06:21:21 1591442138 my-iot-payload-yet-another
(integer) 1
127.0.0.1:6379> zrange device:1:2020:06:06:21:21 0 -1
1) "my-iot-payload"
2) "my-iot-payload-another"
3) "my-iot-payload-yet-another"
127.0.0.1:6379>
在你的应用层;
- 每台设备每分钟检查一次排序集(我知道你说的是 5 秒,但如果你想这样做,你需要一种模数方法以 5 秒间隔键而不是一分钟分隔它们)
- 你有设备列表(可能在你的数据库中table),你知道现在几点了(转换为redis键)
- 使用
zrange
(withscores 选项)获取 minute/device 分隔键,以便在应用程序级别为每台设备和那一分钟进行计算和验证。
- 如果它们通过则保存到您的 PostgreSQL 数据库中(删除排序集键或在您使用
zadd
添加新元素时执行 expire
)。
- 如果他们失败了,那完全取决于你。您有每个设备的分钟分隔日志,您可以删除它或部分解析它们以保存它。
我们有微服务(用 Go lang
编写),它的主要目的是从多个物联网设备获取日志并对它们进行一些处理,然后将结果放入 PostgreSQL table。系统的工作方式是每个设备都有自己的排序集,日志将保存在那里,并且对于每个日志,分数将是一个时间戳(当然我知道时间序列是一个更好的决定,但我们目前希望与排序集)。知道此日志每 1 秒来自每台设备。
我想每 5 秒处理一次这些集合中的数据,但是对于每个集合,里面的日志应该通过一些测试:
- 集合中应该有不止一个日志
- 如果时间戳之间的时间差为 1 秒,则可以从集合中删除两个日志
验证日志后,它们可以传递给其他方法或函数以进行其余处理。如果日志无效(存在与其他日志时间差超过1秒的日志)则返回集合等待下一次迭代再次检查。
问题:
我的问题基本上是我不知道如何从列表中取出数据、验证它们并再次放回去!为了让每组更清楚,可以删除所有或 none 里面的日志,这发生在新数据内容进来的时候,因为我不能用 redis 自己验证数据我不知道该怎么办。我目前的解决方案如下:
每 5 秒,应从 Redis 中删除每个集合中的所有数据并保存在代码中的某个数据结构中(如列表...)验证后,应放置一些尚未验证的日志回到 Redis。如您所见,这些解决方案需要从代码中访问两个数据库,并且在放置无效日志时,它们应该由 Redis 排序......
当日志如此之多且设备众多时,我认为这种解决方案不是最好的方法。我对 Redis 不是很有经验,所以很感谢您就这个问题发表意见。谢谢
既然您决定使用排序集,请先了解以下事项
- "there should be more than one log inside the set"。如果排序集中没有元素,则
set
/key
不存在。您可以通过两个不同的命令检查排序集中是否有任何日志; zcard and exists - 两者都在 O(1) 中工作。 - 排序集中不能有相同的日志(真正相同的)不止一次。您需要一个标识符(例如
timestamp
、uuid
、hash
等)以在单个排序集中将每个单独的日志彼此分开。它将更新现有元素的score
(它可能不是你想要的)
127.0.0.1:6379> zadd mydevice 1234 "log-a"
(integer) 1
127.0.0.1:6379> zadd mydevice 12345 "log-a"
(integer) 0
127.0.0.1:6379> zrange mydevice 0 -1 withscores
1) "log-a"
2) "12345"
127.0.0.1:6379>
没有单一的方法可以使用内置方法在数据层上执行此操作。您将需要具有业务逻辑的应用层来完成您的需要。
我的建议是将每个 IOT 设备 + 分钟的组合保持在不同的排序集中。所以每一分钟每个设备都会有一个不同的密钥,你将在设备标识符密钥后附加分钟 2020:06:06:21:21
,它最多会放 60 条日志。你可以用 zcard
会是这样的;
127.0.0.1:6379> zadd device:1:2020:06:06:21:21 1591442137 my-iot-payload
(integer) 1
127.0.0.1:6379> zadd device:1:2020:06:06:21:21 1591442138 my-iot-payload-another
(integer) 1
127.0.0.1:6379> zadd device:1:2020:06:06:21:21 1591442138 my-iot-payload-yet-another
(integer) 1
127.0.0.1:6379> zrange device:1:2020:06:06:21:21 0 -1
1) "my-iot-payload"
2) "my-iot-payload-another"
3) "my-iot-payload-yet-another"
127.0.0.1:6379>
在你的应用层;
- 每台设备每分钟检查一次排序集(我知道你说的是 5 秒,但如果你想这样做,你需要一种模数方法以 5 秒间隔键而不是一分钟分隔它们)
- 你有设备列表(可能在你的数据库中table),你知道现在几点了(转换为redis键)
- 使用
zrange
(withscores 选项)获取 minute/device 分隔键,以便在应用程序级别为每台设备和那一分钟进行计算和验证。 - 如果它们通过则保存到您的 PostgreSQL 数据库中(删除排序集键或在您使用
zadd
添加新元素时执行expire
)。 - 如果他们失败了,那完全取决于你。您有每个设备的分钟分隔日志,您可以删除它或部分解析它们以保存它。