1. 개요


- consistent hashing 을 간략하게 살펴본다.


2. consistent hashing


- hash node를 key와 같은 hash function으로 hashing하여, node 사이의 key를 후임(또는 전임) node가 처리하도록 함.

- node 삭제시, 후임 노드가 key를 추가 부담

- node 추가시, 추가된 부분만큼만 new가 담당

# node 추가/삭제시 key reassign 최소화하여 안정적인 key 저장 가능해짐


3. 문제점


- node 가 hash되기 때문에 node 사이의 분포에 문제

- 각 node의 가상 노드를 추가하여 분배.

- 한 노드별 분포를 줄이고, 가상 노드에 분배.


# ketama consistent hashing 이라고도 함.

원문 https://serversforhackers.com/nginx-caching


- varnish 마찬가지로 nginx 매우 합리적인 용도의 web cache이다.

- nginx static content 처리 못지 않게 dynamic content proxy 처리하는 것도 수준급이다.


Use Cases

- nginx 다른 서버로부터 수신한 content cache 처리할 있다.

- use case as nginx as a cache server

  - 웹서버의 앞단에 위치 : gateway 동작, LB 유사하게 동작.

  - cache result of FastCGI/uWSGI process.

    - 보통의 유저는 사이트의 dynamic 요소를 요구하지 않음. 단지 content 보기 원할 .

- cache server 주요 이점 : app. server load 경감. static or dynamic content 두루 cache.


How It Will Work

- Origin Server

 - static file 또는 dynamic하게 생성한 HTML 서비스

 - assets(혹은 content) cache 있는지 결정. (HTTP cache header 이용)

- Cache Server

 - frontman : client로부터 HTTP request 수신. 직접 처리(요청받은 리소스의 신선한 캐시를 가지고 있다면)할지 Origin Server 처리를 맡길지 결정

 - Origin Server 처리를 맡긴 후에는 Origin Server 응답한 헤더에서 리소스를 캐시할지 간단히 전달만 할지 결정

 - 역할

  - HTTP request 캐싱된 응답을 허용하는지, 현재 내가 가진 캐시 리소스가 신선한지 결정

  - 위에서 request 캐싱을 허용하지 않거나, 캐시 리소스가 오래된 버전이면, HTTP request Origin Server 전달.

  - HTTP response 적절히 응답

- Client

 - local(private) cache 가짐

  - ex) browser cache

  - image, CSS, JS file

 - local cache fresh item 있으면 재요청하지 않음

 - 역할

  - 요청을 보냄

  - 응답을 캐싱

  - local cache에서 item 쓸지, HTTP request 보낼지 결정


Origin Server

- origin server cache 리소스의 헤더를 적당히 세팅할 책임

- origin server 리소스 타입별 expires 헤더 세팅 예제

- html,xml,json (-1) < rss, atom (1h) < image (1M) < css,js (1y)

- Cache-Control "public" : 누구나 캐시 가능!

- "private" : browser private cache 캐싱!

- Cache-Control: no-cache : don't cache!


Cache Server

- reverse proxy + caching function

- proxy_cache_path : level MD5 hash 이용하여 cache item hierarchy 구성, 검색 용이

- proxy_cache_key : static entry $scheme$request_method$proxy_host$uri

dynamic (CGI) entry FastCGI, SCGI, uSGI 별로 각각 cache_key가 설정되는 듯. (추가 연구 필요)

이 글은 2011년 2월에 LWN에 올라온 'reasing the TCP initial congestion window'를 번역(이라고 썼지만 직역 중에도 발로 한 직역)한 글이다. 참고만 하시길.


아래는 간단한 요약과 감상


<요약>

- slow start 알고리듬 도입 초기와 달리 현재는 망상태가 훨씬 좋아졌으므로 init_cw를 큰 값으로 해도 된다.

- linux는 기본적으로 receive windows도 작기 때문에 이 값 역시 적어도 init_cw 만큼은 되어야 한다.

- 원문을 뒤져야 하겠지만, google이 network 테스트를 하면서 linux를 빼고 했다는 게 특이.


<감상>

