redis |存储IP和网络的最佳数据结构

bq9c1y66  于 2021-06-08  发布在  Redis
关注(0)|答案(2)|浏览(876)

我的目标是在redis中存储:
普通ip地址,如 228.228.228.228 ip网络,如 228.228.228.0/24 以检查请求/响应周期是否为当前ip .yyy..vvv 在内部(包含于):
普通IP

ip网络(例如 228.228.228.228 内部 228.228.228.0/24 )
IP和网络的总数量-很少1000个项目。
问题是,在redis中存储普通ip和网络,并在不从redis获取数据的情况下进行上述检查的最佳方式(最佳结构)是什么?
谢谢。
p、 目前的ip已经知道了。
更新
好吧,让我们用例子来简化一下。
我有两个ip和两个网络,在那里我想检查是否包含某些ip。


# 2 plain ip

202.76.250.29
37.252.145.1

# 2 networks

16.223.132.0/24
9.76.202.0/24

有两种可能的方法可以包含确切的ip:
1) 只是普通的ips。例如 202.76.250.29 包含在上面和下面的结构中 215.08.11.23 不是简单的定义所包含的。
2) ip可能包含在网络中。例如 9.76.202.100 包含在网络中 9.76.202.0/24 但不包含在普通ip列表中,因为没有任何确切的ip= 9.76.202.100. 关于ip网络的一点解释。非常简单。
ip网络代表ip的范围。例如ipv4网络 "192.4.2.0/24" 表示256个ip地址:

IPv4Address('192.4.2.1'), IPv4Address('192.4.2.2'),
…
…
…
IPv4Address('192.4.2.253'), IPv4Address('192.4.2.254')

换句话说,ip网络是一系列ip地址

from '192.4.2.1' up to '192.4.2.254'

在我们的例子中 9.76.202.100 包含在网络中 9.76.202.0/24 作为范围内的地址之一。
我的想法是这样的:
任何ip地址都可以表示为整数。我们的一个ip地址 202.76.250.29 转换为整数是 3394042397 .
由于ip网络是一个ip范围,因此可以通过将范围内的第一个ip和最后一个ip转换为整数来将其转换为整数范围。例如我们的一个网络 16.223.132.0/24 表示范围介于 IPv4Address('16.223.132.1') 以及 IPv4Address('16.223.132.254') . 或整数范围从 283083777 高达 283083781 步进 1 .
单个ip可以表示为整数和整数+1之间的范围(包括下限,不包括上限)。
显然,在普通IP中搜索可以通过将它们放到 SET 然后使用 SISMEMBER . 但是在网络内部搜索呢。我们能用射程做些小把戏吗?

pieyvz9o

pieyvz9o1#

“最佳”是主观的(在内存、速度等方面),但您可以使用两个集合/散列来存储它们。因为它们都是独一无二的 hashes 以及 sets 那就好了。如果您愿意的话,您可以使用一个集合/散列来保存ip和网络ip地址,但我更愿意分开保存,因为它们是两种不同类型的数据集(就像数据库表一样)。
那你可以用这两个 SISMEMBER 时间复杂度为o(1) HEXISTS 时间复杂度为o(1)。
可以使用多个命令或lua脚本(在单个事务中)在应用程序级别处理它。
根据您的选择,使用 SADD 以及 HSET (字段值为1)。
--编辑:(希望我做对)
对于网络地址范围,从围绕两个点的整数创建集合,例如12.345.67.1-12.345.67.254范围将表示为 12.345.67 你要把这个加到布景里。当你想搜索 12.345.67.x 它将被解析为 12.345.67 在您的应用程序级别,您将检查 SISMEMBER . 用hash和 HEXISTS .
由于ip地址包含四个不同的数字和三个点,您将丢弃最后一个点和最后一个数字,其余的将代表(我假设)网络范围。

d5vmydt9

d5vmydt92#

对于ip,您可以在o(1)时间内使用按特定ip设置和查询。
对于ip范围,我认为可以使用list和lua脚本进行查询。列表将有o(n)个搜索时间,但由于您只有1000个项目,所以对于redis内存查询,o(n)和o(1)不会有很大的区别。

相关问题