RecoPick



안녕하세요. 레코픽팀 정재훈입니다.


오늘은 너무나도 당연해서 잊고 살았던 내용들에 대해서 복습을 해볼까 합니다.


HTTP GET과 POST의 차이점을 복습하고. GET, POST가 어떻게 명세 되어 있는지 확인 해보도록 하겠습니다.


HTTP (HyperText Transfer Protocol)는 서버와 클라이언트간에 통신을 위해 설계 되었습니다. 


요청 - 응답 프로토콜을 이용해 통신을 하는데요


HTTP 명세상에 Get과 Post는 아래와 같은 형태로 사용하라고 되어 있습니다. 


Get : 특정 리소스로 부터 데이터를 요청


GET


/blog/entry/1?rate=3&comment=2



Post: 특정 리소스에 데이터를 제출 


POST


POST /blog/post HTTP/1.1

Host:blog.recopick.com

post=글내용&title=글제목



GET 과 POST의 차이점

 

 GET

POST 

 브라우저 리로드

 동의없이 요청

 브라우저가 다시 전송할 지 물음

 브라우저 북마크

 가능

 불가능

 브라우저 히스토리

 가능

 불가능

 인코딩 타입

 application/x-www-form-urlencoded

 다양(multipart, json, xml, custom)  

 데이터 캐쉬

 캐쉬될 수 있음

 불가능 

 데이터 길이제한

 URL 길이가 2048로 제한 

 제한 없음 

 데이터 타입제한

 String만

 제한 없음 (바이너리 가능) 

 보안

 data가 URL상에 다 노출.

- 브라우저 북마크 될 수 있으며 ,히스토리에 남음. 

- 웹서버 로그에 데이터 저장됨.

Get가 비교했을 때 상대적으로 안전함.

- 브라우저 북마크, 히스토리에 데이터 노출 X

- 웹서버 로그에 데이터 저장 X

 가시성

 데이터 요청 형태가 URL에 다 보임

 안보임

 Idempotent method

 YES

 NO

 Safe method

 YES 

 NO 


* Safe method는 HTTP method중 resource를 수정하지 않는 method를 뜻합니다. 오해하시면 안되는 것은 Get method가 resource를 수정하지 않는다는 것을 뜻하는게 아니구요. resource를 수정하는 데 쓰지 말라는 뜻입니다.

 

idempotence (멱등성) 은 수학이나 전산학에서 연산의 성질 중 하나로 여러번 적용하더라도 결과가 달라지지 않는 것을 의미 합니다. 예를 들자면 abs(abs(x)) , 1x1 , max(x,x)등이 있습니다. 따라서 idempotent HTTP method는 여러번 요청해도 결과 값이 달라지지 않는 것을 의미 합니다.

HTTP 명세상으로는 GET은 데이터 요청 , POST는 데이터 제출로 둘이 하는 역할이 다르지만 GET도 데이터를 제출, 요청에 사용할 수 있습니다. 


하지만 명세와 다르게 Get을 non-safe , non-idempoent하게 사용할 경우에는 매우 주의해야 합니다. 

예를 들면, middleware에 프록시가 있고 Safe method (GET)으로 리소스를 수정하는 경우에 문제가 발생할 수 있습니다. http://api/article/1/rateup이라는 GET Method로 리소스를 변경 할 경우 이미 이전에 동일한 method가 다른사람에 의해 호출 되었다면 서버로 전송되지 않고 프록시에서 캐쉬 값을 바로 클라이언트에 전달하는 경우가 발생할 수 있습니다.  

 

그리고 가시성 부분 때문에 데이터를 제출 하는 경우에도 GET을 선호하는 분들이 있습니다. 보안상의 위험, 안전성 을 포기하더라두요.


HTTP 명세상에서 용도를 정해둔 것은 잠재적인 위험으로부터 보호하기 위한 것입니다.


GET은 Idempotent, Safe method라고 명세한 것은 일종의 규약인데 이걸 non idempotent, non safe 하게 쓰면 진짜 괴팍한 겁니다.


당연한 내용이 너무 길어 졌네요.


한줄 요약 들어갑니다.  POST는 Create , Get은 Read. 다른 용도로 쓰지말자.


