2012-04-03 4 views
8

다른 제공 업체의 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 

내 작업 :

(예 : 192.168.2.20 (3232236052)에 대한) 사용자의 IP 주소를 공급자 이름을 찾을 수 MySQL에서는 간단합니다 :

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

레디 스와 같은가요?

+0

IP는 이미 Redis에 저장되어 있습니까? 그렇다면 어떻게 보관하고 있습니까? –

+0

MySQL 데이터베이스에 범위를 저장하지만 공급자 이름을 가져 오기 위해 MySQL에 많은 쿼리가 있습니다 - 끔찍합니다 : ( – trong

답변

14

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 

공급자가 시스템에 추가 될 때마다 인덱스는 유지되어야합니다 (수동 :이 레디 스 관계형 데이터베이스가 아닌)입니다. 점수는 최대 값이고, 구성원은 범위의 ID입니다. 당신의 IP가 최소 주소보다 크거나 같은 것으로 확인

> 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" 

그런 다음 클라이언트 프로그램이 바로이 : 이제

> 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 라운드 트립이 필요 반환 된 범위의

이제 범위가 겹칠 수 있다고 생각하면 해결책은 훨씬 더 복잡하며 이미 here으로 설명되어 있습니다.

9

제 생각에는 최선의 해결책은 sorted set입니다.

삽입하려면 ZADD을 사용하십시오.
까지 member 범위 이름을 지정하십시오.
까지 score 범위에서 가장 높은 값을 지정하십시오.

ZADD ip_table 3232235826 some_name 

그런 MIN_VALUE 및 제한으로 user_ip와 범위 사용 ZRANGEBYSCORE를 찾는 = 1

ZRANGEBYSCORE ip_table user_ip +inf LIMIT 0 1 

그것은보다 크거나 user_ip 같음 엔드 포인트에서 가장 작은 IP와 범위를 찾을 수 있습니다.

+0

구현에 공급자 이름을 얻는 방법 – trong

+0

구성원 이름은 공급자 이름을 포함해야합니다. –

0

MaxMind와 같은 공급 업체의 데이터를 얻는 경우 이미 빠르고 효율적으로 사용할 수있는 라이브러리가있을 수 있습니다. 이 경우에는 Redis를 사용하여 많은 성과를 얻지 못할 것이라고 생각합니다.

+0

예 벤치마킹을했는데 조회를 위해 redis를 사용하면 검색 속도가 10 배 느려진다는 것을 알았습니다. – stupidbodo

0

이것은 Didier Spezia가 제안한 과 비슷하지만 "간격"이있을 수 있으므로 정렬 된 범위에서 시작 범위와 끝 범위를 사용합니다.

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