【问题标题】:store ip ranges in Redis在 Redis 中存储 ip 范围
【发布时间】:2016-04-03 14:46:04
【问题描述】:

我有很多不同提供商的 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 存储在 Redis 中?如果是,您如何存储它们?
  • 我将范围存储在 MySQL 数据库中,但是为了获取提供程序名称而对 MySQL 进行了很多查询 - 这太糟糕了 :(

标签: redis


【解决方案1】:

这取决于您是否认为您的 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

【讨论】:

    【解决方案2】:

    我认为最好的解决方案是sorted set

    要插入范围,请使用ZADD
    member分配range_name。
    score分配范围内的最大值。

    ZADD ip_table 3232235826 some_name
    

    然后查找范围使用ZRANGEBYSCORE 与 user_ip 作为 min_value 和 limit = 1。

    ZRANGEBYSCORE ip_table user_ip +inf LIMIT 0 1
    

    它将在大于或等于 user_ip 的端点处找到具有最小 ip 的范围。

    【讨论】:

    • 如何在你的实现中获取提供者的名字?
    【解决方案3】:

    如果您要为 MaxMind 之类的供应商获取这些数据,可能已经有可用的库来快速有效地完成此操作。在这种情况下,我认为使用 Redis 不会获得太多性能。

    【讨论】:

    • 是的,我做了一些基准测试,发现使用 redis 进行查找要慢 10 倍
    【解决方案4】:

    这类似于 Didier Spezia 提出的, 但是我们在排序集中使用了开始范围和结束范围,因为可能存在“间隙”。

    https://github.com/nmmmnu/GeoIP-Redis

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-13
      • 1970-01-01
      • 2016-12-13
      • 2018-05-05
      • 2018-01-04
      • 1970-01-01
      相关资源
      最近更新 更多