다음에는 Hapi.js 2부나 REST API Versioning에 대해 글을 쓸 예정입니다. 


참고 (https://github.com/for-GET/know-your-http-well/blob/master/methods.md)

methoddescriptionsafeidem.cache.spec
CONNECT"requests that the recipient establish a tunnel to the destination origin server identified by the request-target and, if successful, thereafter restrict its behavior to blind forwarding of packets, in both directions, until the connection is closed."RFC7231#4.3.6,
RFC2616#9.9
DELETE"requests that the origin server remove the association between the target resource and its current functionality."RFC7231#4.3.5,
RFC2616#9.7
GET"requests transfer of a current selected representation for the target resource."RFC7231#4.3.1,
RFC2616#9.3
HEAD"is identical to GET except that the server MUST NOT send a message body in the response (i.e., the response terminates at the end of the header block)."RFC7231#4.3.2,
RFC2616#9.4
OPTIONS"requests information about the communication options available on the request/response chain identified by the effective request URI."RFC7231#4.3.7,
RFC2616#9.3
POST"requests that the target resource process the representation enclosed in the request according to the resource's own specific semantics."RFC7231#4.3.3,
RFC2616#9.5
PUT"requests that the state of the target resource be created or replaced with the state defined by the representation enclosed in the request message payload."RFC7231#4.3.4,
RFC2616#9.6
TRACE"is used to invoke a remote, application-layer loopback of the request message."RFC7231#4.3.8,
RFC2616#9.8





Posted by recopick
TAG get, HTTP, method, post

안녕하세요. 이번에 Recopick팀에 새로 합류하게 된 정재훈이라고 합니다.

먼저 간단히 제 소개를 드리면, 저는 Recopick팀에서 메인업무로 기획을 맡고 있으며 부 업무로 UX 디자인을 진행하고 있습니다. 

는 훼이크! 닥치는 대로 뭐든 하는 개발자 입니다. (a.k.a 닥치고 시키는대로하는 개발자) 

네, 하루살이 처럼 오늘 만을 살아가는 개발자입니다. (내일이 안 보여요..) 

팀 합류 전에는 iOS 클라이언트 개발을 주로 했었구요.(깃헙 팔로우 하기)  백엔드 개발도 잠깐 했었는데 Ruby on Rails을 이용 했었습니다.

지금은 노드로 이동했습니다. 하하하하하하하하하하하…. 죄송합니다. ㅡ,.ㅡ; 이동 후 멘탈에....



몇 줄 안 썼는데 벌서 피로감이 몰려 오네요. 나머지는 다음주에 쓰고싶네요. 그럼 짜이지엔 쒜쒜.



도 훼이크… 추억돋는 짤을 사용해보고 싶었어요.

이제부터 정말로 Hapi.js에 대해 설명 드리도록 하겠습니다.  

1. Hapi.js 란 무엇인가?

Hapi (HTTP API server)는 WalmartLabs에서 월마트 모바일 플랫폼에 사용하기 위해 만들었습니다. 리드개발자는 OAuth 리드 개발자로 잘 알려진 Eran Hammer 입니다.
이름 그대로 API Server 특히 모바일을 위한 서버 개발에 좋은 기능들을 많이 담고 있습니다. 내 대세는 모바일.. 물론 일반 웹서버 개발에도 전혀 불편함이 없습니다. 이후에 차차 설명드리겠습니다만. 다양한 기능들을 지원합니다. Batch Request, Pack, Pre, Plugin등이 Core 개발 시에 고려되어 굉장히 효율적으로 동작합니다. 

Hapi 탄생배경
개발팀은 월마트 모바일 개발을 위해 요구사항이 정해져 있었고 요구사항을 충족시키는 프레임워크를 개발해야 되었습니다. 처음 개발 시에는 Express framework를 기반으로 하피 개발을 시작했으나 몇가지 난관에 봉착하게 됩니다. 우선 mobile을 위해 batch functionality를 추가하다 express는 http server와 router 가 밀접하게 연결 되어 있어 효율적으로 기능을 추가 못하는 상황에 봉착합니다. 또한 너무 많은 미들웨어들이 connect roots(req,res,next)에 들어가 있어서 디버깅이 쉽지 않았다고 합니다. 
간단히 요약해드리면 쉽게 가려고 Express에 Wrapping하려다 망테크 한번 타고 분노를 Express 단점에 두고 맨탈 다잡고 Express의 문제점을 수정하는 방식으로 새로 만들게 되었다는 그런 스토리입니다.~ (물론 자신들이 원하는 프레임워크 요구사항 안에서의 문제 입니다) 자세한 내용은 여기 참조 

이후에 자세히 설명 드리겠지만 위에 탄생 배경으로 부터 유추해 볼 수 있는 Hapi의 장점은 아래와 같습니다.
1. Http Server 와 Router의 분리.
2. 심플한 Core (기본 미들웨어의 이해 없이는 깊이 있는 디버깅이 힘든 것과는 다르다)
3. 비즈니스 로직과 트랜스포트 레이어의 분리. 

물론 Express에서도 노력하면 비즈니스 레이어와 트랜스포트를 분리는 할 수 있겠지요. 그러나 비즈니스 로직은 사업이 변경 됨에 따라 자주 변경될 것이고 시간에 쫒기다 보면 분리에 대한 생각은 우선순위에서 밀리게 되겠지요. 하지만 Hapi 처럼 프레임워크 상에 구조적으로 분리를 강요한다면 비즈니스 로직이 자주 수정 되어도 Isolation을 지킬 수 있겠지요. 

저도 저자 처럼. 프레임워크 상에서 구조적 분리를 강요하는 것이 옳다고 생각합니다. 이게 프레임워크 철학인 것이죠. 또 다른 Hapi.js 장점은 이해하기 쉬운 심플한 Core와 필요한 플러그인들만 붙여쓸 수 있도록 완벽히 분리된 모듈들입니다. 

하피는 안전성이 검증된 오픈소스 프레임워크 입니다.
 모질라, 야후, 페이팔, Beats Audio, npmjs.org, 디즈니등에서 사용되어 지고 있으며 계속해서 발전해 나가고 있습니다.
 
Hapi는 프레임워크 컨셉이 명확합니다. 
1. configuration-centric design framework
2. Business Logic 과 transport layer의 분리 
3. Plugin Architecutre 와 Pack을 통한 모듈화.
4. native node의 장점을 유지 . (buffer ,stream)

많은 회사들이 (Express 말고) Hapi를 선택했습니다. 또는 전환 했습니다. (여기)
엄청난 User Pool을 가진 Express를 두고 왜 많은 회사들이 Hapi.js를 사용할까요? 

2. Why Hapi.js ?


"ㅇㅇ Hapi 좋은거 알겠어 근데 Express.js가 기능은 더 많은데  왜 Hapi를 써야되지?”

일단. 둘간의 비교를 하기 전에 NPM의 경우 왜 Hapi를 선택했는지 알아보고 다시 돌아오겠습니다.

NPM은 새로운 웹사이트를 구축하기 전에 프레임워크를 조사했습니다. 

프레임워크 선정 기준은 아래와 같았다고 합니다. 
1. 모듈화
2. 간결하고 기능 추가가 쉬울 것
3. 쉽고 빠르게 컨트리뷰터들이 적응하고 개발할 수 있을 것 ( 협업이 쉬운 프레임워크)
4. 템플릿 엔진
5. 그외 (안전성, 보안, 생산성, 지원)
그외 다른 조건으로는 개발기간은 1주일 정도 였다고 합니다.

조사 결과.
Restify - 템플릿엔진 없음 ,  Sails - 너무 기능이 많음  , KoaJS - generators를 쓴것은 맘에 들지만 아직 프로덕션레벨 사용가능 의문? 
-> Express or Hapi

NPM이 Hapi.js를 선정한 이유.
1. hapi plugin을 이용한다면 각 모듈 서비스를 별로 분리 개발이 가능하여 나중에 각각 별도의 서비스화가 가능하다. Express라면 별도의 모듈화 과정이 필요하다.
2. 성능. Walmartlabs는 Node.js Core Memory Leak을 발견하고 해결한 팀입니다. 이 팀이 Benchmark Drive Development를 기반으로 하피를 개발했고 결과적으로 성능 또한 훌륭하다고 합니다. 그렇겠지요 월마트 모바일에 쓸려면 성능은 중요하겠지요. 저 같은 중생은 믿고 쓰는거지요. 
3. 신뢰성,안전성 (Core 부분 Coverage 100%)
4. 빠른 이슈해결. (hapi 개발팀의 대응이 빠릿했데요.)

제가 보기에는 2,3,4 항목 보다는 1번 모듈화가 쉽다는 점이 NPM이 Express.js 대신 hapi.js를 선정한 가장 큰 이유 일 것 같습니다.

그외의 Hapi.js의 우수성.
1. Plugin Architecture
2. 훌륭한 기본 플러그인 Validation(joi) login(bell)….


3. Hapi vs Express 


Express.js의 문제점
1) http server와 router가 밀접하게 연결되어 있다.  
2) 여러가지 미들웨어들이 내부에 존재. : 너무 많은 서드파티 미들웨어를 가져오다 보니 해당 미들웨어 대한 공부 없이는 전체를 이해하기가 너무 어렵다. 디버깅은 헬게이트 안그래도 요상한 에러가 잘나는 Node.js에 충격과 공포!
3) 철학이 없다. 이것 저것 모든지 다 있는 만물상이 되어버렸다. 