- linux에서 당연히 설정가능한 값일 줄 알았던 init_cw가 2.6.39 이전에는 하드 코딩된 값이었다는 점이 놀라움

- proc_fs 등으로 값이 설정가능하도록 init_cw 변수를 추가하면 좋겠다는 생각.

- 왜냐하면, 각 route별 init_cw는 route 세부 설정으로 가능한데 비해 default 값은 10으로 고정되어 있기 때문


원문 : https://lwn.net/Articles/427104/


jonathan corbet, Feb/9/2011


van jacobson이 처음 도입한 TCP slow start 알고리듬은 TCP/IP가 인터넷에서 실제 동작하게 하는데 결정적인 역할을 한 프로토콜 수정 사항 중 하나다. slow start는 새로운 connection의 시작시 데이터의 양을 제한하고, 전송 속도를 점차 늘려 connection의 전달 한계까지 도달하게 동작한다. 이런 방식으로 TCP는 실망의 현재 상태에 맞춰 동작할 수 있게 되고 수용가능한 양보다 많은 데이터를 처리할 때 발생하는 라우터의 과부하를 피할 수 있게 되었다. slow star의 핵심 요소는 initial congestion window이며, 전송 초기에 얼마나 많은 양의 데이터를 보낼지 한계를 결정하는 값이다.


이 값은 초기(RFC 3390)에 4개의 세그먼트(4KB 약간 넘는)로 결정되어 근 10년간 사용되었다. 그 동안 connection 속도는 발전하여 - connection live time 주기가 짧아지는데도 불구하고- 한 connection을 통해 전송할 수 있는 데이터의 양은 이전보다 커졌다. 이런 연유(life time 감소, 데이터 전송단위량 증가)로 많은 connection이 최고 속도에 도달하기 전에 이미 종료된다. 따라서 4개의 초기 전송 세그먼트 제한은 현 상황에선 일반적인 connection의 latency를 증가(역주 : 최고 속도에 도달하지 못하고 종료되므로 최고 속도에 비해)시키는 병목의 원인이 되었다. HTTP 스펙이 두 개의 connection 만 사용하도록 제한하고 있음에도 불구하고 최신의 브라우저는 동시에 2개 이상의 connection을 사용하는 이유가 여기에 있다.


구글의 몇몇 개발자들이 initial congestion window의 증가를 잠시동안(for a while) 주장하였다. 2010년 7월에 그들은 init_cw의 변경과 그 동기에 관한 ​IEFT draft를 제출했다. 구글은 대규모의 테스트를 통해 init_cw를 증가시킴으로써 congestion 문제를 추가로 만들지 않고 사용자 측면의 latency가 10% 정도 감소되는 것을 확인하였고, 이에 따라 initial cw를 10개 세그먼트로 증가하시키도록 권고했다. draft는 16개 세그먼트로 증가시 실질적으로 더 좋은 수치를 낼 수 있다고 제안했으나, 테스트가 추가로 필요한 상황이다.


David Miller는 init_cw를 10으로 증가시키는 패치(1)를 제출했다. 이 패치는 아직 mainline에 반영되지는 않았고, 2.6.39에 반영될 것으로 추정된다.


흥미롭게도 구글의 테스트는 몇 개의 OS를 이용해 진행되었지만, 상대적으로 작은 initial receive window(6KB)를 가진 linux는 빠져 있었다. 최소한 congestion window와 비슷하게 큰 receive window 없이는 init_cw가 큰 효과를 보기 어렵다. 이 문제는 initial receive window를 10개 segment로 늘린 Nandita Dukkipati의 패치(2)에 의해 2.6.38에서 해결될 예정이다.


patch 2개 참조.

1) https://lwn.net/Articles/426883/

2) http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/commit/?id=356f039822b8d802138f7121c80d2a9286976dbd



reply:


2개의 패치가 더 적용되어야 한다.


1) minimum retry timeout이 대략 1ms 혹은 timer 정확도가 허용하는 이하로 줄어야 한다. LAN 환경에서 1초의 MIN_RTO는 터무니없다.

