<개요>

- 최근 S3를 File,정적데이터 제공등의 목적으로 사용중인데 max-age 헤더에 대한 내용이 궁금하여 상세한 내용을 파악해 보았다. (HTTP 완벽 가이드 중 일부 내용 정리)

- HTTP 프로토콜은 통신의 많은 부분을 차지하고 있으며 OSI 7 Layer상 최상단에 위치한다.

 

- 즉, 해당 계층을 잘 활용하면 실제 사용자에게 전달되는 데이터를 컨트롤 할 수 있으며

 특히 캐시를 잘 활용하면 응답시간을 상당히 개선할 수 있다.

(다만 브라우저나 클라이언트등에서 일으키는 강제 Refresh에 대해서도 고려할 필요가 있다.)

 

<내용>

1. Cache-Control 헤어

- 클라이언트는 Cache-Control 요청헤더를 사용하여 만료제약을 조정할 수 있다.

Cache-Control: max-stale
Cache-Control: max-stale=<s>
캐시는 신선하지 않은 문서라도 자유롭게 제공할 수 있다.
<s>가 지정되면, 클라이언트는 만료시간이 <s>만큼 지난 문서도 받아들인다.
완화
Cache-Control: min-fresh=<s> 클라이언트는 지금으로부터 적어도 <s>초 후까지 신선한 문서만을 받아들인다. 엄격
Cache-Control: max-age=<s> 캐시는 <s>초보다 오랫동안 캐시된 문서를 반환할 수 없다.
나이가 유효기간을 넘어서게 되는 max-stale지시어가 함께 설정되지 않는 이상 더엄격하게 만든다.
엄격
Cache-Control: no-cache-Pragma:no-cache 이 클라이언트는 캐시된 리소스는 재검사하기 전에는 받아들이지 않을 것이다. 엄격
Cache-Control: no-store 이 캐시는 저장소에서 문서의 흔적을 최대한 빨리 삭제해야 한다.
그 문서에는 민감한 정보가 포함되어 있기 때문이다.
엄격
Cache-Control: only-if-cached 클라이언트는 캐시에 들어있는 사본만을 원한다.  

* 이는 완벽한 시스템이 아니다.

* 유효기간을 먼 미래로 설정한다면, 어떤 변경도 캐시에 반영되지 않을 것이다. 

* 유효기간을 사용조차 하지 않아서 문서가 얼마나 오래 신선할 것인지 캐시가 알기 어려운 경우도 많다.

* 이는 DNS와 같은 많은 인터넷 프로토콜에서 사용되는 "ttl"의 기법의 한 형식이다.

다행히 HTTP에는 DNS와 달리 클라이언트가 만료일을 덮어쓰고 강제로 재로딩할 수 있는 메커니즘이 있다.

 

2. 나이와 신선도 계산

- 캐시된 문서가 제공되기에 충분히 신선한지 알려면 두 가지값을 계산할 필요가 있다.

- 바로 캐시된 사본의 나이와 신선도의 수명이다.

- 충분히 신선한가?

 $나이 < $신선도 수명

 

다음 사항이 주 고려사항이다.

- 캐시는 문서응답이 어디에서 왔는지 알 수 없기 때문에 헤더를 통해서 계산해야 한다.

- 신선도 수명은 해당 문서의 나이가 신선도 수명을 넘었다면 제공하기에 충분하지 않다고 판단하는 것으로 문서의 유효기간 뿐만 아니라 영향을 주는 클라이언트의 모든 요청을 고려해야 한다. (e.g 네트워크 지연) 

 

A. 겉보기 나이는 Date헤더에 기반한다.

$겉보기_나이 = max(0, $응답을 받은 시각 - $Date_헤더값)

$문서가_캐시에_도착했을때의_나이 = $겉보기 나이

 

- 모든 컴퓨터가 똑같이 정확한 시간을 갖고 있다면 단순히 현재시간 - 문서를 보낸 시간으로 계산할 수 있다.

- 하지만 모든 시계는 동기화되지 않으며 심지어 오차가 심할 경우에는 음수가 되기도 한다. max(0, )처리가 필요한 이유

- 이러한 문제를 클럭 스큐라고 한다. 

 

B. 점층적 나이

- 그래서 우리는 이에 대한 대응방법으로 프락시나 캐시를 통과할때마다 Age헤더에 상대적인 나이를 누적해서 더하도록 한다.

- 이 방법은 서버간의 시간비교나 종단 시간비교가 필요없기 때문에 유용하다. (내부시계를 사용하여 체류시간 계산)

