Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/redis/2.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
在Redis中存储ip范围_Redis - Fatal编程技术网

在Redis中存储ip范围

在Redis中存储ip范围,redis,Redis,我有很多不同提供商的IP范围。比如说 P1: 192.168.1.10 - 192.168.1.50, 192.168.2.16 - 192.168.2.49, P2: 17.36.15.34 - 17.36.15.255, P3: ... 我将此IP转换为int32: P1: 3232235786 - 3232235826, 3232236048 - 3232236081, etc 我的任务:按用户IP地址查找提供商名称(例如192.168.2.20(3232236052)) 在MySQL

我有很多不同提供商的IP范围。比如说

P1: 192.168.1.10 - 192.168.1.50, 192.168.2.16 - 192.168.2.49,
P2: 17.36.15.34 - 17.36.15.255,
P3: ...
我将此IP转换为int32:

P1: 3232235786 - 3232235826, 3232236048 - 3232236081, etc
我的任务:按用户IP地址查找提供商名称(例如192.168.2.20(3232236052))

在MySQL中,它很简单:

select name from ip_ranges where l_ip <= user_ip and user_ip <= r_ip

从ip_范围中选择名称,在我看来,l_ip是最好的解决方案

要插入范围,请使用。
向成员分配范围名称。
评分
指定范围内的最高值

ZADD ip_table 3232235826 some_name
然后用用户ip作为最小值和限制=1来查找范围

ZRANGEBYSCORE ip_table user_ip +inf LIMIT 0 1

它将查找端点处最小ip大于或等于用户ip的范围
  • 使用散列集合存储提供程序数据
  • 使用zset索引范围的最大值
  • 检索最大值大于IP的(唯一)范围
  • 检查此范围的最小值是否低于IP
例如:

这是我的供应商。它们中的每一个都有一个id。请注意,我可以添加更多附加到每个提供者的属性:

> hmset providers:1 name P1 min 3232235786 max 3232235826
OK
> hmset providers:2 name P3 min 1232235786 max 1232235826
OK
> hmset providers:3 name P3 min 2232235786 max 2232235826
OK
> hmset providers:4 name P4 min 4232235786 max 4232235826
OK
每次在系统中添加提供者时,都必须维护索引(手动:这是Redis,不是关系数据库)。Score是最大值,member是范围的id

> zadd providers:index 3232235826 1 1232235826 2 2232235826 3 4232235826 4
(integer) 4
> zrange providers:index 0 -1
1) "2"
2) "3"
3) "1"
4) "4"
现在,要查询与IP地址对应的唯一范围,您需要2次往返:

> zrangebyscore providers:index 3232235787 +inf LIMIT 0 1
1) "1"
> hgetall providers:1
1) "name"
2) "P1"
3) "min"
4) "3232235786"
5) "max"
6) "3232235826"
然后客户端程序只需检查您的IP是否大于或等于返回范围的最小地址


现在,如果你认为范围可以重叠,则解决方案要复杂得多,并且已经被解释了。

< P>如果你为像MaxMind这样的供应商获得这些数据,可能已经有图书馆可以快速有效地完成这项工作。我认为在这种情况下,使用Redis不会获得太多性能

这与迪迪埃·斯佩齐亚的提议相似, 但我们在排序集中使用开始范围和结束范围,因为可能存在“间隙”


您的IP是否已存储在Redis中?如果是,您是如何存储它们的?我在MySQL数据库中存储范围,但是为了获取提供者名称,需要对MySQL进行大量查询-这很糟糕:(如何在您的实现中获取提供者名称?是的,我做了一些基准测试,发现使用redis进行查找的速度慢了10倍