Express.js와 비교하여 Hapi.js가 가진 장점
1) '프레임워크의 철학이 개발프로세스와 코딩스타일에 영향을 미친다’  - Plugin 시스템을 통해 Core는 깔끔한 상태로 유지하며 모듈화를 통해 다양성을 충족하는 방향을 잡았다.
2) Business Logic과 Transport Layer의 분리와 Plugin을 통한 모듈화를 통해 대형프로젝트에 협업하기 좋은 구조를 프레임워크에 녹여 내었다.
3) 코드를 깨끗하고 간결하게 관리 할 수 있다.

Express.js와 비교하여 Hapi.js가 가진 단점.
1) 커뮤니티 베이스가 상대적으로 작다
2) User Pool이 상대적으로 작다.


Merge Conflict 따위 일상이야! , 자바스크립트에 뭔 Configuration Centric이야 하시는 분들은 Express 계속 쓰시면 되구요.

코드보다는 설정 중심이 가독성이 좋고 깔끔하거든!, 이제 Node.js 협업이 중심이야. 모듈화 깔끔하게 되면 좋지 않니? 하시는 분들은 


저와 함께 Hapi를 사용 해보시면 되겠습니다. 실제로 홈피의 Tutorial 내용이 Core의 대부분이구요 10~20분 정도면 금방 익힐 수 있습니다. 