2) syn retry timeout이 1초에서 200ms 정도로 줄어야 한다. 이 값을 크게 유지해야 하는 경우는 병목인 link가 56kbps의 모뎀과 비슷한 성능(느린)일 때 뿐이다.


만약 경로 특성에 따라 이 값이 변경가능하도록 -특수하게 느린 링크에서는 이값을 증가시키고, LAN 환경에서는 이값을 감소시키는 방법으로- 라우터의 설정(혹은 유도)이 가능하다면, 획기적인 일이다.


-> TCP_RTO_MIN은 커널에 200ms로 하드코딩된 걸로 알고 있음. 내가 테스트해 본 바로는 이 값을 10ms로만 바꾸더라도 큰 이득이 있었음.


200ms도 몇몇 상황에서는 실제적인 병목이 되는 것으로 보이므로 이 값이 설정 가능하거나, 적은 값으로 유도가능하다면 획기적인 일이 될 것임.


... (이하 생략)

2015년 상반기, 핵심 기술에 관심이 있는 기업을 정리.

주관적인 괌심도에 따라 기록. 추후 업데이트가 안 될 수도. 생각나면 다른 포스팅을 할 예정.


1. paloalto networks

https://www.paloaltonetworks.com


방화벽 전문 기업. 방화벽하면 예전 기술이라는 선입견이 있는데, 이 업체는 NG F/W (NG는 마케팅적 성격이 강한 용어이긴 하지만) 즉, 기존에 IP나 port로 세션을 구분하는 차원에서 컨텐츠에 따라 어플리케이션을 구분하는 DPI 기술을 이용한 방화벽을 제공.

UI나 UX 등도 깔끔하고, 최근 국내에서 인지도를 높여가고 있음.

WAF를 기반으로 하는 우리 회사와 본격적으로 경쟁하는 단계는 아니지만, 사업 영역이 넓어질 수록 H/W appliance 기반인 우리 제품과 겹칠 가능성이 있음.


2. mellanox technolodgies

http://www.mellanox.com


서버/스토리지간 통신을 위한 infiniband/ethernet 카드 및 스위치 전문 업체로써 최근에는 SDN 스위치를 개발하고 있으며, 미국과 이스라엘에 기반을 두고 아시아 지역 영업을 확대하고 있음. 통신 H/W 개발 노하우를 바탕으로 endpoint간 가속화 솔루션도 제공. 쉽게 말하면 SDN도 하는 카드/스위치 회사. 복잡하게 말하면 상호연결 가속 솔루션 전문 기업.


3. Netronome

https://netronome.com


SDN 솔루션 제공 기업. server switch 개념. network virtualization. ARM 기반 network processor(SoC)와 이를 이용한 card 타입 H/W, ​H/W 사용을 위한 SDK로 구성.


4. cumulus networks

http://www.cumulusnetworks.com


NOS 전문 기업. whitebox switch에 설치/사용 가능한 Network OS 개발. cumulus linux를 ONP(또는 industrial standard switch)올려서 flow 기반 SDN 스위치나 legacy switch로 운용할 수도 있음.


5. DISQUS

https://disqus.com


community of communities. 각종 커뮤니티(stack overflow, reddit, etc,)의 토론을 한군데서 보거나, follow하는 사람 또는 그룹의 각종 커뮤니티 활동을 한군데서 보고, 소셜 액션(recommendation, 좋아요와 유사)도 할 수 있도록 구현된 사이트. nginx로 구성하였으며, surge에 대한 튜닝 관련 정보 공유를 통해 알게 됨.

이 글은 NBP(네이버 비즈니스 플랫폼)의 웹플랫폼개발랩(송기선)에서 낸 "Java HashMap"은 어떻게 동작하는가?"라는 블로그 포스팅을 읽은 감상 및 Java가 아닌 우리 플랫폼에 내재화하기 위한 아이디어를 기술한다.


Java의 특징 중 하나가 강력한 라이브러리의 제공인 것은 주지의 사실이다. JDK가 지속적으로 버전업 하면서 라이브러리의 성능, 기능 개선도 이루어지는 점은 C를 주력 개발 언어로 사용하는 사람에게는 부러운 일이자 아쉬운 일이기도 하다.


