본문 바로가기

개발/기타

[GPS] Redis GEO 검색

GPS 란?

미국에서 개발하고 관리하는 위성항법 시스템.

세계 어느 곳에서든지 인공위성과 통신하여 자신의 위치를 정확히 알 수 있는 시스템. 

위치정보는 경도, 위도, 표고(해발 고도)로 이루어져 있다. 추가로 정확한 시간 정보까지 얻을 수 있습니다.

 

2020년 전후에 출시된 스마트폰 기준으로, 대부분의 스마트폰에서는 총 1~5개(GPS, Beidou, GLONASS, QZSS, 갈릴레오) 이상의 위성항법장치를 지원하고, 현재 위치 찾기 시 탐색 가능한 모든 항법장치를 동시에 사용해서 매우 높은 수준의 정확도와 매우 빠른 시간 내로 위치를 추적할 수 있습니다.

(출처: 나무위키 https://namu.wiki/w/GPS )

 

 

GEO 검색 서비스

GEO 검색 서비스 는 Redis, elasticSearch, CouchDB  등이 있지만 우리는 Redis 를 알아보겠습니다.

Redis는 확장성, 성능 및 가용성이 우수하고 가벼우며 많이 알려진 서비스로 레퍼런스가 많습니다.

 

기술조사

  • GEO 관련 기능
  • 확장성
  • 고가용성
  • 성능

GEO 관련 기능

  • 명령어 요약
    • 경도/위도 입력 : GEOADD
    • 경도/위도 조회 : GEOPOS
    • 해시값 조회 : GEOHASH
    • 거리 조회 : GEODIST
    • 주변 지점 조회 : GEORADIUSBYMEMBER, GEORADIUS
    • 주변 지점 조회 : GEOSEARCH (6.2 버전 이상에서 사용 가능)

◎ GEOADD

경도/ 위도 입력 (지리정보 좌표 등록)

명령어 : GEOADD
명령문 : GEOADD key [NX|XX] [CH] longitude latitude member [longitude latitude member ...]
옵션 :
XX: 기존 멤버를 수정한다. 새 멤버를 추가하지는 않는다.
NX: 새 멤버를 추가한다. 기존 멤버를 수정하지는 않는다.
CH: 새로 추가되거나 수정된 멤버의 개수를 리턴한다. CH 옵션을 사용하지 않으면 수정된 개수는 리턴하지 않는다.

사용예시
geoadd citymap 126.98987242188554 37.55941851781025 seoul

 

◎ GEOPOS

경도 / 위도 조회 (등록한 도시의 위도, 경도 조회)

명령어 : GEOPOS
명령문 : GEOPOS key member [member ...]

사용예시
geopos citymap seoul

 

GEOHASH

등록한 도시의 해시값  조회
Geohash: 52bits 정수로 부터 encoding 된 11자리 문자열.
아래 주소로 좌표와 위치 확인 가능합니다.

http://geohash.org/{hash}

명령어 : GEOHASH
명령문 : GEOHASH key member [member ...]

사용예시
geohash citymap seoul busan

 

GEODIST

좌표간의 거리 측정 (km)
두 지역의 거리를 리턴합니다. 단위는 m(meter), km(kilometer), mi(mile), ft(feet) 입니다. 기본 단위는 meter입니다.

명령어 : GEODIST
명령문 : GEODIST key member1 member2 [unit]

사용예시
geodist citymap seoul busan km

 

GEORADIUSBYMEMBER

지정한 지역의 근처에 있는 도시 조회
지정한 지역에서 반경 몇 km 이내의 지역(member)를 찾는다.

명령어 : GEORADIUSBYMEMBER
명령문 : GEORADIUSBYMEMBER key member radius m|km|ft|mi

[WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
[ASC|DESC] [STORE key] [STOREDIST key]

옵션 :
	거리 단위
		m : meter
		km : kilometer
		ft : feet, 0.3048 meter
		mi : mile, 1.6093 kilometer
	WITH option (중복할 수 있음)
		WITHCOORD: 좌표(Coordinate) 조회
		WITHDIST: 거리 조회
		WITHHASH: 해시값 조회
	COUNT count option
		조회할 지역(member) 수 선택
   	SORT (ASC/DESC)
		ASC : 가까운 지역부터 표시
		DESC : 먼 지역부터 표시


사용예시
서울에서 100 km 이내 도시
georadiusbymember citymap seoul 100 km

 

GEORADIUS

지정한 지점 근처에 있는 도시 조회

명령어 : GEORADIUS
명령문 : GEORADIUS key longitude latitude radius m|km|ft|mi

[WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count]
[ASC|DESC] [STORE key] [STOREDIST key]

옵션 : GEORADIUSBYMEMBER 와 동일

사용예시
특정 좌표에서 100 km 이내 도시
georadius citymap 127 38 100 km

 

GEOSEARCH

지정한 도시 또는 좌표로 주변 도시 조회
이 명령은 GEORADIUSBYMEMBER, GEORADIUS 를 대체 할 수 있음

명령어 : GEOSEARCH
명령문 : GEOSEARCH key [FROMMEMBER member] [FROMLONLAT longitude latitude]

[BYRADIUS radius m|km|ft|mi] [BYBOX width height m|km|ft|mi] [ASC|DESC]
[COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH]

필수 옵션 : 
	도시 또는 좌표 지정
		FROMMEMBER: 도시를 기준으로 검색할 경우 사용합니다.
		FROMLONLAT: 좌표(경도,위도)를 기준으로 검색할 경우 사용합니다.
	반지름(원) 또는 사각형(box)
		BYRADIUS: 원의 반지름으로 검색합니다.
		BYBOX: 사각형의 높이(height)와 폭(width)으로 검색합니다.
		거리는 m(meter), km(kilometer), ft(feet), mi(mile)로 입력할 수 있습니다.

사용예시
GEOSEARCH citymap FROMLONLAT 127 38 BYRADIUS 200km의 ASC

 

ZCARD

등록된 좌표 갯수 조회

사용예시
zcard citymap

 


Redis GEO에 대하여 더 알아보기

  1. 확장성
    시간 복잡성에서 지리 데이터의 양이 증가함에 따라 명령 실행 시간이 증가한다는 것이 분명합니다.
    사용된 메모리도 증가할 수밖에 없습니다이러한 경우 Redis 클러스터는 데이터 볼륨의 변화에 따라 확장될 있습니다.
    Redis 클러스터를 확장하는 방법에는 수평 및 수직 확장의 두 가지가 있습니다
    • 수평적 확장을 통해 클러스터에서 노드(샤드) 추가하거나 제거할 있습니다클러스터는 스케일 /아웃 동안 리샤딩 중에도 계속해서 요청을 처리합니다.
    • 수직 확장을 사용하면 요청을 처리하는 동안 확장/축소를 위해 노드 크기를 변경할 있습니다
  2. 고가용성
    Redis 클러스터는 복제를 통해 고가용성을 제공합니다.
    기본 노드에는 물리적 (또는 데이터 센터) 구성된 여러 복제본이 있을 있습니다자동 장애 조치는 Redis 클러스터에서도 지원됩니다
  3. 성능
    Redis 성능에 최적화된 데이터 구조를 가진 인메모리 데이터 저장소입니다그러나 지리 공간 쿼리의 성능을 벤치마킹하고 조정할 다음 사항을 염두에 두어야 합니다
    • GEOADD GEORADIUS 명령의 시간 복잡도는 각각 O(log(N)) O(N + log(M)) 순서입니다단일 노드에 과부하가 걸리지 않도록 크기를 작게 유지하고 데이터를 분할하는 것이 중요합니다반경이 증가하면 명령 실행 시간이 늘어날 있습니다.
    • 클라이언트는 TCP 연결을 사용하여 Redis 서버와 통신합니다. Redis는 멀티플렉싱 및 비차단 I/O를 사용하므로 클라이언트 소켓은 비차단 상태가 됩니다. 성능 조정을 위해 TCP Keepalive를 활성화해야 합니다. Keepalive는 각 새 요청에 대해 새 연결을 여는 대신 동일한 TCP 연결을 사용할 수 있도록 하는 방법입니다.
    • 수평 확장을 통해 키를 샤드에 분산시키고 샤드당 로드를 줄여 성능을 향상합니다.
    • Redis 클러스터 모드가 활성화된 경우 RDB 지속성 및 AOF가 필요하지 않습니다.
    • 기본적으로 Redis는 10,000개의 클라이언트 연결을 허용하며 이를 구성할 수 있습니다.
    • Redis 명령의 성능은 redis-benchmark 유틸리티를 사용하여 벤치마킹할 수 있습니다

 

기억할 점

Redis는 모델이 지구를 구로 가정할 때 Haversine 공식을 사용하여 거리를 계산합니다. 이로 인해 최대 0.5%의 오류가 발생할 수 있습니다.

유효한 경도 범위는 -180도에서 180 사이이고 유효한 위도 범위는 -85.05112878도에서 85.05112878도입니다.

 


우분투에서 Redis 설치

◎ apt-get 으로 설치

$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install redis-server

 

버전확인

$ redis-server --version

 

 

포트 확인

netstat -nlpt | grep 6379

 

접속

$ redis-cli

 

 

레디스 최신버전 설치

레디스 다운로드

wget https://download.redis.io/releases/redis-6.2.5.tar.gz

 

 

압축해제

tar xzf redis-6.2.5.tar.gz

 

컴파일

$ cd redis-6.2.5
$ make

 

혹시나 에러가 난다면 gcc 설치, make 컴파일 초기화

$ sudo apt install gcc
$ make distclean
$ make

 

데몬설정

$ cd redis-6.2.5
$ vi redis.conf

daemonize 설정을 yes 로 변경후 저장

 

 

레디스 실행

$ src/redis-server ./redis.conf

 

포트 확인

$ netstat -ntlp | grep 6379

 

레디스 cli

$ src/redis-cli

 

 

redis geo 의 모든 기능을사용하기 위해서 최신버전을 사용하실 것을 권장합니다.