redis - 在 Redis 中存储 ip 范围

标签 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 中很简单:

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

如何用 Redis 做同样的事情?

最佳答案

这取决于您是否认为您的 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 是否大于或等于返回范围的最小地址。

现在,如果您考虑范围可以重叠,解决方案就复杂得多,并且已经解释过了here .

关于redis - 在 Redis 中存储 ip 范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9989023/

相关文章:

javascript - Redis 在意外终止时丢失数据

python - 用于 nginx/uwsgi 服务器的持久内存中 Python 对象

Lua 脚本尝试访问集群节点中的非本地 key

c# - 在 ASP.NET MVC 中使用 Redis 和 SQL 数据库有哪些可能性

java - 在 Redis 中存储带有时间戳的值列表

json - Redis 添加 "\"到 JSON 字符串

php - 超时作业挂起 15 或 30 分钟,然后运行

ruby - 运行时错误 : -ERR Unknown Command running redis gem on Ruby

Laravel Sail 作为生产设置

c# - 应用程序永远不会在调试中完成启动,可能是 Redis?