이번에 블로그로 접한 HashMap은 기존에는 HashTable로 불린 자료구조로 Linux 커널에서 주로 사용하는 HashTable과 일견 통하는 측면이 있다. 물론 Linux 커널은 라이브러리의 도움을 받지 못하기 때문에 직접 HashTable을 구현하였고, 특히 Lock 문제가 성능 뿐 아니라  안정성에도 심각한 영향을 끼칠 가능성이 있으므로 변경 적용이 쉽지 않은 편이다. 그럼에도 불구하고 JDK의 버전업에 따라 HashTable이 HashMap으로 변경되고 그 안에서도 개선되는 과정은 많은 Insight를 준다.


블로그의 내용은 그다지 길지 않고 요약을 잘 할 자신도 없기 때문에 이 부분은 원본을 참고하도록 제안하며, 내용 중 a) 잘 모르거나 대충 알던 것을 정리하게 된 부분과 b) Linux 커널에도 적용하면 좋을 부분을 위주로 글을 써 보련다.


1. collision 회피 방법

1-1. associative array에서는 hash function을 결과값 범위(N)보다 작은 M개의 원소가 있는 배열을 사용

1-2. 따라서, 서로 다른 hash value를 가지는 객체가 1/M의 확률로 같은 hash bucket을 사용하게 됨

1-3. 이를 collision이라고 하며 이를 회피하기 위한 방법으로 open addressing과 separate chaining을 사용하게 됨

1-4. 리눅스는 separate chaining을 기본으로 사용하고 있고, JDK도 마찬가지.

1-5. 둘 다 worst case O(M).

1-6. open addressing은 연속된 공간에 데이터를 저장하기 때문에 separate chaining에 비해 캐시 효율이 높다.

1-7. open addressing은 데이터의 개수가 적은 경우 적합. 데이터가 많아지면 캐시 효율이 떨어져 open addressing의 장점이 사라지고, collision 가능성이 훨씬 커지기 때문(다른 hash value에 의해서도 내 hash bucket이 잠식될 가능성)에 단점이 부각

1-8. 또한, remove 작업이 빈번하면, open addressing은 비효율적.


2. HashMap(Table)의 collision 대처법

2-1. collision 개수가 일정 횟수(8)를 넘어서면 링크드 리스트를 트리로 변경

2-2. Linux의 CT hash는 collision이 일어날 가능성이 큰 데, 이를 경우에 따라 트리로 변경하면 collision시 적절한 대응이 가능할 듯. (테스트 필요) !!

2-3. collision 개수가 일정 횟수(6) 이하로 떨어지면 트리에서 링크드리스트로 변경

2-4. 상호 변환 횟수가 다른 이유는 경계값에서 증감하는 worst cast에서 drastic한 성능 하락을 막기 위한 tip!

2-5. 트리 구조체는 Red-Black Tree 사용.


3. hash bucket 동적 확장

3-1. 해시 버킷의 사이즈에 따라 메모리와 성능상 trade-off 발생

3-2. 해시를 동적으로 확장해서 데이터 사이즈에 따라 절충 가능

3-3. 데이터 사이즈를 미리 알고 있는 경우에는 고정하는 것도 가능

3-4. CT 개수에 따라 미리 hash bucket을 지정하는 기능이 이미 Linux에는 반영되어 있음. 동적 할당이 추가로 필요한지는 의문 !!


4. 보조 해시 함수

4-1. 해시값을 메모리 효율성을 위해 전부 사용하지 하고 특정값(M)으로 나눈 나머지를 사용

4-2. M은 소수가 되는 것이 좋으나, 계산이 복잡해지는 측면이 있기 때문에 2^a로 나누는(1<<a - 1 값으로 &) 연산을 주로 활용

4-3. 이 때, 상위 비트 (a 이상)는 버려져 collision 가능성이 증가하므로 보조 해시 함수를 둠

4-4. JDK 8부터는 해시값의 상위 16비트를 XOR하는 보조함수 사용

4-5. 보조 함수가 단순해진 이유는 해시 함수 자체가 잘 분산되는 함수로 변경되었거니와, collision 발생이 빈번하면 트리 구조로 바꾸어 collision시 탐색 부담을 줄였기 때문

