I have a lot of IP ranges of different providers. For example
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: ...
I convert this IP to int32:
P1: 3232235786 - 3232235826, 3232236048 - 3232236081, etc
My task: to find provider name by user IP address (for example 192.168.2.20 (3232236052))
In MySQL it's simple:
select name from ip_ranges where l_ip <= user_ip and user_ip <= r_ip
How to do the same with Redis?
If you're getting this data for a supplier like MaxMind, there may be libraries available already to do this quickly and efficiently. I don't think you'll gain much performance using Redis in this case.
In my opinion best solution would be sorted set.
To insert range use ZADD.
To
member
assign range_name.To
score
assign highest value in range.Then for finding range use ZRANGEBYSCORE with user_ip as min_value and limit = 1.
It will find range with smallest ip at endpoint that is greater than or equal to user_ip.
This is similar to what Didier Spezia proposed, but we use begin range and end range in sorted set, because there may be "gaps".
https://github.com/nmmmnu/GeoIP-Redis
It depends if you consider your IP ranges can overlap or not. If not, the solution is quite simple:
Example:
Here are my providers. Each of them are identified with an id. Please note I could add more properties attached to each provider:
Each time a provider is added in the system, an index must be maintained (manually: this is Redis, not a relational database). Score is the max value, member is the id of the range.
Now to query the unique range corresponding to an IP address, you need 2 roundtrips:
Then the client program just has to check that your IP is greater or equal than the minimum address of the returned range.
Now, if you consider the ranges can overlap, the solution is much more complex, and it has already been explained here.