그리고 현재 Hapi.js의 커뮤니티 베이스도 지속적으로 증가할 것 같습니다. 그 이유는 반사이익 때문인데요.. 자세한 것은 다음장에서 설명드리겠습니다.

4. 어두운 그림자가 드리운 Express.js 

Express에 대해 모두가 우려하는 사항에 대해 객관적으로 말씀 드리겠습니다.

1) 떠나간 메인 개발자 TJ - Farewell Node.js
노드의 콜백지옥에 흥미를 잃고(?) Go로 떠나시면서 Express.js 메인테이너를 모집하게 됩니다. 꽤 유명한 사건이라 길게 설명을 하지 않겠습니다. (자세한 사항은 윗링크 참조)

2) Strongloop에 넘어간 Express와 떠나가는 Contributor들
메인테이너 권한을 팔았다? Express 리포는 TJ에서 Strongloop라는 스타트업 회사에 넘어갔습니다. Strongloop는 Express의 메인테이너가 되며 엄청난 홍보효과를 누렸지요.
물론 TJ가 팔았다는 증거는 없습니다. 정황 상… 여러사람들이 의심하고 있습니다.
여러사람들이 정황상 팔렸다고 생각하는 가장 큰이유는  Exppress.js foundation에 Repo로 넘기면 되었을 텐데…그렇게 하기로 했었구…

하여튼 Express 판매와 관련하여 3 개월전 Express.js Repo에서는 '왔다 장보리' 급의 막장드라마가 펼쳐졌었죠

참고 Open Source Dickishness by Eran Hammer

야! 싸움구경 났데~ Maintainer가 바뀐날 Github repo issue 