- 문서가 각 어플리케이션에 머무른시간과 네트워크 사이를 이동한 시간만큼 Age헤더의값을 늘려야 한다.

- 비 HTTP/1.1 장치의 경우 헤더를 고치거나 삭제하기 때문에 유의해야 하며, 따라서 Age 헤더는 상대나이에 대한 모자란 추정값의 상태로 본다.

 

$보정된_겉보기_나이 = max($겉보기_나이, $Age헤더값)

$문서가_캐시에_도착했을때의_나이 = $보정된_겉보기_나이

 

*신선한 컨텐츠를 얻는 것이 목적이기 때문에 max를 이용해서 보수적으로 계산한다.

 

C. 네트워크 지연에 대한 보상

- 트랜잭션은 느려질 수 있다. (캐시의 주된 동기)

- 매우 느린 네트워크, 과부하 서버, 트리팩등의 발생은 문서의 나이 추정에 대한 추가 계산이 필요하다.

- Date헤더는 언제 문서가 원 서버를 떠났는지 나타내주고 ( *프락시/캐시는 절대 이 헤더를 수정해서는 안된다), 캐시로 옮겨가는 중 얼만큼 시간이 걸렸는지 말해주지 않는다.

- 서버 <> 캐시 왕복지연 시간을 계산하는 것은 상대적으로 쉽다. (왜나하면 요청시각과 도착시간을 알고 있으니까)

 

$겉보기_나이 = max(0, $응답을 받은 시각 - $Date_헤더값)

$보정된_겉보기_나이 = max($겉보기_나이, $Age헤더값)

$응답_지연_추정값 = ($응답을_받은_시각 - $요청을_보낸_시각)

$문서가_캐시에_도착했을때의_나이 = $보정된_겉보기_나이 + $응답_지연_추정값

 

D. 최종 나이계산

- 이 응답이 캐시에 한번 저장되면, 나이를 더 먹게 된다.

- 그 문서의 현재 나이를 계산하기 위해서 그 문서가 캐시에 얼마나 오랫동안 머물렀는지 알아야 한다.

 

$나이 = $문서가_캐시에_도착했을때의_나이 + $사본이_얼마나_오래_우리의_캐시에_있었는지

  캐시된 문서의 나이
서버   요청네트워크지연 서버가 처리하는 시간 응답네트워크지연      
캐시 요청한_시각       응답을_받은_시각 캐시에 체류한 시간 현재_시각
클라이언트             클라이언트가_요청한_시각

 

<정리>

- HTTP에서는 문서의 나이와 신선도를 계산하여 캐시를 제공한다.

- 신선도 수명은 서버와 클라이언트의 제약조건에 의존한다.

- 인터넷의 특성상 클럭스큐와 네트워크 지연이 발생하며 문서의 나이를 계산할때 이를 고려한 방법들이 존재한다.

- 다음 글에서는 신선도를 계산하는 알고리즘에 대해서 정리한다.

<개요>

- 일반적으로 많이 사용하는 지리좌표계는 위도, 경도로 이루어져있다.

  이는 실제 정확한 위치를 측정하는 것이 목표이기 때문에 소수점 표현에 제한이 없이 무한하게 표현한다. (보통 6자리)

- 특정 영역(Area) 에 대한 처리를 하기에는 적합하지 않기 때문에, 영역기반의 검색/표현에 적합한 구조가 필요하다.

- 즉, (무한->유한) 한정된 공간내에서 필요한 만큼만의 데이터(의미있는 데이터) 를 관리할 수 있도록 개선이 필요하다.

 

<내용>

- 지도뷰를 기반으로 하는 시스템에서 좌표를 기반으로 검색하는 것은 속도/공간에서 많은 손해를 본다. (대부분 특정영역 내 검색)

- 지도내에서 살짝만 움직여도 소수점 값이 변경되는데 실제 서비스내에서 의미를 갖는 값으로 보기 어려울때가 있다.

- 또한 Round처리를 통해서 어느정도 고정적으로 표현할 수는 있으나 연산에 역시 불편함이 있다.

- 지역내 검색이나 가까운 위치 등을 계산할때도 복잡한 수식을 사용해야 하며 Index 나 Key를 사용하기에 쉬운 구조는 아니다.

 

<GeoHash Concept>

전 세계를 잘라내기

- 이를 보완하기 위해서 전 세계 지역을 특정영역 단위로 잘라낸 것이 GeoHash의 기본사상이다.

- 좌표값을 특정 해시값으로 변경하여 지역기반 검색 이나 캐시 활용에서 편리하게 활용 할 수 있다. ( f(x) -> y )

