Descripción del problema
Más de una vez, nuestro equipo en Karuna enfrentó el desafío de almacenar y usar direcciones IP en una base de datos. Supongamos que hay una tarea típica: necesita analizar una gran cantidad de rangos de direcciones (~ 300k) de un recurso conocido y luego determinar el país por la dirección IP del cliente. No parece nada especial. Esto se puede resolver de manera bastante simple mediante cualquiera de los métodos descritos a continuación con cargas bajas. ¿Pero si tenemos miles de usuarios, o nuestro servicio es un proxy frente a todos los demás? En este caso, no quieres ser un cuello de botella y tienes que luchar por cada fracción de segundo.
Un poco sobre abordar
Hay 2 tipos de direccionamiento de red
INET ( IP-) — , 1981 1993 . .
CIDR (Classless Inter-Domain Routing, ) — IP-, .
address/y, y — . , /28 , 28 IP- , 4 — , .
, 192.168.5.0/24 192.168.5.1 192.168.5.254, 192.168.5.0 — 192.168.5.255 — .
inet cidr
PostgreSQL 2 IP- : inet cidr. inet/cidr.
inet , . address/y. y , 32 ( IPv4), .
cidr IPv4 ( IPv6). address/y. y , (INET).
, inet , cidr . /8, cidr , 24 , inet . , 255.0.0.2/8 cidr .. 255.0.0.0 ( 2 ). 255.128.128.7/24, 255.255.255.255/31 — , inet .
-?
(MacBook 16, 2019 2,6 GHz 6-Core Intel Core i7). IP-:
CREATE INDEX ON ip_ranges USING GIST (ip_range inet_ops);
(1.000.000) IP- :
DO
$$
DECLARE
i RECORD;
BEGIN
FOR i IN 1..1000000 LOOP
PERFORM country_id FROM ip_ranges WHERE ip_range >>= ‘{random_ip}’;
end loop;
END;
$$
;
.
inet |
cidr |
749 |
891 |
ip4r
— ip4r, .
, , PostgreSQL. . , .
38 .
( ?)
nginx, geo , IP- . docker-compose.yml:
version: '3.7'
services:
web:
image: nginx:latest
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
- ./GeoIP.dat:/var/geo/GeoIP.dat
- ./geo.conf:/var/geo/geo.conf
ports:
- "8080:80"
environment:
- NGINX_PORT=80
nginx:
http {
...
geo $geo {
default NONE;
include /var/geo/geo.conf;
}
geoip_country /var/geo/GeoIP.dat;
...
server {
...
location / {
...
add_header Geo-By-File $geo;
add_header Geo-By-Binary $geoip_country_code;
}
}
}
, $geo, geo.conf :
128.0.0.0/1 US;
...
GeoIP.dat , ($geoip_country_code).
, . , ( , , ..).
, PostgreSQL — . , .
, ( ). , .. , - .
, , , inet cidr, . ip4r ~20 .