TJ의 반박글 StrongLoop & Express 

[첨부] 지난 12개월 동안 Commit 수를 보면 왜 Douglas가 TJ에게 분노했는가를 알수 있습니다
303  Douglas Christopher Wilson
 84  Jonathan Ong
 66  Roman Shtylman
 49  TJ Holowaychuk
  5  Fernando Silveira

저는 TJ가 한말 중에 '대부분의 상업적 지원을 받은 오픈소스 프로젝트는 죽거나 망했다'는 내용이 와닿네요. 

왜~ 슬픈 예감은 틀린적이 없나~~~

'I completely understand the rage that I'm seeing from everyone, it's easy to assume every commercial sponsorship will lead to the death of a project or poor results, but I'm sure we can all list numerous cases where the opposite is also true. I think it still takes a community to hold it together regardless.’ 

물론 현재까지 만으로도 Express는 훌륭한 프레임워크입니다. 하지만 많은 컨트리뷰터들이 이탈한 것은 자명한 사실이고 앞으로는 StrongLoop가 리드 메인테이너로서 자신들이 방향을 정하고 진행되어가겠죠. 상업적 기업이 활용하는 프레임워크인 이상 오픈소스라도 자신들의 방향에 맞춰지게 되지 않을까 싶습니다. 또한 상업적인 용도로 쓰일 프레임워크에 무료로 공헌하는 개발자는 없겠지요. 

물론 시간이 지나봐야 알겠지만 좋은 컨트리뷰터들이 계속해서 떠나간다면 익스프레스의 미래는 어둡다고 생각되어집니다.

이런 상황이라면 Sail.js 같이 Express Foundation 위에 만들어진 Framework들은 빠른 시일 내에 koa로 갈아타지 않을 까 싶습니다. 

여러가지 미련을 남겨둔채 여기서 1부 Why Hapi.js를 마치겠습니다.





다음 2부에서는 Hapi.js Restful Service 개발에 대해서 알아보겠습니다.


Posted by recopick

안녕하세요. RecoPick 팀의 김성민입니다.

지난번 DynamoDB의 Write Capacity를 낮춰서 DynamoDB 비용 줄이기 글에 이어서 DynamoDB 비용을 어떻게 또 절감했는지 공유해드리고자 합니다.

지난번 글에서 설명한 것처럼 DynamoDB 비용을 좌우하는 주요 요인이 Write Capacity이기 때문에, 저희 팀에서는 Write Capacity를 줄여서 DynamoDB 비용을 줄였습니다.


하지만 아무리 Write Capacity를 절반 정도로 줄였다고 하더라도, Write 연산이 전혀 없는 시간에 Write Capacity를 일정 수준을 유지해 줘야 하므로 Write 연산이 전혀 없는 시간의 DynamoDB 비용이 여전히 낭비되는 문제가 있었습니다.

마른 수건이라도 한 번 더 짜 본다는 심정으로 Read, 특히 Write 연산이 없는 경우에 DynamoDB 비용을 줄 일 방법이 없을까 고민을 하던 중에 Read/Write 연산이 없는 경우, DynamoDB의 Read/Write Capacity를 낮춰서 비용을 줄일 수 있지 않을까 하는 생각이 들었습니다.

DynamoDB의 Read/Write Capacity 변화를 감시하다가, Read/Write Capacity가 낮아지면 자동으로 Read/Write Provisioned Capacity를 낮추고, 다시 높아지면 올려주면 될 것 같았습니다.

여기서 고려해야 할 점은 DynamoDB의 제약 사항 중, 1일 최대 4회까지 Read 혹은 Write Provisioned Capacity를 낮출 수 있다는 점입니다. Read/Write Provisioned Capacity를 올리는 것은 DynamoDB 비용이 증가하므로, 회수 제한이 없지만, 낮추는 것은 1일 4회로 제한되어 있기 때문에, Read/Write Capacity 변화가 빈번한 경우 자동으로 Read/Write Provisioned Capacity를 조정하기 어렵다는 생각이 들었습니다.

이러한 고민을 하던 중에 Dynamic DynamoDB라는 오픈 소스를 발견했습니다.
Dynamic DynamoDB는 앞서 설명한 것처럼, DynamoDB의 Read/Write Capacity 변화에 따라 Read/Write Capacity를 자동으로 조절해주는 도구입니다.