- GeoHash의 결과는 특정 영역(Area) 이다.  지점(Point)이 아니다.

 

<GeoHash Algorithm>

- 알고리즘은 간단히 설명하면 Index Tree, Binary Search등과 비슷하다.

1. Latitude (-90 ~ 90), Longitude (-180 ~ 180) 범위 내에서 Binary Search를 수행한다.

2. 왼쪽에 속하면 0, 오른쪽에 속하면 1 이다. (bits)

3. 다음 구간으로 이동하여 1,2를 반복한다.

Longtitude / Latitude 변환

4. 이렇게 해서 얻은 각 bit를 하나씩 꺼내어 결합한다.

- Geohash level이 높아질 수록 더 자세한 위치를 표현해야 하기 때문에, 더 많은 bit를 필요로 하게 된다.

- latitude 1개, longitude 1개 순으로 번갈아가면서 결합한다.

 (Longitude의 값의 범위가 더 넓기 때문에 Level에 따라서 Bit가 1개 더 필요한 경우가 있고, 이 때 마지막 두 개를 연속해서 붙인다. )

 

5. 마지막으로 얻은 bits를 5개씩 나눠서 BASE32 encoding으로 변환하여 알파벳 문자를 얻을 수 있다. (2^5=32)

BASE32

6. Binary Search를 많이 반복할 수록 더욱 정확한 숫자를 얻게 되고, GeoHash 의 길이는 길어진다고 볼 수 있다.

 - GeoHash Stirng의 길이가 GeoHash Level로 생각하면 된다.

 

7. 위의 연산을 통해서 얻은 결과값은 다음과 같다.

위/경도 좌표 (37.385595, 127.122759) -> Level 2 (wy), Level 8 (wydkstzf)

위/경도 좌표 (37.384887, 127.123689) -> Level 2 (wy), Level 8 (wydksv8w)

 

*장점

- 매우 길고 큰 값을 상대적으로 짧고 저장공간을 적게 차지하는 String으로 바꿀 수 있게 된다. (Hash의 기본사상)

- GeoHash알고리즘의 특성상 prefix비교를 통해서 이웃인지 판별할 수 있다.

 예를 들어서 GeoHash를 통해서 gbsuv (Level 5)값을 얻은경우 아래의 지역들은  Neighbours 로 판별할 수 있다.

gbsvh gbsvj gbsvn
gbsuu gbsuv gbsuy
gbsus gbsut gbsuw

 

<코드>

전체코드는 다음 위치에서 확인 가능합니다.

https://github.com/ggthename/geohash

 

GitHub - ggthename/geohash: get a geohash value from a coordinate (latitude,longitude)

get a geohash value from a coordinate (latitude,longitude) - GitHub - ggthename/geohash: get a geohash value from a coordinate (latitude,longitude)

github.com

위도/경도 기반의 좌표
GeoHash Level에 따른 Binary Search 응용

 

<정리>

- 이를 통해서 특정 지역 내의 데이터값을 관리할때 Key값으로 사용할 수 있다.

 e.g) 특정지역내 위치한 상점 검색, 50 x 50내 인구 등

 

- 해당 지역간의 인접성도 복잡한 계산없이 판별할 수 있다.

 e.g) 현재 위치에서 10km내 이동가능한 곳에 있는 주유소 위치 등

 

- 최대 Level 12로 32.2mm x 18.6mm의 지역까지 표현할 수 있다. 일반적으로 Level 9 까지 사용한다.

 

<참고>

- https://en.wikipedia.org/wiki/Geohash#Technical_description

 

Geohash - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search This article is about the system for encoding geographic coordinates. For the game, see Geohashing. Public domain geocoding invented in 2008 Geohash is a public domain geocode system i

en.wikipedia.org

- https://en.wikipedia.org/wiki/Base32

 

Base32 - Wikipedia

From Wikipedia, the free encyclopedia Jump to navigation Jump to search Binary-to-text encoding scheme using 32 symbols Base32 is the base-32 numeral system. It uses a set of 32 digits, each of which can be represented by 5 bits (25). One way to represent

en.wikipedia.org

https://www.movable-type.co.uk/scripts/geohash.html

 

Geohash encoding/decoding

Movable Type Scripts Geohashes A geohash is a convenient way of expressing a location (anywhere in the world) using a short alphanumeric string, with greater precision obtained with longer strings. A geohash actually identifies a rectangular cell: at each

www.movable-type.co.uk

 

+ Recent posts