4-6. CT 해시에는 이미 보조 함수를 사용하고 있음

4-7. hash LB 알고리듬 등에서 IP 해시에 의한 collision이 발생할 가능성이 큰데 이를 활용하면 좋겠다!!


5. 스트링에 대한 해시 함수

5-1. 스트링에 대한 해시는 잘 하지 않음. (속도 문제)

5-2. 또는 해시에 참여하는 스트링의 길이를 대폭 줄임 (2바이트)

5-3. 요즘은 CPU 파워가 좋아졌기 때문에 전체 스트링에 대해 hash를 해도 무방

5-4. 대신 hash function은 대체로 h = 31 * h + str[i] 로 구현

5-5. 31을 승수로 쓰는 이유는 이 값이 소수이기도 하고, 31N = 32N - N 인데, 32 = 2^5 이므로 (N << 5) - N과 같이 계산하기 쉽고 빠르므로.

5-6. HTTP 프로토콜 헤더 분석시 이용하면 좋겠다.


이상 정리 끝.


원문 사이트 : http://helloworld.naver.com/helloworld/831311

bash 설정 중 builtin 'cd' 명령을 override하여, 특정 디렉토리로 이동시 임의의 동작을 실행 할 수 있다.

특정 디렉토리로 이동하여 매번 같은 명령을 실행하는 경우 매우 유용하다.


나의 경우 다음 fuction을 이용하여 'cd'를 override 하였다.


function cd {

    # actually change the directory with all args passed to the function

    builtin cd "$@"

    # if there's a regular file named "todo.txt"...

    if [ -f "todo.txt" ] ; then

        # display its contnets

        cat todo.txt

    fi

    # if there's a shell script named ".enc"...

    if [ -f ".enc" ] ; then

        # run script

        source .enc

    fi

}



'cd' 함수는 builtin cd "$@" 명령줄을 실행하여 기존 cd 명령을 수행한 후.


1) todo.txt 파일이 있다면 이를 보여 주고, (banner로 사용할 수 있겠다.)

2) .enc 파일이 있다면 이 파일을 실행한다. (특정 동작 실행)


다양한 용도로 사용할 수 있으니 참고하자.

레퍼런스는 stackoverflow였던 것 같은데, 정확한 url을 잊어버렸다. 향후 추가 예정​

지난 번 포스트에서 git log --graph가 한글로 표시될 때 줄바꿈 문제를 언급했었다.



이 때 사용한 git log 옵션은 다음과 같은데,


git log --graph --oneline --abbrev-commit --decorate [--all]


이번에는 --decorate 옵션 사용시 tag가 너무 많아서 보기가 힘들 때의 정리 tip이다.


우선 LESS 환경변수에 -S 옵션을 추가한다.

-S 옵션은 --chop-long-lines 옵션으로 긴 줄을 접어서 아래로 내리는(fold) 대신 잘라(chop)버린다.


-S option, see also the man-page.

    http://superuser.com/questions/272818/how-to-turn-off-word-wrap-in-less 참조


그러면 길게 한 줄로 내용이 표시되는데 decorate 의 표시 순서가 {hash, refs, log} 순이어서 log가 나오지 않는 문제가 발생한다.