특히, Read/Write Capacity 증가 시점 및 비율 등을 설정으로 조절할 수 있기 때문에, 1일 4회로 제한된 Read/Write Capacity를 낮출 수 있는 DynamoDB의 제약 조건 내에서도 Provisioned Read/Write Capacity를 자동으로 변경할 수 있었습니다.

아래 그래프는 Dynamic DynamoDB 적용 후, DynamoDB의 Write Capacity 변화 그래프입니다.





Dynamic DynamoDB 설치 및 운영 방법은 Dynamic DynamoDB 문서를 참고 하시면 되기 때문에 자세한 설명은 하지 않겠습니다.


대신 몇 가지 주의하실 점을 설명해 드리자면,


(1) Read/Write 연산이 전혀 없으면서도 Read/Write Capacity를 줄이고자 한다면, allow-scaling-down-Reade-on-0-percentallow-scaling-down-writes-on-0-percent를 true로 설정해야 합니다.


(2) Dynamic DynamoDB는 기본적으로 CloudWatch의 5분 동안의 모니터링 결과를 사용해서 Read/Write Capacity를 조절하는데, CloudWatch 결과의 최신성을 조절하려면, lookback-window-start를 조정하시면 됩니다.

lookback-window-start 값을 5로 하면, now() - 5(분) 에서 now() (분)까지의 Cloud Watch 모니터링 결과를 사용하게 됩니다.

하지만 5분 미만의 Cloud Watch 모니터링 결과를 사용할 수 없으므로, 너무 작게 설정하면, Read/Write Capacity가 자동 조절되지 않습니다.


(3) 1일 4회까지 Read/Write Capacity를 낮출 수 있다는 Dynamo DB 제약 사항을 지키려면,

increase-{reads, writes}-with는 작게 decrease-{reads, writes}-with는 크게 하는 편이 좋습니다.

즉, Batch 작업의 경우, Read/Write가 천천히 증가하다가 작업 종료 시점에 급격하게 줄어들기 때문에, 증가 비율보다 감소 비율을 크게 해서 작업 종료 시점에 Read/Write Capacity를 크게 낮춰서 1일 Read/Write Capacity 감소 횟수를 줄이는 것이 좋습니다.


[참고 자료]







Posted by recopick

안녕하세요. RecoPick팀의 김성민 입니다.


이번 글에서는 HBase를 사용하면서, 궁금했던 점들 몇 가지를 질의 응답 형식으로 정리해 봤습니다.

FAQ와 다르게 자주하는 질문들이 아닌 것 같아서, 제목을 IAQ[각주:1]라고 했습니다.


Q1. HBase의 .META. 테이블도 split 될까?

A1. 안됨

HBase의 .META. 테이블은 region 정보를 저장하고 있는 특별한 테이블인데, BigTable 논문에서 .META. 테이블이 여러 region으로 나눠질 수 있도록 설계했지만, HBase에서는 .META. 테이블은 split 되지 않도록 구현했습니다. 그리고, -ROOT- 테이블은 .META. 테이블이 저장된 region 정보를 가지고 있기 때문에, split 되지 않습니다. 하지만, HBase에서는 .META. 테이블이 split 되지 않기 때문에, 0.94 이후 버전 부터는 -ROOT- 테이블을 없애고, .META. 테이블만 사용하도록 변경하였습니다.


.META. 테이블에 모든 region의 메타 정보(데이터가 저장된 위치 정보)를 저장하고, .META. 테이블이 split 되지 않기 때문에, HBase 클러스터는 최대 1개의 region에 저장할 수 있는 메타 정보 개수 만큼의 region을 저장할 수 있습니다. 즉, HBase 클러스터를 무한히 크게 할 수 없습니다.




Fig 1-(a). .META. 테이블 구조



Fig 1-(b). Zookeeper와 .META. 테이블 구조





Fig 1-(c). BigTable의 root, meta 테이블 구조


Q2. (minor/major) compaction 작업은 서로 다른 region들 사이에서도 진행되는가?

A2. 안됨.

HBase에서는 주기적으로 데이터 사이즈가 작은 파일들을 하나로 합쳐주는 compaction 작업을 진행합니다. 데이터를 저장할 때, 자동으로 split 해서 저장했다가, 파일 크기가 작은 파일들이 많이 생길 경우, 하나의 큰 파일로 합쳐주는 작업을 진행하는데, compaction 작업의 단위는 directory가 아니라 file 단위이기 때문에, 서로 다른 region에 있는 작은 파일들을 하나로 merge하지는 않습니다.

HBase에서 region은 HDFS상에서 하나의 directory를 의미하고, compaction의 동일한 region 즉, directory 내에 있는 파일들을 하나의 큰 파일로 합쳐주는 작업이라고 이해하시면 됩니다.




Fig 2. Minimum compaction threshold


Q3. HBase에서 저장하고자 하는 테이블(region)을 미리 split 한 후, 데이터를 저장할 때, major compaction이 시작되면, 데이터(HFile)가 없는 테이블(region)은 삭제 되는가?

A3. 안됨.

HBase에서는 write 연산이 빈번하게 연속적으로 발생할 경우, region split 역시 빈번하게 발생 하기 때문에, 미리 region을 split 해서 write할 때, region이 split되는 것을 회피해서 write 성능을 향상 시키는 방법을 종종 사용합니다. 그런데, 실제 write 연산을 수행하기 전에 region을 split 하는 것이기 때문에, 실제 데이터는 존재하지 않고, .META. 테이블에 rowkey와 region server 정보가 기록되어 있습니다. 이후, write 연산을 수행하면, 저장할 데이터의 row key가 미리 split한 region에 start과 end row key 범위에 들어있지 않은 경우, 특정 region에는 데이터가 전혀 존재하지 않을 수 있습니다. 이렇게 되면, major compaction을 할 때, region의 데이터 사이즈가 작기 때문에, 데이터가 존재하지 않은 region은 삭제 될 것 같다고 추측할 수 있습니다. 하지만, Q2에서 설명한 것 처럼, compaction은 여러 파일들을 하나로 합치는 작업이지 디렉터를 하나로 합치는 작업이 아닙니다. 따라서, region은 일종의 디렉터리이기 때문에, 데이터 즉, 파일을 하나도 가지고 있지 않은 region (비어 있는 디렉터리)들을 compaction 작업 시, 하나로 합치거나 삭제 되지 않습니다.




Fig 3. HBase Architecture - Storage


Q4. Region이 split 될 때, region의 데이터 크기를 기준으로 split 되는지, 아니면, region 내의 row key의 최소, 최대 값을 기준으로 하는지?

A4. 설정에 따라 다름.

Region을 split하는 정책은 "hbase.regionserver.region.split.policy" 라는 설정에 따라서, 결정됩니다.

0.94 이전 버전에서는 region이 데이터 크기를 기준으로 split 했지만, 이후에는 defalut 설정이 변경되었습니다.

다음과 같은 미리 정의된 Split policy가 있습니다. (물론, custom split policy를 구현하실 수도 있습니다.)


(1) ConstantSizeRegionSplitPolicy

(2) IncreasingToUpperBoundRegionSplitPolicy

(3) KeyPrefixRegionPolicy

(4) DelimitedKeyPrefixRegionSplitPolicy

(5) DisabledRegionSplitPolicy




Fig 4. HBase Region splitting


Q5. WAL (Write Ahead Log) 를 disable 시킨 상태에서 write을 수행 중이던 region server가 crash 될 경우, crash 이전까지 write한 데이터는 HBase에 저장되었을까?

A5. 알수 없음.

HBase에서 write 연산을 수행하면, WAL(HDFS)와 Memstore(Memory)에 데이터를 기록하는데, WAL을 사용하지 않을 경우, Memstore에만 데이터를 쓰고, Memstore에 더 이상 데이터를 쓸 수 없을 경우나, 혹은 일정 시간 간격으로 Memstore에 있는 데이터를 HDFS에 강제로 기록합니다. 그런데, 만약, Memstore의 데이터가 HDFS에 flush 되지 않은 시점에 region server가 crash된 경우, 메모리 상에 있는 Memstore 데이터가 사라지기 때문에, region server가 crash 되기 전에 write 한 데이터가 정상적으로 저장되었다고 확신할 수 없습니다.