* ca5f427 (tag: merge_18500, tag: VA-v2.0.0.0.8-rc3, tag: VA-v2.0.0.0.8-rc2, tag: VA-v2.0.0.0.8-rc1, tag: MII-v2.0.0.0.7-rc3.DB99  <-- log가 없음


이제 --decorate 대신 --format 옵션을 사용하여 decorate 옵션에 의해 생기는 화면과 유사하게 만들어 줄 차례다.


format 옵션에서 사용되는 변수 중 deocrate에 유사한 포멧은 "%h %d %s" 이다.

이 중 %d가 refs를 담당하고 있으니, 순서를 바꾸어 "%h %s %d"로 하면 log도 보이고 tag도 일부 보이는 상태가 된다.


* ca5f427 R #19294 kernel header include 경로 수정  (tag: merge_18500, tag: VA-v2.0.0.0.8-rc3, tag: VA-v2.0.0.0.8-rc2, tag: VA-v2   <-- log가 등장, tag는 여전히 일부만 출력


그냥 그대로 두면, 색깔이 너무 칙칙하다. 색은 format 옵션에 %C(색)으로 주고 %Creset 으로 취소 가능한데, docerate와 같이 tag, branch, remote 별로 다른 색을 주려면 git 버전이 1.8.3 이상이어야 한다.

As of git 1.8.3 (May 24, 2013), you can use %C(auto) to decorate %d in the format string of git log.

From the release notes:

 * "git log --format" specifier learned %C(auto) token that tells Git
   to use color when interpolating %d (decoration), %h (short commit
   object name), etc. for terminal output.)

    http://stackoverflow.com/questions/12694510/how-to-emulate-git-log-decorates-different-colors-per-branch-type 참고

    http://stackoverflow.com/a/16844346/55948 참고


따라서 다음과 같이,


"%C(auto)%h%Creset %C(auto)%s%Creset %C(auto)%d%Creset"


옵션을 주면 색색의 옷을 입은 log를 볼 수 있다.


완성된 git log 는 다음과 같다.


git log --graph --format="%C(auto)%h%Creset %C(auto)%s%Creset %C(auto)%d%Creset" [--all]


@ 주의할 점


 - refs는 tag, remote_branch, local_branch 순으로 표시되므로 tag가 많이 있으면 branch  정보가 가려져서 보이지 않는다. 기존 --deocrate 옵션과 병행하여 branch 정보를 빼 먹지 말자.

 - format 옵션에서 이미 oneline 옵션과 abbrev-commit 옵션을 override 하므로 graph 옵션만 넣으면 된다.

 - git 버전이 1.8.3 이하인 경우 %C(auto)가 먹지 않으므로 (auto) 자리에 직접 색을 넣든지 색을 빼든지 하도록 한다.



Embedded System 뿐 아니라, 데스크탑 또는 개발용 머신에서도 여러 버전의 binary를 관리하여 사용하고자 할 때가 있다.

이 경우, 직접 link를 관리하는 것 보다는 update-alternatives를 사용하는 편이 관리도 수월하고 낫다.


update-alternatives는 다음과 같이 사용 가능하다.


~#  update-alternatives --help

Usage: update-alternatives [<option> ...] <command>


Commands:

  --install <link> <name> <path> <priority>

    [--slave <link> <name> <path>] ...

                           add a group of alternatives to the system.

  --remove <name> <path>   remove <path> from the <name> group alternative.

  --remove-all <name>      remove <name> group from the alternatives system.

  --auto <name>            switch the master link <name> to automatic mode.

  --display <name>         display information about the <name> group.


<link> is the symlink pointing to /etc/alternatives/<name>.

  (e.g. /usr/bin/pager)

<name> is the master name for this link group.

  (e.g. pager)

<path> is the location of one of the alternative target files.

  (e.g. /usr/bin/less)

<priority> is an integer; options with higher numbers have higher priority in

  automatic mode.



몇 가지 옵션만 살펴 보면,


--display <name> : 해당 이름의 등록 정보를 보여준다.

--install <link> <name> <path> <priority> : <link>는 alternatives가 대표할 패스와 이름이다.

                <name> /etc/alternatives에 등록되는 그룹 이름이다.

                <path> 이번에 등록되는 실제 패스를 의미한다.

               <priority> 자연수로 표기되는 우선순위이며 클수록 우선순위가 높다.

--remove <name> <path> : 패스를 해당 그룹으로부터 제거한다.

--config <name> : 그룹의 사용 우선순위를 조정한다.


내부 동작은 다음과 같다.


1) --install 옵션을 통해 등록

2) <link>를 생성하고, link의 source를 /etc/alternatives/<name>으로 생성

3) /etc/alternatives/<name> 링크의 source를 등록한 <path>로 생성


즉, <link> -> /etc/alternatives/<name> -> <path> 형태로 링크된다.


상세 내용은 man update-alternatives 참조.


+ Recent posts