만약, WAL을 사용했다면, 새로운 region server가 실행 되면서, WAL를 replay 하기 때문에, region server가 crash 되기 전의 데이터가 정상적으로 저장됩니다.




Fig 5-(a). HBase Write Path



Fig 5-(b). HBase Write Sequence Diagram



[참고 자료]

Q1. (1) http://blog.cloudera.com/blog/2013/04/how-scaling-really-works-in-apache-hbase/ 

       (2) https://blog.safaribooksonline.com/2012/11/16/tip-2-hbase-meta-layout/

(3) http://research.google.com/archive/bigtable.html


Q2. (1) http://hbase.apache.org/book.html#compaction


Q4. (1) http://hortonworks.com/blog/apache-hbase-region-splitting-and-merging/

       (2) http://hbase.apache.org/book/config.files.html#hbase.regionserver.region.split.policy


Q5. (1) http://hbase.apache.org/book/config.files.html#hbase.regionserver.optionalcacheflushinterval

       (2) http://www.slideshare.net/enissoz/hbase-and-hdfs-understanding-filesystem-usage

       (3http://blog.sematext.com/2012/07/16/hbase-memstore-what-you-should-know/

(4http://blog.cloudera.com/blog/2012/06/hbase-write-path/

(5http://www.larsgeorge.com/2010/01/hbase-architecture-101-write-ahead-log.html

 

  1. Peter Norvig의 Java IAQ에서 제목을 인용함(http://norvig.com/java-iaq.html) [본문으로]
Posted by recopick
TAG HBase

안녕하세요. RecoPick팀 김군우입니다.


RecoPick에서는 쉽고 빠르게 추천 서비스를 사이트에 적용할 수 있도록, 아래와 같은 추천 위젯을 제공 해 드리고 있습니다.


RecoPick 추천 위젯추천 위젯 스크린샷



참고

 - 커스텀 CSS를 통해 추천 위젯의 디자인을 마음껏 바꿔보세요.: http://blog.recopick.com/40

 - 한 페이지에 여러 개의 추천 위젯을 제공해보세요!: http://blog.recopick.com/31

 - 베이비 엔젤에 추천이 적용되었습니다. + 추천 위젯 소식: http://blog.recopick.com/9



추천 위젯에는 한 번에 좀 더 많은 추천 상품을 보여 달라는 요구사항에 맞추어 Swipe(혹은 페이징) 기능이 포함되어 있습니다.


처음 추천 위젯을 만들었을 때는 간단하게 Swipe.js 라이브러리를 사용하여 이 기능을 구현하였었습니다만, 이 라이브러리가 아이프레임으로 사용되었을 때에는 iOS에서는 브라우저가 죽어버리는 치명적인 결함이 있었습니다. https://github.com/thebird/Swipe/issues/407


결국 고객사의 다양한 요구사항을 지속적으로 반영할 수 있도록 자체적으로 Swipe 라이브러리를 개발하였고, 이를 오픈 소스로 공개하였습니다.


RecoPick Swipe https://github.com/mctenshi/recopick-swipe


RecoPick Swipe는 터치 디바이스 에서의 Swipe 동작에 따른 이전, 다음 페이지 이동, PC 환경을 위한 이전, 다음 버튼 설정, 무한 Swipe, 현재 페이지 표시 등의 기능을 제공합니다. 사이트를 통해 자세한 동작 원리, 데모, 설명 문서 등을 확인 하시기 바랍니다.


사이트를 둘러볼 시간이 없으신 분들은 아래 데모를 통해 PC/모바일에서 모두 사용 가능한 Swipe 기능을 간단히 체험해보세요~

http://jsfiddle.net/mctenshi/qA9aw/1/


RecoPick Swipe 데모데모 스크린샷



RecoPick Swipe는 여러 사이트에서 서비스를 하여 왔고, Swipe 기능 개발에 필요한 요소들을 지속적으로 갖추어 왔습니다. 앞으로도 이 라이브러리는 RecoPick 서비스와 함께 발전해나아갈 예정이니 많이 이용해주세요~ :)



Posted by recopick