Monthly Archives: July 2012

[입 개발] 인터넷 스타트업을 위한 소프트웨어 스택 – 하드웨어 이중화

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

 

일반적으로 개발자들이 잘 아는 분야는 소프트웨어 개발입니다. 엄청나게 세분화되어 있는 세상에서, 네트웍 장비나, 서버의 특성등에 대해서 자세히 알기는 어렵습니다. 그래서 조그만 규모가 있는 회사들은 하드웨어 쪽을 관리하는 관리자들이 다 따로 있습니다. 어떤 분은 L4 스위치의 전문가이고, 어떤 분은 NAS 스토리지에 대해서 자세히 아시는 거죠. 그런데 이제 막 창업한 스타트업이나, 이미 어느 정도 시간이 지난 기업이라도, 이런 분야에 대해서 잘 아시는 분들을 다 고용하기는 어렵습니다.

 

그런데 사실 서비스를 운영하다보면, 실제 소프트웨어 장애도 많지만, 그것보다 하드웨어 장애를 더 많이 만나게 됩니다. 서버를 1000대 이상 운영하는 서비스를 보면, 하루에 최소 1~2대 이상 서버가 죽어나갑니다. 그런데 재미있는 것은 대부분의 어느정도 경험이 있는 개발자들은, 이렇게 서버가 장애나는 경우에 대해서 대비한 서비스 아키텍처를 설계하고 만들기 시작합니다. 그래서 서버 한 두대가 죽는 것 가지고는 실제로 서비스에 큰 문제가 일어나지 않도록 구성하는 것이지요.

 

일반적으로, 여기까지가 우리 개발자들의 생각의 범위입니다. 서버가 죽는 것은 개발자가 생각하는 스케일러블한 아키텍처 상의 고려 사항에 들어가는 거죠.(워낙 자주 경험하니까요.) 그런데 대부분 전체 서버가 한꺼번에 장애 나는 것에 대해서는 고려하지 않습니다. 어차피 그런일은 거의 발생하지도 않고, 비용대비 효과가 미비할 가능성이 큽니다. 특히 이제 서비스를 시작하는 스타트업이라면 비용대비 효과에 대한 고민이 더더욱 필요합니다.

 

그런데, 아주 쉽게, 이렇게 전체 서버가 죽는 경우를 경험하는 케이스가 생길 수 있습니다. 그게 바로 개발자들은 잘 신경쓰지 않는 네트웍 장비쪽의 장애입니다. 즉 라우터나, 메인 스위치가 고장이 나면, 거기에 연결된 모든 서버가 장애가 나게 됩니다. 그런데 서버쪽 경험이 없는 분들은 서버 코드는 짜더라도 이런 부분에 대해서는 쉽게 알지 못하시는 경우가 많습니다. 저도 그랬습니다. 쿨럭…

 

다시 처음으로 돌아가서 일반적으로 우리가 구성하는 초기 서비스는 다음과 같은 물리적 구성을 가질 것입니다.

 

일반적으로 개발자가 고민하는 범위는 서버의 장애 입니다. 보통 Switch 나 Route 따위는 신경쓰지 않습니다. 쿨럭, 그리고 서버 한대가 죽더라도 다른 서버가 FailOver 할 수 있도록 하는 것이 일반적입니다. 이제 막 시작하는 업체라면 이런 구성도 안할수도 있을 듯 하네요.

 

그런데 만약 Route나 Switch가 장애가 나면 어떻게 될까요? 서버는 잘 돌아가는데, 전혀 다른 서버들과 연결이 안되는 이슈가 벌어지거나, 서버에는 전혀 리퀘스트가 안오는데, 접속이 안된다는 글들만 트위터나 페북에 바글바글 할껍니다.(이 정도면 이미 성공한 건가요?)

 

그러면 어떻게 물리적으로 구성해야 안전할까요? 서버랑 마찬가지 입니다. Route 랑 Switch를 두 개 이상으로 늘리고, 교차 연결이 되도록 설정해 두면 됩니다. 물론 서버에도 랜 카드 하나씩 더 설치해서 처리해주면 됩니다.(랜카드를 추가하면, 랜카드 장애시에도 유용합니다.) 즉 다음과 같은 구성이 됩니다.

이런 구조로 구성을 해두면, Route나 Switch 에서 장애가 나더라도 서비스는 문제가 없습니다.

 

 

서버 호스팅을 이용해서 서비스를 하게 되면, 어찌되었든 하드웨어 장애와 부딪치게 되어있습니다. 클라우드, 클라우드를 외치는 이유중에 이런 부분에서 살짝 벗어날 수 있다라는 장점도 있긴 합니다. 하지만 일단 클라우드 보다 비용을 보면(인건비 제외 -_-) 서버 호스팅이 더 싸기 때문에 이렇게 시작하시는 분들도 많을 것이라고 생각합니다. 이런 부분에 대해서 알고 지나가시면 좋을듯 합니다.

 

* 혹시나 스타트업을 운영하시는 분들중에 자신의 소프트웨어 스택을 공개하고 싶은신 분은 저에게 연락 주시면 감사하겠습니다. charsyam@naver.com 이나 @charsyam 으로 멘션 주시면 됩니다. 감사합니다.

 

 

[입 개발] 인터넷 스타트업을 위한 소프트웨어 스택 – 프롤로그

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

 

제가 개인적으로 하고 싶은 프로젝트가 몇 가지 있는데, 그 중에 하나가, 이것입니다. 스타트업에서 사용할 만한 소프트웨어 스택을 정리하고, 현재 인터넷 스타트업에서 사용하는 기술 스택들을 분석해서 장단점을 분석하고, 사용하기 쉽게 template 형태나, 정보를 제공하는 것이 목표입니다.(혹시나 투자하실 분은 ㅋㅋㅋ 저에게 연락을 ㅋㅋㅋ)

 

한참동안 머릿속으로 구성만 하고 있다가, 조금씩 정리해볼 생각입니다. 다만 약점은 제가 스타트업을 다닌 경험이 없어서, 상상에 의존하거나, 주변 분들의 도움을 얻어야 할 것 같습니다. 혹시나, 스타트업을 운영하시는 분들 중에, 소프트웨어 스택을 공개하실 분들은 저에게 연락을 주시면 감사하겠습니다. charsyam@naver.com 입니다. 공개가 꺼려지시면 이런 이런 것들을 쓴다 정도로만 알려주셔도 됩니다.    제 능력으로 보답을 해드릴 수 있는 것은 거의 없지만, 혹시나, 기술적인 부분에 대해서 필요하신 부분이 있으면, 제가 아는 한도내에서는 자세히 설명을 쿨럭…( <– 이런걸로 때우겠다는 놀부 심보를 ㅋㅋㅋ)

 

아 혹시나, 제가 못미더울 분들을 위해서(저도 절 못믿습니다. ^^) 최초에는 디지털 포렌식 업체에서 5년 5개월 정도 디지털 포렌식 소프트웨어를 개발했습니다. 윈도우 프로그래밍, 파일 시스템, 파일 포맷 분석이나 내부 검색 시스템 정도를 개발해봤습니다. 그리고 그 뒤에는 NHN에서 2년 정도는 윈도우/윈도우 모바일/아이폰 등의 어플리케이션 개발을 했고, 그 뒤에 2년 정도는 네이버 메일 백엔드 쪽 개발을 했습니다.   그럼 경력이 대략 9년 반 정도 되는건가요? 물론, 경력에 맞는 실력을 갖췄냐고 물어보시면 그냥 거의 -_- 초보라고 보시는게 쿨럭… 그럼 제 소개는 간단히 마치고, 주로 해당 내용에 들어갈 것들은…

 

1. 기본적인 소프트웨어 스택 소개 및 구축 방법

  • HAProxy, Nginx, Vanish, Redis, Memcached 등의 개별 솔루션 소개 및 간략한 내부 구조
  • 차후에는 Hadoop, HBase, Cassandra, MongoDB 등의 NoSQL 류와 Mysql, PostgreSQL 등의 DB류 소개

2. 현존하는 인터넷 스타트업들이 고려하거나 구축한 소프트웨어 스택 소개(사실 이걸 해보고 싶은데, 이건 누가 연락을 주셔야 쿨럭…)

 

뭐, 이걸 할 수 있으면 꽤 재미있을 듯 한데, 혹시나 공개하고 싶으신 분들은 저에게 메일이나 연락주시면 감사하겠습니다. 제가 필리핀에 있어서, 인터넷이 잘 안되는 환경이라 혹시나 메일 주셨는데 답변이 늦어도 아, 또 비와서 인터넷 끊겨서 연락을 못하는구나 라고 생각하시면 감사하겠습니다. @charsyam 으로 멘션주셔도 됩니다. 감사합니다.

[발 번역] 클라우드 컴퓨팅 시스템 아키텍처 다이어그램

해당 블로그는 KT UCloud 의 지원을 받고 있습니다.

해당 글은 http://support.rightscale.com/12-Guides/EC2_Best_Practices/EC2_Site_Architecture_Diagrams 글을 발 번역한 것입니다. 오역에 주의하시기 바랍니다.  해당 내용을 보면 RightScale을 이용해서 구성하는 구조라고 나옵니다. 그렇다면, 제가 RightScale 를 쓰기를 추천해서 해당 글을 선택한 것은 아니라, RightScale을 이용하든 안하든, 실제로 클라우드 기반 설계를 하게되면, 아래에서 보여주는 형태로 하게 되기 때문입니다. RightScale은 여러가지 클라우드 설정을 쉽게하고 구축을 도와주는 것이므로, 실제로, 최종 결과물은 우리가 꼭 해당 기술을 이용하지 않더라도 따라가야하는 모습입니다. 이번에 또, 아마존의 버그로 인해서 몇몇 유명 사이트(instagram, heroku, pinterest, raddit ) 이 사이트가 제대로 동작하지 않는 이슈가 있었습니다. 그에 대비하는 것이 Multi Cloud나 Hybrid Cloud 가 될 것입니다. 물론, 이런 클라우드 서버 시스템의 구조를 따르기 전에, 자신의 서비스나 데몬이 장애에 대응 가능하게 구성되어 있는지를 꼭 먼저 체크하시기 바랍니다.

Table of Contents

  1. 1. Overview
  2. 2. Things to Consider
  3. 3. Example Reference Diagrams
    1. 3.1. Single “All-in-one” Server
    2. 3.2. Single Cloud Site Architectures
      1. 3.2.1. Non-Redundant 3-Tier Architecture
      2. 3.2.2. Redundant 3-Tier Architecture
      3. 3.2.3. Multi-Datacenter Architecture
      4. 3.2.4. Autoscaling Architecture
      5. 3.2.5. Scalable Architecture with Membase
      6. 3.2.6. Scalable Multi-Tier Architecture with Memcached
      7. 3.2.7. Scalable Queue-based Setups
        1. 3.2.7.1. Number of Jobs
        2. 3.2.7.2. Time
        3. 3.2.7.3. Internal Hybrid Setup
        4. 3.2.7.4. Alert-based and Queue-based Scalable Setup
    3. 3.3. Hybrid Cloud Site Architectures
      1. 3.3.1. Scalable MultiCloud Architecture
      2. 3.3.2. Failover MultiCloud Architecture
      3. 3.3.3. MultiCloud Disaster Recovery Architecture
      4. 3.3.4. Cloud and Dedicated Hosting Architecture

Overview

아래에서 RightScale Platform을 이용해서 public, private 클라우드 인프라스트럭처를 이용하는 클라우드 기반 솔루션의 샘플 다이어그램을 몇개 찾을 수 있을것 입니다.  해당 아키텍처의 대부분은 MultiCloud Marketplace에서 존재하는 ServerTemplates를 이용해서 구성할 수 있을 것입니다.  각각의 어플리케이션은 유일하고, 요구사항에 대해서, 목적에 맞게 수정된 것들입니다. 아래의 시스템 아키텍처 다이어그램의 목적은 클라우드에서 자신만의 시스템 아키텍처를 디자인 해야 할 때, 기본 참고 아키텍처로 사용할 수 있는 실제 예제를 알려주기 위해서 입니다. 만들고자 하거나, 수정하거나, 자체 프로젝트의 요구사항에 따라서 변경해야 할 때, 필요로 하는 것과 비슷한 시스템 아키텍처를 찾을 수 있습니다. 다이어그램들은 장애 복구(DR)나 멀티 클라우드 배포와 같은 특별한 컨셉으로 디자인되었습니다. 자기 만의 솔루션 아키테처를 디자인 할 때, 아래에 묘사된 여러 컨셉과의 연관에 대해서 고려하시기 바랍니다.

Things to Consider(고려사항)

여기에 자신만의 클라우드 기반의 시스템 아키텍처를 설계하려고 한다면 깊이 고려해야 하는 여러가지 요소들이 있습니다. 특히 멀티 Cloud/Region 아키텍처를 고려중이라면 더더욱 그렇습니다.

  • Cost - 사이트/어플리케이션을 설계 하고, 서비스를 시작하기 전에, 사용할 클라우드 인프라스트럭처에서 제공하는 가격 모델과 SLA에 대해서 명확하게 이해하고 있어야 합니다. private 과 public 클라우드는 각각 다른 비용이 소모됩니다. 예를 들어, AWS에서는 같은 데이터센터( 같은 Availability Zone ) 에서는 데이터 전송비용이 무료입니다. 그리고 같은 EC2 Region 내의 데이터 통신이 다른 Region의 클라우드나 자체 데이터센터와의 통신보다 쌉니다.
  • Complexity - 고도로 맞춤화된 하이브리드 클라우드 솔루션 아키텍처를 구축하기 전에, 해당 어플리케이션의 동작에 필요한 요구사항(SLA 등등)에 대해서 확실하게 이해해야 합니다. 간결한 아키텍처는 항상 디자인하기도 쉽고 관리하기도 편하게 만듭니다. 좀 더 복잡한 아키텍처는 오직 간결한 버전이 충분하지 않을 때만 사용되어야 합니다. 예를 들어, 멀티 클라우드(Region들)로 분산된 시스템 아키텍처는 아키텍처 레벨에서 복잡성이 늘어나고, 다른 클라우드간 장애 대응을 위해서 마이그레이션 되는 데이터베이스와 통신하거나 좀 더 반응시간에 안정적이기 위해서 어플리케이션 레벨에서도 많은 변화가 필요할 것입니다.
  • Speed - 클라우드는 웹 사이트와 어플리케이션의 속도나 반응속도에 좀 더 유연함을 제공합니다. 예를 들어서, 어플리케이션의 필요에 따라서 서로 다른 종류의 인스턴스를 시작할 수 있습니다. 높은 메모리나 높은 CPU 타입의 인스턴스가 필요하다면? 유저의 위치에 따라서 지역적으로 가까운 클라우드에서 낮은 레이턴시를 제공하고 싶다면? CDN이나 캐시 서비를 이용하는 것이 비용이 싸거나, 필요하다면? 멀티 클라우드간의 통신 때문에, 추가적인 레이턴시가 필요하다면, 어플리케이션에 따라서 용납하지 못할 수도 있습니다.
  • Cloud Portability - 클라우드 서비스에서 제공하는 툴이나, 서비스, 예를 들어, 로드밸런서나 데이터 베이스 서비스를 사용하는 것이 쉽긴 하지만, 아키텍처의 일부분을 다른 클라우드 서비스로 옮겨야 할 필요가 있을 때, 아키텍처를 변경해야 한다는 것을 깨닫는 것은 매우 중요합니다.  Service Template 은 클라우드 종류에 상관없이 사용이 가능하므로, 이것을 이용해서 이동 가능한 유연한 클라우드 아키텍처를 만들 수 있습니다.
  • Security - 멀티 클라우드 시스템 아키텍처에서, 클라우드 간 통신이 일반 인터넷으로 수행된다는 것을 아는 것은 매우 중요합니다. 그러므로 VPN이나 암호화를 이용해서 보안에 대해서 생각을 해야합니다.

Example Reference Diagrams

아래의 아키텍처 다이어그램은 간단한 것에서 좀 더 복잡한 레퍼런스 아키텍처를 보여줍니다.(역자 주: 자신의 기준에 맞춰서 간단한 거 일 수록 유지보수가 편하겠죠?)

Single “All-in-one” Server

“All-in-one” Server Template 들 중에 하나를 사용하면, 예를 들어, LAMP(Linux, Apache, Mysql, PHP) Server Template를 하나의 서버에서 구동하면, 해당 서버는 Apache 웹 서버와, PHP, Mysql을 포함하고 있습니다. 신규 RightScale 유저와 기본적인 데모에 유용한 간단한 “All-in-one” Server Template 들을 MultiCloud 마켓플레이스에서 쉽게 찾을 수 있을 겁니다.

diag-System_Architecture-1.png

Single Cloud Site Architectures

표준적인 3-Tier 웹 사이트 아키텍처에서는, 시스템의 각 티어마다 적어도 한대 이상의 서버가 있습니다.(Load Balancing Server, Application Server, Database Server)

Non-Redundant 3-Tier Architecture

아키텍처의 각 티어간의 상호 테스팅이 목적이라면, 비용과 리소스를 아끼기 위해서, 이중화 되지 않은 시스템 아키텍처를 원할 것입니다. 개발 목적이나 간단한 테스트를 위해서 이러한 이중화 되지 않은 시스템 아키텍처를 주로 원합니다. 아래 예제 다이어그램에서, 각 어플리케이션이나 사이트의 티어마다 서버들이 있습니다. 실제 서비스 환경에서는 해당 아키텍처는 권장하지 않습니다.

diag-System_Architecture-2.png

Redundant 3-Tier Architecture

클라우드에서 실행되는 모든 실 서비스 환경은 장애회복을 위해서 이중화되어야 합니다. 일반적으로 클라우드에서 Auto Scaling의 장점을 취하기 위해서 해당 어플리케이션 티어에서 서버를 여러 대 추가할 수 있는 형태로 사용할 것입니다. 그러나, 어플리케이션이 auto scale 되도록 고혀하지 못한 시나리오가 몇 개 있을 것입니다. 이런 경우에도, 아래 레퍼런스 아키텍처의 각 티어에서 이중화 된 것을 보고, 이중화된 멀티 티어 아키텍처를 만들 수 있습니다.  아래의 예제를 보면, 두 개의 로드밸런서 서버, 두 대의 어플리케이션 서버, 마스터, 슬레이브 데이터 베이스가 있습니다. 이중화된 아키텍처는 웹이나 어플리케이션을 시스템 다운으로 부터 보호하는 것을 돕습니다.(역자 주: 클라우드를 사용하지 않을 때는 물리적 시스템 구성에도 신경을 써야 합니다. 최소 라우터 두 개, 스위치 두 개를 이용해서 LoadBalancer 를 연결해 두고 각 서버단에 연결을 해두어야 장비 장애시 안전성을 보장해줍니다.)

아래의 샘플 다이어그램은 데이터베이스 티어에서 분리된 볼륨 셋을 사용한 것을 보여줍니다. 만약 데이터베이스가 크고, 빠른 백업이 필요하다면, 데이터 스토리지를 위한 불리된 볼륨 셋을 고려하는 것을 권장합니다.

diag-System_Architecture-3.png

Multi-Datacenter Architecture

현재 사용하는 클라우드 인프라스트럭처가 다중 데이터센터(Zone) 을 지원한다면, 시스템 아키텍처를 이중화 레이어를 다중 데이터센터를 이용해서 펼쳐 놓기를 권장합니다. 클라우드의 각 데이터센터는 같은 지역 클라우드 내에서 분리된 지역에 위치하도록 설계되었습니다. 만약 하나의 데이터센터에 전력 장애가 발생하면, 다른 데이터센터는 영향을 받지 않습니다. 예를 들어서, AWS의 각 EC2 Region(cloud)는 다수의 Availability Zone들을 가지고 있습니다. 다중 데이터센터를 사용하는 장점은 특정 데이터센터의 네트웍이나 전력 장애, 또는 리소스의 부족, 서비스 용량 초과 등의 안좋은 상황에서 전체 웹사이트나 어플리케이션을 보호할 수 있다는 것입니다.

좋은 사례로써, 클라우드 인프라스트럭처에서 지원이 된다면, 레퍼런스 아키텍처처럼 다중 데이터센터 간에 연결이 되도록 해야 합니다. 아래의 다른 레퍼런스 아키텍처 다이어그램에서 처럼, 명시적으로 다중 데이터센터 사용이 보여지지 않더라도, 다중 데이터 센터를 사용하는 것을 권장합니다.

Note: 추가적인 비용은 다른 데이터센터간에 데이터 전송이 얼마나 발생하는 가에 달려있습니다.

diag-System_Architecture-4.png

Autoscaling Architecture

시간에 따른 어플리케이션이나 웹사이트의 필요에 따른 수평 적인 확장 능력은 클라우드이 주요 장점중에 하나입니다.( 운영 중인 서버 자원을 늘리거나, 줄일 수 있는) RightScale 과 함께라면, 아키텍처의 특정 티어를 미리 정의된 조건에 따라 기반해서 자동으로 확장가능한 서버 구조로 사용할 수 있습니다. Autoscaling은 클라우드 레퍼런스 아키텍처의 어플리케이션 티어에서 가장 흔히 사용되고 있습니다.

diag-System_Architecture-5.png

Scalable Architecture with Membase

Master-Slave 구성의 Mysql 셋팅을 원한다면, 데이터베이스 티어를 위해서 모든 Membase 노드들 간에 데이터를 리플리케이션 하는 분산 NoSQL 데이터베이스인 Membase(Couchbase)를 이용할 수 있습니다. 기업용 버전을 사용하길 원한다면, 아래에서 보여주듯이 각 노드마다 볼륨을 붙일 수 있습니다. 커뮤니티 버전의 경우는 볼륨의 사용이 불가능합니다.

diag-System_Architecture-7.png

Scalable Multi-Tier Architecture with Memcached

어플리케이션과 웹 사이트를 위해서 많은 스태틱 파일을 서비스 해야하고, 많은 읽기가 필요해서, 읽기가 많은 데이터베이스의 부하를 줄이기 위해, 클라우드 시스템 아키텍처에 Memcached 레이어를 추가하기를 원할 수 있습니다.  Memcached는 오픈 소스 분산 메모리 객체 캐싱 시스템으로 데이터베이스의 부하를 감소시켜서 동적 웹 어플리케이션의 속도를 높이기 위해서 만들어졌습니다. 아래의 샘플 다이어그램을 보면, 어플리케이션 서버들은 여전히 데이터베이스에 쓰기를 하고 있지만, 많은 흔히 사용되는 객체들은 마스터 DB 서버 대신에 memcached 서버들 중에 하나에서 서비스 되고 있습니다.

diag-System_Architecture-6.png

Scalable Queue-based Setups

(AWS only)

RightScale의 Grid Edition 은 아마존 EC2 같은 클라우드 컴퓨팅 인프라스트럭처의 확장 기능의 장점을 가짐으로써, 효과적인 잡 처리를 위한 효과적인 솔루션으로 백엔드 배치 프로세싱 프레임워크를 제공합니다. 큐 안의 작업 수에 기반하거나 큐 안에 얼마나 오래 샘플 잡들이 체류했는가에 기반해서, 확장가능한 Grid 어플리케이션을 생성합니다.

Number of Jobs

큐 안의 작업 수에 기반해서 배치 프로세싱 어플리케이션을 확장하는 것은 가장 일반적인 방법입니다.

rightgrid_number_jobs.gif

Time

큐 안에 샘플 잡들이 얼마나 오래 처리되지 않았는지를 기반으로 Grid 어플리케이션을 생성합니다. 이 셋팅에서, 큐 안에 10개의 아이템 중에 하나를 무작위로 샘플로 선택합니다.  서버들은 큐 안의아이템의 평균 체류 기간이나, 가장 오래된 아이템에 기반해서 확장하게 될 것입니다.

rightgrid_time.gif

Internal Hybrid Setup

이미 Grid 아키텍처를 쓰고 있거나 여전히 사용하길 원하는 내부 컴퓨팅 리소스가 이미 있다면, AWS Region 안에 필요할 때 확장 가능한 하이브리드 모델을 만들 수 있습니다. 해당 셋팅은 내부 자원의 사용과 클라우드의 제한 없는 컴퓨팅 리소스를 사용할 수 있는 유연성을 제공합니다.

rightgrid_internal_hybrid.gif

Alert-based and Queue-based Scalable Setup

같은 배포에 여러개의 서버를 붙일 수 있기 때문에, 확장가능한 프론트 엔드, 백 엔드 서버군들을 가지는 두 개의 확장 가능한 아키텍처 역시 만들 수 있습니다.

site_grid_array_diagram_v1.png

Hybrid Cloud Site Architectures

클라우드의 웹 사이트, 어플리케이션을 보호하는 다른 방법은 여러 개의 public/private 클라우드 인프라스트럭처 와 개별적으로 호스팅된 서버를 하이브리드한 클라우드 사이트 아키텍처를 디자인하는 것입니다. RgihtScale 플랫폼의 주요 장점중에 하나는 클라우드 이동성입니다. 같은 설정 정보들을 이용해서(ServerTemplate과 RightScripts 등등) 같은 기능의 서버들을 여러 public/private 클라우드에서 시작할 수 있습니다. 클라우드 Lock-In을 피하기 위해서, 하나의 클라우드 대신에 여러 클라우드 리소스 풀을 사용할 수 있도록 아키텍처를 디자인해야 합니다. 유사하게, 내/외부 데이터 센터에 호스팅된 다른 서버들과 클라우드 내의 웹서버가 통신하도록 하이브리드 클라우드 아키텍처로 디자인할 수 있습니다.

Scalable MultiCloud Architecture

아래의 샘플을 보면, 웹사이트, 어플리케이션을 위해서 하나의 클라우드 인프라 스트럭처를 이용할 수 있습니다. 그러나, 다른 클라우드 인프라스트럭처의 어플리케이션 티어의 Auto Scaling을 위해서 서버들을 셋팅할 수도 있습니다. 예를 들어, 퍼블릭 클라우드 인프라스트럭처에서 서버를 구동함으로써, 비용을 발생하기 전에, 개인적인 클라우드 서버를 사용할 수 있습니다. 아래의 멀티클라우드 아키텍처 다이어그램은  어플리케이션을 개인 클라우드 인프라스트럭처에 호스팅하고, 필요하면 추가적인 서버 용량을 위해 퍼블릭 클라우드로 Auto Scale 하는 것을 보여주고 있습니다.

diag-System_Architecture-9.png

Failover MultiCloud Architecture

아래의 샘플 다이어그램에서 같은 ServerTemplate과 스크립트들은 Cloud X, Y에 상관없이 설정과 서버 시작에 사용되어 집니다. 멀티 클라우드에서  동작하는 클라우드 시스템 아키텍처를 디자인하고 있다면, 알아야할 몇 가지 고려사항이 있습니다. 아래의 다이어그램에서 Slave-DB 서버는 “Warm Backup” 상태로 동작하고 있습니다. 그래서 마스터 DB와의 리플리케이션은 Private IP가 아니라 공인 IP를 이용하고 있습니다. 오직 같은 클라우드 인프라스트럭처 내에서만 private IP로 통신할 수 있습니다. 그러나, 장애나 다른 문제로 인해서 클라우들를 변경해야 할 때, 멀티 클라우드 아키텍처는 쉽게 웹사이트나 어플리케이션을 이전하는 것을 도와줍니다. 레퍼런스 아키텍처에서 다른 티어들은 이미 설정이 되어 있고, Cloud X에서 Y로 실 서비스를 옮겨야 할 필요가 있을 경우 쉽게 시작할 준비가 되어 있습니다. public/private 클라우드의 어떠한 조합이라도, RightScale 계정안에서 가능하다는 것을 기억하는 것은 중요합니다.

diag-System_Architecture-8.png

다른 두 클라우드 서버간에 안전한 방법을 통해서 데이터를 전송/수신하기를 원한다면, 다른 두 클라우드 인프라스트럭처 사이에 전송되는 공인 IP로 전송되는 모든 데이터들에, 데이터 암호화나  VPN 을 사용할 수 있습니다.(각각 클라우드 내부는 제외하고), 아래의 다이어그램에서, 데이터 복제는 안전한 VPN 터널을 이용해서 다른 두 클라우드 서버들 간에 퍼블릭 인터넷을 거쳐서 이루어지고 있습니다.

diag-System_Architecture-10.png

MultiCloud Disaster Recovery Architecture

RightScale 관리 플랫폼의 주요 장점 중에 하나는 자동적으로 멀티 클라우드 장애 복구 솔루션을 ServerTemplate들을 이용해서 좋은 사례를 따라함으로써 간단히 사용할 수 있다는 것입니다. 어떤 클라우드도 장애에 검증되지 않았습니다. 서버와 서비스들은 갑자기 다운되므로, 다양한 장애 복구 시나리오를 다룰 수 있도록 시스템 아키텍처가 구축되어 있는것은 중요합니다. 예를 들어, 현재 배포된 실 서비스가 돌고 있는 클라우드가 용량 부족이 갑자기 발생한다면 무슨 일이 벌어질까요? 전통적인 서버 호스팅 모델에서는 호스팅 업체가 문제를 해결해 줄 때 까지 기다리고, 동작 가능하도록 서버 상태를 되돌리는 방법밖에 없었습니다. 그러나 클라우드에서는 웹사이트가 적절히 설계되어 있다면, 즉시 반응할 수 있고, 스스로 웹사이트를 복구할 수 있습니다.   예를 들어서, RightScale의 ServerTemplate들을 사용해서, 실 서비스를 배포했다면, 다른 여러 클라우드에도 같은 ServerTemplate을 이용해서 같은 서버들을 배포할 수 있습니다.  그래서 클라우드에서 서비스가 문제가 발생해도(예를 들어, AWS US-East), 다른 클라우드나 Region 에 바로 실서비스를 재구축 할 수 있습니다. 만약, ServerTemplate들 대신에, 현재 배포된 AWS Region에서 사용한 AMI를 사용한다면, 아래에 묘사된 상황에서는 장애를 복구하지 못할 것입니다.

 아래에 묘사된 다이어그램은 RightScale 관리 시스템을 통해서만  가능한 두 가지 장애 복구 솔루션을 보여줍니다.

  1.  해당 예제에서, 스냅샷은 기본적으로 일정 시간마다 백업되고 있습니다. 그러나 수동으로 데이터베이스의 LVM 백업을 해야 합니다. 그러므로 클라우드 장애시에 데이터베이스 이전을 수행해야 합니다. LVM bakcup을 이용해서 다른 클라우드나 Region에 데이터베이스 서버를 재 시작할 수 있습니다. 데이터베이스 서버가 LVM 백업으로 부터 동작하기 시작하면, 정기적으로 데이터베이스의 백업은 계속 될 것입니다. Note: 현재 다이어그램에서는 하나의 데이터베이스는 데이터베이스 스토리지를 위해서 하나의 볼륨만 이용하고 있는 것을 보여주고 있습니다. 로컬 서버에도 데이터를 저장할 수 있습니다.
  2. 해당 예제에서, LVM 백업은 다른 클라우드 스토리지에 저장됩니다.(e.g. RackSpace Cloud Files Contaner) 그리고 다른 클라우드에서 실해되는 데이터베이스 서버를 복구하는 데 사용됩니다.( e.g. Rackspace Cloud Servers) 데이터베이스 서버가 동작하면, 정기적으로 데이터베이스는 백업을 시작합니다.

Note: 현재 ServerTemplate은 이런 동작은 베타 서비스중입니다.

diag-System_Architecture-13.png

Cloud and Dedicated Hosting Architecture

하이브리드 클라우드 솔루션 아키텍처의 다른 형태는 public/private 클라우드 리소스를 내/외부의 데이터센터에 있는 자원들과 함께 사용하는 것입니다. 예를 들어서, 데이터베이스는 서버는 민감한 유저 정보와 중요한 데이터들을 가지고 있으므로, 물리적 위치에 엄청난 제약 조건이 있을 것입니다. 이런 경우에, 어플리케이션이나 웹 사이트의 다른 티어들은 같은 종류의 제약조건이 없을 때, 데이터 베이스는 클라우드 인프라스트럭처에 호스팅되지 않을 수 있습니다. RightScale 플랫폼을 이용해서 클라우드 서버와 호스팅된 서버 사이의 공인 IP 사이에 안전한 터널을 생성하는 VPN 솔루션을 이용한 하이브리드 시스템 아키텍처를  만들 수 있습니다.

diag-System_Architecture-11.png

[입 개발] Redis Swap, Redis는 메모리를 두배로 먹어요.

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

Redis 는 현재 가장 인기있는 오픈 소스 캐시 솔루션 중의 하나입니다. 수 많은 기업에서 Redis를 사용하고 있거나 사용할려고 합니다. 이렇게 Redis가 있는 이유가 무엇일까요? 무엇보다도 안정적이고 속도가 빨라서 그렇습니다. 그리고 이 빠른 속도를 보장해주는 가장 큰 부분은 Redis 메모리 기반 솔루션이라는 것입니다.

Redis는 Single Thread 기반의 어플리케이션입니다. 그런데, Single Thread 임에도 불구하고, 백그라운드 Snapshot을 만들 수 있는 기능을 제공합니다. 우와, 어떻게 이것이 가능할까요? 그러면서 데이터에 대한 변경도 가능합니다. 보통의 솔루션들이 Snapshot을 뜨는 시점에는 변경 사항을 만들지 않기 위해서 안전하게 freeze 시켜두는 것과 다르게 말입니다.

그렇다면 어떻게 이런 기능을 제공할까요? 예전에 한번 언급했듯이, “BGSAVE”를 통한 백그라운드 스냅샷 기능은 Redis 가 차일드 프로세스를 생성하고, 여기서 작업을 진행하게 됩니다.

 

그런데 여기서 문제가 발생할 수 있습니다. fork 가 되면 기본적으로 자식 프로세스는 부몬 프로세스의 메모리를 복사하게 됩니다. 산술적으로 Redis 가 2GB 의 메모리를 쓰고 있다면 자식 프로세스도 2GB를 사용하게 된다는 것이죠.  OS가 COW(Copy On Write) 라는 것을 지원해서 해당 페이지에 Write가 와야만 실제로 메모리를 할당하므로 그 때는 큰 문제가 없겠지만, Redis에 write가 많을 경우 최대 2배가 되는 문제가 발생할 수 있습니다.

 

 fork 하면 처음에 자식 프로세서는 부모 메모리 페이지를 그대로 사용하게 됩니다.

write 가 생길 수록 복사되는 페이지가 늘어납니다. 만약 전체 페이지에 모두 write 가 생기면 최대 2배의 메모리를 사용하게 됩니다.

 그러므로 만약 해당 장비에서 RDB를 통한 스냅샷을 남길 때에는 Write 가 빈번한 서버의 경우에 주의해야 성능 저하를 줄일 수 있습니다. 그래서 실제 스냅샷은 슬레이브에서 남기는 것을 추천드립니다.

 

[입 개발] Redis Automatic failover Solution – Redis Sentinel 소개

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

Redis Sentinel 은 Redis 개발자가 만든 자동 Automatic Failover Solution 입니다.  현재는 베타 Release 상태이나, 간단하게 테스트 한 결과로는 잘 동작하고 있습니다. 이 글을 작성하는 시점에 몇 가지 테스트를 더 해봐야 하는데, 일단은 간단하게 사용법 정도를 공유합니다.

특징

Sentinel은 다음과 같은 3가지 특성을 가집니다.

  • Monitoring : master나 slave 가 제대로 동작하는지 모니터링 합니다.
  • Notification : API를 제공해서 관리자가 장애 상황에 대해서 통보 받을 수 있도록 해줍니다.
  • Automatic FailOver: 마스터가 장애가 나면 Slave를 자동으로 새로운 마스터로 만들고 다른 Slave들이 해당 마스터를 사용하도록 설정합니다.

Sentinel은 분산 프로그램입니다. 그래서 장애 모니터링 자체의 장애를 받기 위해 여러 개의 서버를 동시에 실행할 수 있습니다. sentinel의 master 정보만 입력하면, 자체적으로 sentinel 과 redis 서버들의 정보를 확인할 수 있습니다. 재미난 것은 redis-sentinel 자체가 redis 소스를 그대로 이용한 거라, 거의 비슷한 구조로 동작합니다. 다만 기존 redis 명령이 먹지 않습니다.

코드

현재 sentinel 은 redis git trunk 에 이미 merge 되어 있습니다.


git clone https://github.com/antirez/redis.git

빌드

빌드도 간단합니다. mecached 가 libevent 의존이 있는 것과 다르게, redis는 외부 라이브러리 의존성이 없어서 그냥 make 만 하시면 빌드가 됩니다. 다만 unittest까지 전부 돌려보기 위해서는 TCL 을 설치하셔야 합니다.

실행

sentinel 은 두 가지 방법으로 실행할 수 있습니다. 빌드 결과물 중에 redis-sentinel을 사용하든지 기존 redis-server 에 –sentinel 옵션을 줘도 됩니다.


redis-sentinel sentinel.conf

redis-server sentinel.conf --sentinel

설정

기존 redis-server의 동작 자체는 바꿀 필요가 없고, 일단 sentinel 용 conf를 보도록 하겠습니다.


sentinel monitor resque 127.0.0.1 2001 1
sentinel down-after-milliseconds resque 3000
sentinel failover-timeout resque 900000
sentinel can-failover resque yes
sentinel parallel-syncs resque 1

기본적인 sentinel의 conf 구성은 다음과 같은 형태로 구성되어 있습니다.


sentinel <command> <command values>

일단 기본적으로 monitor 커맨드는 마스터 서버의 주소와 ip가 들어가게 됩니다. 그리고 down-after-miliseconds 는 해당 장비가 장애가 난 걸 인지하고 failover 를 결정할 때 걸리는 시간을 지정해주는 것입니다. can-failover 는 실제로 failover를 할 것인지에 대해서 결정합니다. yes일 때만 장애가 발생하면 failover가 시작됩니다. parallel-syncs는 최소 몇 대의 slave 가 새로운 마스터와 sync를 맞춰야 하는 가에 대한 내용인데, 아직 확실히 확인해보지는 못했습니다.

sentinel 를 추가하더라도 기존 시스템 자체에 변경이 필요하지 않고 sentinel 만 설정해주면 됩니다.  sentinel 은 기본적으로 26379 포트를 이용하는데, redis 의 설정 처럼 port 정보를 주면 원하는 포트로 실행이 됩니다.

여러 대의 sentinel 을 이용할 때 sentinel monitor resque 127.0.0.1 2001 1 에서 마지막 1의 값이 몇 대의 sentinel로 부터 마스터 장애를 통보 받아야 실제로 failover를 할 것인지에 대한 설정 값이다. 만약 해당 값을 실제 sentinel 서버 수 보다 늘리면, failover가 영원히 동작하지 않습니다.

시나리오

sentinel의 시나리오는 다음과 같습니다. Sentinel의 monitor에 master의 정보를 주면 자동으로 slave 는 감지하게 됩니다.

그리고 Master가 장애가 나면 Sentinel 이 감지하게 됩니다.

그리고 Sentinel 이 하나의 slave를 정해서 slave를 master로 변경합니다. 그리고 타 슬레이브 노드의 마스터를 신규 마스터로 설정합니다.

SDown(Subjectively down) 과 ODown(Objectively down)

Sentinel 은 서버의 상태를 SDown 과 ODown 이라는 형태로 구분합니다. SDown은 한 대의 sentinel 이 해당 장비가 장애가 났다라고 판단하는 것인데, 이것으로만은 Failover를 하지 않습니다. ODown 상태가 되어야만 Failover를 하게 되는데, 최초에 장애가 났다는 것이 SDown 그리고 다른 sentinel 에서 과반 수 이상이 해당 장비가 장애난게 맞다라고 답변을 주면 ODown이 되어서 실제로 Failover가 시작됩니다.( 보통 이런 경우는 Brain Split, 네트웍으로 인해서 특정 sentinel이 해당 서버가 장애났다고 인식해서 갑자기 failover 하는 것을 막기 위한 방법입니다. ) SDown은 정기적으로 PING 명령을 사용해서 체크하게 됩니다.

무엇보다 알아야 할 부분은?

사실 가장 중요한 부분이 여기 있습니다. 여기까지 보셨으면 질문이 하나 생길 것입니다. 그리고 그 질문에 대한 대답이 나오지 않으면 쓸 수 없을지도 모릅니다. Sentinel 은 “마스터” 가 장애가 나면 슬레이브 중에 한대를 골라서 “새로운 마스터”로 승격시켜주고, 다른 슬레이브들은 해당 마스터를 바라 보도록 합니다. 그렇다면, 어떤 슬레이브가 선택이 되고, 클라이언트 입장에서 해당 FailOver의 발생과 새로운 마스터 서버의 정보를 얻을 수 있을까요?

  •  새로운 마스터 정보의 획득: 해당 정보는 redis-sentinel 역시 redis와 마찬가지라 command를 통해서 얻을 수 있습니다. SENTINEL get-master-addr-by-name <master name>을 이용하면 됩니다. 해당 master name은 montior 로 설정했던 그 이름입니다.
</pre>
redis 127.0.0.1:2003> SENTINEL get-master-addr-by-name resque
1) "127.0.0.1"
2) "2002"
<pre>
  • 그리고 이런 변경에 대한 이벤트는 sentinel 에 대해서 psubscribe 를 통해서 통보 받을 수 있습니다.
</pre>
charsyam@ubuntu:~/projects/redis$ src/redis-cli -p 2003
redis 127.0.0.1:2003> psubscribe *
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "*"
3) (integer) 1
1) "pmessage"
2) "*"
3) "+sdown"
4) "master resque 127.0.0.1 1999"
1) "pmessage"
2) "*"
3) "+odown"
4) "master resque 127.0.0.1 1999 #quorum 1/1"
1) "pmessage"
2) "*"
3) "failover-detected"
4) "master resque 127.0.0.1 1999"
1) "pmessage"
2) "*"
3) "+failover-end"
4) "master resque 127.0.0.1 1999"
1) "pmessage"
2) "*"
3) "+switch-master"
4) "resque 127.0.0.1 1999 127.0.0.1 2002"
1) "pmessage"
2) "*"
3) "+sentinel"
4) "sentinel 127.0.0.1:2004 127.0.0.1 2004 @ resque 127.0.0.1 2002"

주의할 점

아직 sentinel의 경우 beta release 입니다만, 꽤 안정적으로 보이지만, 주의해야 할 부분이 있습니다. 예를 들어서 현재까지는 기존 redis-server 들이 모두 재시작하게 되면 sentinel 서버들의 정보를 reset 해 주거나 재시작해야만, 다시 모니터링이 시작됩니다. 이걸 모르시고 적용하게 되면, 한번 모니터링 된 이후에는 안될 수도 있으니 주의해야 합니다.

[추가] 해당 이슈에 대해서는 베타라 아직 구현되지 않았다고 합니다.

[발 번역] Cassandra의 Read에 대하여

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

해당 포스트는 http://www.datastax.com/docs/1.1/dml/about_reads 을 발 번역한 것입니다. 얼마 전에 카산드라의 Write 에 대해서 올렸는데, Read는 양이 적어서 금방 할 수 있을 것 같아서, 같이 진행하였습니다. Oracle, MySQL등의 RDBMS는 사용자도 많고, 이에 대한 트러블 슈팅을 가진 사람들도 많습니다. NoSQL등의 경우는 그에 비해 사용자도 적고 문제를 공유할 사람들도 적은게 사실입니다. 다만, Oracle, MySQL에서도 내부 구조를 이해하면 개발 시에 편리하지만, NoSQL은 필수로 알아야만 잘 이용할 수 있습니다.

About Reads in Cassandra

하나의 노드에 속한 row 에 읽기 요청이 오면, 응답을 하기 위해서 해당 row는 해당 row에 속하는 컬럼을 포함한 노드에 속하는 모든 SSTable 로 부터 결과를 조합해야 하고, 모든 디스크로 flush 되지 않은 memtable 들로 부터, 정보를 조합해야 합니다. 이런 문제를 효율적으로 처리하기 위해서, 카산드라는 메모리 내에 Bloom filter 라는 것을 이용합니다. 각각의 SSTable은 다른 I/O가 일어나기 전에 요청된 row가 해당 SSTable 에 존재하는지 확인하기 위해서 Bloom Filter를 가지고 있습니다. 그 결과, 카산드라는 다른 스토리지 시스템에 비해서 매우 읽기 부하가 심할때를 포함해서 읽기 성능이 좋습니다.

 

다른 데이터베이스와 마찬가지로, 대부분의 요청 데이터가 메모리에 들어가 있으면 매우 빠릅니다. 자주 요청되는 데이터에 대한 빠른 접근을 위해서 모든 현대의 스토리지 시스템이 몇가지 형태의 캐시를 제공함에도 불구하고,  캐시 용량을 초과하면, 모든 시스템이 성능 저하를 겪게 되고, 디스크 I/O가 필요해집니다.  카산드라의 읽기 성능은 캐시 안에 있을 때 이점이 크지만, 랜덤 디스크 액서스가 필요한 상황에도 극단적으로 느려지지는 않습니다. 읽기 부하가 늘어나 카산드라 내부에 I/O 가 많아지기 시작하면, 클러스터에 새로운 노드를 추가하므로써 쉽게 해결할 수 있습니다.(역자 주: 카산드라 클러스터가 부하가 많은 상황에 서버를 한 번에 많이 추가하면, 해당 서버로 리플리케이션 해야되는 데이터를 가진 서버들의 부하가 함께 늘어나므로, 카산드라는 서버를 한번에 적게 추가하는 것이 좋습니다. )

 

row가 빈번하게 요청되는 것을 위해, 카산드라는 내부적으로 key cache 를 만들어 두었습니다.( 추가적인 row 캐시 ).  캐싱 기능을 이용한 읽기 성능 최적화에 대한 좀 더 설명이 필요하면 Tuning Data Caches 를 보시기 바랍니다.(역자 주: 전체 SSTable을 뒤져야 하는 부담 때문에, 카산드라에서는 Row 캐시를 제공합니다. 다만 해당 기능은 기본적으로는 꺼져있습니다. )

 

카산드라에서 클라이언트의 읽기, 쓰기 요청이 어떻게 처리되는지 자세한 정보가 필요하면, 다음 About Client Requests in Cassandra 페이지를 보시기 바라니다.

[발 번역] Cassandra의 Write 에 관하여

해당 블로그는 KT UCloud의 지원을 받습니다.

최근 몇일 동안 갑자기 Cassandra의 Read/Write Path 에 대해서 궁금해져서 소스를 파게 되었는데, 그걸 정리하기 전에 공식 문서에 정리된 내용을 한번 더 정독하는게 좋을듯 해서 해당 글을 번역하게 되었습니다. 해당 글은 http://www.datastax.com/docs/1.1/dml/about_writes 발 번역한 것입니다. 오역에 주의하세요.

카산드라는 매우 빠르고, 고가용성을 가지는 쓰기에 최적화되어 있습니다. 관계형 데이테베이스는 일반적으로 최소한의 중복만 유지하기 위해서 테이블을 구조화합니다. 쿼리에 적합한 데이터를 제공하기 위해서, 정보는 여러 조각으로 나뉘어서 미리 정의된 여러 테이블에 저장되게 됩니다. 관계형 데이터베이스의 데이터 구조 때문에, 데이터 쓰기는 여러 연관된 테이블들의 데이터 정합성을 보장하기 위해서 추가적인 작업을 하는 만큼 느립니다. 그 결과, 관계형 데이터베이스는 일반적으로 쓰기가 빠르지 않습니다.

반대로, 카산드라는 쓰기 성능에 최적화 되어 있습니다. 카산드라의 쓰기는 처음에 Commit Log 에 쓰여집니다.(데이터 안전성을 위해서), 그리고, memtable이라고 부르는 메모리 내 테이블 구조에 저장합니다. 쓰기는 Commit Log와 메모리에 쓰여지면 성공하게 됩니다. 그래서, 최소한의 Disk I/O만 쓰기시에 발생합니다.( 역자 주: Commit Log를 쓰는 것도 설정할 수 있습니다. )  쓰기는 메모리내에서 배치작업형태로 , 주기적으로 SSTable(Sorted String Table) 로 만들어서 디스크에 저장합니다. Column family 마다  Memtable 과 SSTable 을 유지합니다.( 역자 주: ColumnFamilyStore 안에 Memtable 이 존재하고 Memtable은 ConcurrentSkipListMap 형태로 Key를 관리합니다. 실제로 flush 시에 SSTable은 Memtable의 데이터를 단순히 순회하면서, 출력하는 작업을 하게 됩니다. )  Memtable은 row key에 의해서 정렬되어서 저장되어 있고, SSTable 에 순차적으로 저장하게 됩니다.( 관계형 데이터베이스에서의 no random seeking )

SSTable 은 변경 이 불가능합니다.( flush가 되고 나면 다시 쓸 수 없습니다. ) 이것은 일반적으로 하나의 Row 가 여러개의 SSTable 파일들에 걸쳐서 저장된다는 것을 의미합니다. 읽을 때는, 요청이 들어왔을 때 하나의 Row는 반드시  디스크의 전체 SSTable 과, 아직 flush되지 않은 memtable 들에서 읽은 데이터를 결합해서 만들어지게 됩니다.(역자 주: HBase 도 그렇지만, 카산드라는 그 정도가 더더욱 심합니다. 최악의 경우에는 정말 극악의 읽기 속도가 예상되는 부분입니다.) 이런 문제를 보완하기 위해서, 카산드라는 Bloom filter 라고 부르는 메모리내 데이터 구조를 사용합니다. 각각의 SSTable은 Bloom Filter 와 연결되어 있고, row 키가 요청되었을 때, SSTable에 존재하는지를 디스크를 찾기 전에 Bloom Filter를 통해서 체크합니다.

카산드라에서 클라이언트의 요청을 어떻게 처리하는지에 대해서 자세히 알고 싶은 분은 About Client Requests in Cassandra 를 보시기 바랍니다.

Managing Stored Data

카산드라는 현재 column family들을 디스크에 저장할 때, 디렉토리와 파일명의 포맷을 다음과 같은 형태로 합니다.

/var/lib/cassandra/data/ks1/cf1/ks1-cf1-hc-1-Data.db

(역자 주: ks는 key space, cf 는 column family 입니다. ) 카산드라는 각각의 Column Family를 위한 디렉토리를 생성하고, 개발자나 관리자에게 다른 데이터 볼륨이나 물리 드라이브에 링크를 거는 것을 허용합니다. 이것은 매우 접근이 많은 Column Family들을 SSD 등의 더 좋은 퍼포먼스를 내는 장비에 옮기는 것이 가능하게 해주고, column family 에 따라서 스토리지 레이어에서 더 좋은 I/O 밸런스를 가지도록 스토리지 디바이스를 나눠주는게 가능해줍니다. ( 역자 주: 카산드라는 그냥 로컬 장비의 디스크의 파일을 이용하므로 이런 것이 가능합니다. )

bulk loading을 더 쉽게 하기 위해서 keyspace 이름이 SST 이름의 한 부분을 차지합니다. 더 이상 sstable 을 keyspace 이름으로 만들어진 디렉토리에 넣거나,  클러스터를 분리하기 위해서 새로운 sstable을 생성할 때 keyspace 에 대해서 고민할 없습니다

About Compaction

백그라운드에서, 카산드라는 정기적으로 SSTabe 들을 더 큰 SSTable로 합치는 작업을 진행하고 있고, 이를 Compaction 이라고 부릅니다. Compaction 은 조각난 row 들을 합쳐주고, tombstone 들을 제거하고,  주 인덱스와 보조 인덱스 들을 재구성합니다.(역자 주: SSTable이 immutable 하므로, 삭제는 tombstone이라고 해서, 해당 컬럼이 삭제되었다는 추가 정보를 넣어서 lazy delete 형태로 처리합니다. ) SSTable이 row key로 정렬되어있기 때문에, 머지 작업이 매우 효과적입니다.( Random I/O가 없으므로 ) 새로운 SSTable이 머지가 끝나서 만들어졌을 때, 원본 SSTable 들은 더 이상 쓰지 않는다고 표시되고, 나중에 JVM garbage collection(GC) 프로세스에 의해서 제거됩니다. 그러나, Compaction 을 하는 동안에는  disk 공간과 disk I/O를 일시적으로 많이 사용합니다.

Compaction 은 읽기 성능에 두 가지 형태로 영향을 미칩니다.(역자 주: 한 row 자체가 여러개로 나눠져서 들어갈 수 있으므로, 대충 어떤 얘기를 할지 생각해보시면 될듯 합니다.) compaction이 진행되는 동안에 일시적으로 disk I/O와 디스크 사용율이 증가합니다. 이로 인해서 cache에 있지 않은 데이터에 대한 read의 경우 read 성능이 영향을 받습니다. 그러나, compaction 가 완료된 후에는, cache에 없는 데이터라도 read 성능이 증가됩니다. read 요청을 처리하기 위해서 몇 개의 SSTable 파일만 체크하면 되기 때문입니다.

카산드라 1.0의 경우, Column family-size-tiered compaction 과 Leveed Compaction의 두 가지 다른  설정할 수 있는 compaction 전략이 있습니다. 해당 Compaction 전략에 대한설명은  Tuning Compaction 을 보시기 바랍니다

카산드라 1.1 부터 실제 서비스 환경에 부담을 주지 않고 다양한 compaction 전략을 테스트 할 수 있도록 옵션이 추가되었습니다. Testing Compaction and Compression 를 보시기 바랍니다. 게다가, Compaction을 멈출 수도 있습니다.

About Transactions and Concurrency Control

카산드라는 완전한 ACID-compliant 트랜잭션을 제공하지 않습니다. 관계형 DB에서 트랜잭션은 다음과 같습니다.

  • Atomic. 트랜잭션내의 모든 작업이 성공하거나 아니면 완전하게 롤백되어야 한다.
  • Consistent. 하나의 트랜잭션은 데이터베이스를 불일치하는 형태로 남겨두면 안된다.
  • Isolated. 트랜잭션이 다른 트랜잭션에 영향을 주면 안된다.
  • Durable. 서버 장애나 다른 종류의 문제에도 완료된 트랙잭션은 문제가 없어야 한다.

비관계형 데이터베이스처럼, 카산드라는 join이나 foreign key 를 제공하지 않고, 당연히 ACID 의 consistency도 제공하지 않습니다. 예를 들어서, 계정 A에서 계정 B로 돈을 옮긴다면, 전체 어카운트의 돈은 바뀌지 않습니다. 카산드라는 atomicity 와 isolation은 row 수준에서만 제공합니다. 트랜잭션 isolation 과  atomicity 를 높은 가용성과 빠른 쓰기를 위해서 포기했습니다. 카산드라의 Write는 durable 합니다.

Atomicity in Cassandra

카산드라에서 row 단위에서는 쓰기가 atomic 합니다. 즉 하나의 주어진 row에 대한 insert나 update는 하나의 쓰기 작업으로 다루어집니다. 카산드라는 여러개의 row 사이에 발생하는 update에 대해서는 트랜잭션을 제공하지 않습니다.( 역자 주: all or nothing, 다 되거나, 아예 안되거나 하는 transaction의 특성을 제공하지 못합니다. ) 하나의 리플리카에 성공적으로 썼을 때는 롤백을 하지만, 다른 리플리카에 대해서는 실패하게 됩니다. 카산드라에서는 클라이언트에 쓰기 실패에 대해서 보고하지만, 실제로 하나의 리플리카에 데이터가 남아있을 수 있습니다.

예를 들어서, 복제 개수가 3으로 설정된 상황에서 QUORUM 을 일관성 레벨로 설정해서 쓰기를 하게 되면, 카산드라는 2개의 리플리카에 쓰기를 요청할 것입니다. 만약에 하나의 리플리카에 쓰기가 실패하고 다른 한곳에는 성공하면, 카산드라는 쓰기 실패를 클라이언트에게 알려줄 것입니다. 하지만, 다른 리플리카에서 자동적으로 롤백되지는 않습니다.

카산드라는 timestamp를 컬럼에 최신 데이터를 판단하기 위해서 사용하는데, 해당 timestamp는 클라이언트 어플리케이션에서 제공한 것입니다. 하나의 row에 대해서 동시에 여러 개의 클라이언트들이 업데이트를 요청하면 가장 최신의 timestamp를 가진 요청이 항상 적용될 것입니다. 가장 최근의 업데이트가 결국 디스크에 저장되게 됩니다.( 역자 주: 결국 이런 상황이면 만약에 데이터 읽기를 ONE으로 이용해서 사용하면 실패한 결과를 읽을 수 도 있다라는 뜻이됩니다.  만약에 읽기도 QUORUM이라면 읽는 시점에, 값이 다른 하나는 보정되게 될 것입니다. )

Tunable Consistency in Cassandra

여러개의 row나 column family들에 대해서 동시에 업데이트가 발생할 때 적용할 수 있는 Lock이나 트랜잭션 전략이 카산드라에는 없습니다. 카산드라에서는 가용성과 일관성 사이를 설정할 수 있는 기능을 제공합니다.(tuning between availability and consistency) 그리고 항상 Partition tolerance 기능을 제공합니다. 카산드라는 분산 데이터베이스 클러스터내에서 모든 노드들이 CAP 이론에서 말하는 Strong Consistency를 주도록 설정할 수 있습니다. 유저는 하나의 오퍼레이션에 얼마나 많은 노드들이 DML 명령이나 SELECT query에 응답하도록 설정할 수 있습니다

Isolation in Cassandra

Cassandra 1.1 이전에는, 다른 유저가 같은 row를 읽는 동안에 다른 유저가 해당 row를 부분적으로 업데이트 하는 것이 가능했습니다. 만약 한 유저가 2000개의 컬럼과 하나의 row를 쓰고 있는 중에, 다른 유저가 해당 row 와 컬러중에 일부를 읽을 수 있습니다. 하지만, 전부는 아니지만 쓰기 작업은 계속 진행 중 일 수도 있습니다.

한 유저가 쓰기를 수행중에 다른 유저가 완료되기 전까지는 변경 중 내용을 볼 수 없게 하는 완벽한 row 단위의 isolation은 현재 적용중입니다.

전통적인 ACID((atomic, consistent, isolated, durable)) 관점에서, 해당 개선으로 카산드라는 트랙잭션의 AID를 지원하게 되었습니다. 쓰기 작업은 스토리지 엔진에서 row 단위로 분리되어 있습니다.

Durability in Cassandra

카산드라의 쓰기는 안전합니다. 복제 노드의 모든 쓰기는 성공을 리턴하기 전에 메모리와 Commit Log 양쪽에 저장됩니다. 메모리 테이블을 디스크로 저장하기 전에 서버 장애나 뭔가 충돌이 생기면, 재 시작시에 Commit Log를 이용해서 잃어버린 테이터를 모두 복구합니다.

About Inserts and Updates

동시에 여러 개의 Column들이 insert 될 수 있습니다. Column이 하나의 Column Family에 insert나 update 될 때, 클라이언트 애플리케이션은 어떤 Column의 내용을 업데이트 할 것인지 row key를 통해서 확인하게 됩니다. Row Key는 하나의 Column Family 내에서 각각의 row를 유일하게 구분해주는 primary key와 유사합니다. 그러나 primary key와는 다르게, 중복된 row key를 통한 insert는 primary key 중복 제한 위반이 발생하지 않습니다. 그 때는 UPSERT( 데이터가 없으면 insert, 데이터가 있으면 update로 동작하는 ) 로 다뤄집니다.

 

컬럼은 오직 현재 존재하는 버전보다 최신의 새 버전의 timestamp를 가질 때만 update 됩니다. 그래서 만약 update가 자주 발생한다면, 정확한 timestamp 가 필요합니다.  timestamp는 클라이언트에게서 전달받기 때문에, 모든클라이언트 장비는 NTP(network time protocol)를 통해서 동기화 시켜야 합니다.

 

About Deletes

카산드라에서 Row 나 Column 을 지울 때, 관계형 데이터베이스 일어나는 동작과 비교해서 다른 부분이 몇가지 있습니다.

When deleting a row or a column in Cassandra, there are a few things to be aware of that may differ from what one would expect in a relational database.

  1. 삭제된 데이터는 즉시 디스크에서 지워지지 않는다. 카산드라에 들어가 있는 데이터는 디스크의 SSTable에 저장되어 있습니다. SSTable이 쓰여질 때, SSTable은 immutable(파일이 더 이상 DML 오페레이션으로 업데이트가 되지 않는) 상태입니다. 이것은 삭제된 Column이 바로 사라지는 것이 아니라, tombstone 이라고 불리는 삭제 마크가 새로운 Column 정보를 가리키게 됩니다. tombstone에 설정된 삭제된 컬럼은 설정에 기록된 시간동안 존재하게 됩니다.( Column Family 에 gc_grace_seconds 라고 설정되어 있습니다. ), 해당 시간이 지나면 compaction 과정에서 실제 디스크에서 삭제되게 됩니다.
  2. 정기적인 node 복원 작업이 동작하지 않으면삭제된 컬럼이 다시 나타날 수 있다. tombstone 에서 삭제된 컬럼을 마킹하는 것은 replica가 다운되었더라도 나중에 해당 시간동안의 삭제 정보를 노드가 복구되었을 때 삭제 정보를 다시 받을 수 있는 것을 보장합니다. 하지만, 해당 노드가 tombstone 정보를 저장하는 시간보다 오래 다운되어 있다면( ColumnFamily의 gc_grace_seconds  에 정의되어 있습니다. ) 삭제 했다는정보를 전부 잃어버릴 수도 있습니다. 그리고 삭제된 데이터가 노드가 복구되면서 삭제되었던 정보가 다시 복제되어서 데이터가 다시 나타날 수 있습니다. 지워진 데이터가 다시 살아나는 현상을 방지하기 위해서, 관리자는 반드시 , 크러스터의 모든 클러스터의 노드에 정기적으로 복원작업을 해주어야 합니다.(기본적으로 10일마다 한번씩)
  3. 삭제된 row key는 range query 에서 여전히 나타날 수 있다. 카산드라에서 row를 하나 삭제했을 때, 해당 row key를 위한 모든 컬럼이 compaction에 의해서 해당 tombstone들이 삭제될 때 까지 tombstone 에 표시됩니다. 만약 row key에 어떤 컬럼도 없는 빈 row key를 가지고 있다면, 이 삭제된 key들은 get_range_slices()의 결과로 보여질 수 있습니다. 클라이언트 어플리케이션이 해당 row들에 range queries를 수행한다면, 반환되는 빈 컬럼 리스트에 대해서 필터링을 수행해야 할 수 있습니다.

About Hinted Handoff Writes

Hinted handoff 는 카산드라의 장애난 서버가 클러스터로 돌아옸을 때, consistency를 맞추기 위한 시간을 줄이기 위한 추가적인 기능입니다. (역자 주: Hinted handoff 는 카산드라의 모든 노드가 coordinator 가 되고, 이 때, 요청이 간 서버가 다운되서 정보를 저장하지 못하면, 해당 서버가 대신 정보를 저장하고 있다가 실제 서버가 복구되었을 때, 이를 알려주는 기능입니다. ) 또, 클라이언트가 쓰기 실패는 허용하지 않지만, 읽기의 불일치는 허용할 수 있을 때, 쓰기 가용성을 높이기 위해서도 사용됩니다.( 역자 주: 꼭 그렇다는 건 아니지만, SNS 류의 데이터의 경우, 잠시 쓰인 것이 읽히지 않더라도 문제 되지 않는 상황이 있을 수 있습니다. 내 트위터나 페이스북 내용이 보는 사람들마다 조금 다르다고 해서 무슨 문제가 있겠습니까? 쿨럭.. )

 

쓰기가 실행될 때, 카산드라는 영향 받는 row key를 가진 모든 리플리카에서 쓰기를 시도합니다. 쓰기가 일어난 시점에 하나의 리플리카가 다운된걸로 확인되면, 응답을 할 살아있는 리플리카가 Hint를 저장합니다. 해당 hint 는 해당 데이터의 위치 정보 뿐만 아니라( 복제해야할 노드와 복제해야할 row key ), 실제로 쓰여질 데이터도 포함됩니다. 리플리카에 hint를 저장하는데는 이미 자신에게 써야할 데이터를 쓰는 동안  쓰기 과정을 통해서 hint에 써야할 데이터들이 분석되어서 최소한의 오버헤드만 발생합니다.(역자 주: 해당 케이스는 리플리카가 3인데 하나가 죽어서 같은 키를 저장하는 리플리카에 hint가 저장되는 케이스입니다. )

 

만약 해당 row key를 저장해야하는 모든 리플리카가 다운도면, write consistency level 를 ANY로 선택함으로써, 쓰기에 성공하는 것이 가능합니다. 해당 시나리오에서는, 해당 hint 와 data 들이 coordinator 노드에 저장됩니다. 그러나 실제 리플리카에 해당 정보가 쓰여지기 전까지는 읽기는 이용할 수 없습니다. ANY consistency level 은 데이터를 쓴 후에 언제 읽을 수 있다는 것을 보장하지 않기 때문에 완벽한 쓰기 가용성을 제공합니다. ( 물론 얼마나 오랜 시간동안 리플리카가 다운되어 있는지에 달려있습니다.) ANY consistency level  을 이용하는 것은 coordinator 노드가 쓰기를 받아들일 리플리카가 없는 경우, 추가적인 row 정보를 저장해야 해서, 잠재적으로 클러스터의 부하를 높입니다.

 

Note

기본적으로 hint는 한 시간 동안만 저장됩니다. 만약 쓰기를 할 때, 모든 리플리카가 다운되어 있고, 모든 리플리카가 max_hint_window_in_ms 에 설정된 시간보다 길게 장애가 유지되면, ANY Consistency Level을 이용하더라도 잠재적으로 데이터를 잃어버릴 수 있습니다.

Hinted handoff는 ANY Consistent Level 이외에는 동작하지 않습니다. 예를 들어서 ONE Consitency Level 을 이용하면 쓰기시에 모든 리플리카가 다운되었을 때, 해당 쓰기는 hint를 저장했든 아니든, 실패로 처리됩니다.

하나의 hint를 저장하고 있는 리플리카가 gossip 프로토콜로 장애난 녿가 복구 된것을 알게 되면,  해당 리플리카가 따라잡아야 하는 놓친 쓰기들을 보내기 시작할 것입니다.

 

Note

Hinted handoff 는 정기적인 node 복구 작업을 수행하는 것을 대체하기에는 완전하지 않습니다.

[발 번역] 아마존 클라우드에서의 Auto Scaling

해당 블로그는 KT UCloud 의 지원을 받고 있습니다.

해당 포스트는 http://techblog.netflix.com/2012/01/auto-scaling-in-amazon-cloud.html 의 글을 발 번역한 것입니다. 최근에 계속 Netflix 관련 글을 번역하게 되는데, Netflix는 2010년 경, 데이터 센터대신에 아마존 클라우드로 모든 인프라 스트럭처를 이전하였습니다. 그래서 이에 대한 기술력이 가장 높은 회사중에 하나가 아닐까 합니다. 글을 읽고 공개한 자료들을 보면, 정말 AWS에 대해서 엄청난 수준의 이해와 경험을 가지고 있는 것 같습니다. 오역에 주의하세요.

Auto Scaling in the Amazon Cloud

 2010년에 모든 인프라스트럭처를 클라우드를 옮겨가기 시작한 이후로, 운영하는 모든 서버풀을 관리하기 위해서 아마존 Auto Scaling Group을 사용해오고 있습니다. Auto Scaling Group 이 서비스의 가용성을 향상시키고, 클라우드 비용을 최적화 시켜주는 최고의 툴을 제공한다고 믿습니다. auto scaling 서비스를 이용한 2년 이상의 경험으로, 이미 경험에서 배운 몇가지 교훈들뿐만 아니라, 왜 이것을 사용해야 하고, 어떻게 사용하는지에 대해서 나누는 좋은 시간을 가질 수 있었습니다. Auto Scaling과 친숙하지 않은 분들을 위해서, Auto Scaling Group은 아마존에서 자신의 클라우드 기능의 일부로 제공하는 자동화서비스입니다. Auto Scaling은 비정상 서버를 교체하고, 서버 풀의 사이즈를 자동적으로 늘리거나, 줄이는 기능을 포함해서, 동작중인 서버 풀을 관리하는 기능을 제공합니다. 좀 더 많은 정보를 원하시면 Amazon Documentation 을 보시기 바랍니다.

Benefits

1. Availability

모든 서비스 환경에서 동작중인 서버는 하나의 Auto Scaling Group에 속해있어야 합니다. simian army   툴 중에 하나를 이용해서 해당 환경에서 비정상 서버의 위치를 찾아내고 종료시키는 것을 검증했습니다. 목표는 비정상 노드를 최대한 빨리 발견하고 종료시키는 것입니다.  아마존에 의해서 자동적으로 교체될 것이라고 기대할 수 있습니다. 이것은 또한 어떤 서버든지 아마존에 의해서나 하드웨어 장애로 인해서 종료될 때도 적용할 수 있습니다. stateful 과 stateless, 두 가지 서비스 모두를 위해서도 동작합니다. stateful 서비스 또한 AMI가 실행될 때, 어떻게 필요한 모든 것들을 셋업할 것인지 알고 있습니다.  게다가  대부분의 서비스는 stateless 이고 해당 작업은 최적화 된 auto scaling을 사용하기 위한 정보를 제공하고 다룸으로써  매우 쉽습니다.

2. Optimization

Availability에서 가장 중요한 것은 auto scaling의 사용입니다. 비용과 리소스의 최적화는 확실히 더 매력적입니다. 필요에 의해서 리소스의 할당이 가능하게 되고 거기에 따라 비용을 지불하게 되는 것은 클라우드의 큰 이점 중의 하나입니다.매우 적은 어플리케이션만 일정한 워크로드를 가지고, Netflix 역시 예외는 아닙니다. 사실, 사용자 패턴에 따라서 피크타임에 매우 큰 사용량의 변화가 있습니다. Auto Scaling은 리소스 풀 사이즈를 사용량에 따라서 다양하게 설정하게 해주어서 비용을 아끼고,  처리 용량을 수동으로 설정할 필요도 없고, 처리 용량을 넘어가는 문제가 없어서, 예측하지 못한 문제에 쉽게 대체할 수 있습니다.

3. Making it Work

Auto Scaling을 설정하는 것은 복잡한 일입니다. 간단하게 말하면, Auto Scaling은 크게 세 가지 단계로 구성되어 있습니다. 첫번째로, 제약이 있는 자원들( 예, 메모리, CPU ) 등을 분류하는 것입니다.  두번째로  아마존의 리소스 모니터링 서비스인, CloudWatch 를 이용해서 제약이 있는 자원들을 모니터하도록 합니다. 마지막으로 자원에 변경이 있을 때에 연관된 프로파일과 어떤 행동을 할지에 대한 동작과 알람을 설정합니다. AWS에서 제공하는 사용할 수 있는 메트릭은 특별히 모든 어플리케이션 종류에 대해서 중요한 지표로 여길수는 없는 CPU 사용율뿐입니다. 해당 프로세스를 쉽게 할 수 있도록 몇가지 스크립트와 두 단계의 툴을 개발했습니다.

첫 번째 단계의 툴은 인프라스트럭처를 모니터링하고 모니터링을 위한 정보 메트릭스를 CloudWatch로 보내기 위한 익스포팅을 해주는 모니터링 라이브러리입니다. 개발자들이 익스포트하기 쉽도록 어노테이션을 제공합니다. “@Monitor” 태그와 연관된었다고 어노테이션 된 필드가 있으면, 해당 필드는 자동적으로 JMX에 등록이 되고, 설정 가능한 필터를 통해서 CloudWatch에 전달됩니다. 몇가지 기능들이 있지만, 중요한 스텝은, Auto scaling 설정을 위한 필드를 익스포트 하기 위한 태그를 하는 것입니다.  Netflix Open Source 에서 해당 라이브러리에 대한 차후의 블로그를 찾아보시기 바랍니다.(역자 주: 다음 블로그를 보시면 해당 정보를 볼 수 있습니다. http://techblog.netflix.com/2012/07/open-source-at-netflix-by-ruslan.html )

두 번째 단계의 툴은 Netflix Application console(slides).에 통합될 기능들입니다. 전체 클라우드 인프라스트럭처를 관리할 수 있는 툴이지만, 여기서는 Auto Scailing을 쉽게 하기 위해 추가한 기능들에 대해서만 초점을 맞추도록 하겠습니다. push 프로세서의 부분으로써, 새로운 버전의 코드를 위한 auto scaling group을 새로 만들었습니다. 이것은 전체 설정을 이전 그룹에서 새 그룹으로 복사되었는지 확인할 필요가 있다는 것을 의미합니다. 해당 툴은 허가 받은 사용자가 간단한 HTML UI를 통해서 규칙을 변경하거나 볼 수 있도록 해줍니다. 게다가, 몇가지 Auto Scaling Rule 들 설정을 도와주는 간단한 샘플 스크립트를 가지고 있습니다. SNS Notification을 설정하고, roll-back 옵션을 만들고, 해당 스크립트는 다음 사이트에서 테스트가 가능합니다(github site).

마지막으로, 동적으로 Auto Scaling을 잘 하기 위한 가장 중요한 조각은 로드 속에서 프로그램의 동작을 테스트하고 이해하는 것입니다. 실제 트래픽에서 작은 규모의 서버군을 실제로 다운시켜보거나, 하나의 서버에 인공적으로 로드를 만들어서 해당 작업을 했습니다. 실제 부하 상황에서, 어플리케이션이 어떻게 동작하는지 이해하지 않거나, 실제 어플리케이션의 제약 조건이 뭔지 모르면,  비효율적이거나, 심지어 장애를 일으키는 Auto Scaling 설정을 할수도 있습니다.

The End Result

아래의 그래프들은 2틀 동안의 요청 트래픽을 보여줍니다. 서버 풀에서 CPU 사용량과 트래픽에 맞추어서 적절한 수의 서버가 동작하고 있습니다. 서버 대수가 요청 비율과 CPU 사용 부하에 있어서 거의 평행한 것을 볼 수 있습니다.(역자 주: 첫번째 그림은 Request Rate, 두 번째는 서버 대수, 세 번째는 CPU 로드입니다.)

Lessons learned

Scale up early, scale down slowly

Netflix에서는 Scale Up은 빨리하고 Scale Down은 천천히 하는 것을 권장합니다. 우리는 팀에서 Auto Scaling 정책과 CloudWatch 알람을 이용해 symmetric percentages 과  symmetric  periods 적극 이용하는 것을 적극 옹호합니다. 더 자세한 것은 여기에 있습니다. (역자 주: 원래 Scale up은 장비를 좀 더 좋은 장비로 바꾸는 것인데, 여기서의 Scale up은 말 그대로 장비를 추가하는 것을 의미합니다. 일반적으로 Scale Out이 이 의미에 맞습니다. github에 연결된 wiki 자료를 꼭 보시기 바랍니다. “여기” 로 표시한 부분에 있습니다.)

Scale up을 빨리하기 위해서 임계점의 75% 정도에서 짧은 시간동안 CloudWatch 알람을 설정하기를 권장합니다. 5~10분 정도 지속되면 해당 이벤트를 시작하기를 권장합니다. 새로운 노드가 시작하는데 EC2 인스턴스의 시작시간이나, 어플리케이션이 시작하는 시간이 필요하다는 것을 기억하기 바랍니다. 해당 25%의 틈이, 짧고 불규칙한 한계를 벋어나는 요청의 증가나 새로운 노드가 시작하는 도중에 실패하는 것을 인한 처리 용량의 손실로 부터 보호해줍니다. 예를 들어, 최대 CPU 사용량이 80%라면, 해당 알람은 CPU 사용량이 60%를 넘은 5분 후에 발생하도록 설정하는 것입니다.

Scale down을 천천히 하는 것은 너무 빨리 처리 용량이 줄어드는 위험을 완화시키거나, 잘못된 처리 용량의 감소의 위험을 줄여주므로 중요합니다. 이런 경우를 방지하기 위해서,  스케일을 천천히 하기 위한 방법으로 시간을 사용합니다. 예를 들어, CPU 사용량이 60%를 5분 동안 넘으면 바로 10% 확장하지만,  CPU 사용량이 30% 정도로 20분 이상 지속되어야만 10%를 줄입니다. 시간을 이용하는 장점은, 비 대칭적인 확장 정책을 적용하게 됨으로써, 서버의 용량이 부족한 상황이나, 너무 많은 처리 용량을 제거하고 바로 다시 서버가 추가되어야 하는 상황을 막아줍니다.(역자 주: 예를 들어 조건에 맞아서 계속 서버를 추가하고 제거하는 상황이 벌어질 수 있습니다.) 이런 현상은 Scale Down에 대한 정책을 너무 공격적으로 잡았을 때 발생할 수 있습니다. 시간 기반 확장 정책은 계획되지 않았던, 서비스 장애시에, 잘못 스케일을 축소하는 것을 막아줍니다. 예를 들어, 서비스가 잠시 다운되었다고 가정하면, 해당 시점에 해당 서버와 연관된 요청이 장애로 인해서 줄어들 수 있습니다. 이 때, 미들 티어에서 잘못 scale down 할 수 있습니다. 장애난 서버가 설정된 시간보다 적게 장애가 난다면, scale down 이벤트는 발생하지 않을 것입니다.

 

Provision for availability zone capacity

Auto Scaling 정책은 해당 Availability zone에서 필요한 용량에 기초해서 결정되어야 합니다. 퍼센트 기반 스케일링 정책을 활용해서 여러 availability zone 으로 Auto Scaling Group을 구성하는 것은 매우 중요합니다. 예를 들어서, 서비스를 세개의 존에서 각각 최소 10개 최대 30개의 리퀘스트를 처리할 수 있도록 설정을 했다면,  해당 서비스는 최대 초당 110 요청의 부하(RPS: Requests Per Second)로 한대의 ELB, 그리고 각 존마다 균등하게 라운드 로빈으로 요청을 보내서 테스트되어야 합니다.  효과적으로, 각 zone은 전체의 1/3 정도의 트래픽을 충분히 처리할 능력을 공급해야 합니다. 퍼센트 기반 스케일링 정책 아래서 하나 이상의 zone 이 추가로 제공될 수 있습니다. 전체가 1850 RPS 라고 가정하면, zone 마다 617 RPS 가 전달됩니다. 2개의 Zone이 6대의 장비가 있고, 마지막 Zone이 5대의 장비를 가진다면, 총 17대의 장비가 있습니다. 그리고 6대를 가진 Zone은 평균적으로 서버마다 103 RPS를 처리한다고 하면, 로드 테스트에서 바라는 것보다 13% 정도 더 처리가 가능합니다. 문제의 원인은 균형이 맞지 않은 Availability Zone에 있습니다. Scale Up/Down 을 함으로써, Zone안의 서버가  균형이 맞지 않을 수 있습니다.  이것이 퍼센트 기반 확장 정책을 이용할 때 발생하는 경향이 있습니다. CloudWatch 에 의해서 계산되고 집계되는 것은 간단합니다.  균등한 가중치, 평균, 제공된 Zone 에 대한 셋팅 정도입니다.

 

Conclusion

Auto Scaling 은 매우 강력한 툴이지만, “양날의 검” 도 될 수있습니다. 적절한 설정과 테스트 가 없으면, 유용하기 보다는 훨씬 위험합니다. 최적화를 시도하거나, 설정을 복잡하게 만들 때, 몇몇 안 좋은 케이스가 발생할 수 있습니다. 위에서 설명했듯이, 올바르고 조심스럽게 설정하면, Auto Scaling은 가용성은 늘려주고 전체적인 비용을 줄여줍니다. 좀 더 사용한 툴이나, 우리의 경험에 대해서 알고 싶으면 위키에 많은 문서 뿐만 아니라 사용하는 툴의 소스까지 포함한 auto scaling github project 를 방문하시기 바랍니다.

Greg Orzell

Justin Becker

[입 개발] 우분투 11.04 에 glusterfs 3.3.0 설치하기

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

갑자기 glusterfs 가 설치하고 싶어져서 KT UCloud 의 장비 3대에 glusterfs를 설치 했습니다. 위키피디아를 보면 glusterfs는 Scale-Out 가능한 NAS(Network Attached Storage) 파일 시스템입니다.  특징으로는 메타 정보 관리를 위한 Master Node가 따로 존재하지 않고, 모든 노드가 모든 정보를 관리합니다. 하둡과 카산드라를 생각해보면, 하둡은 마스터 노드가 모든 메타 정보를 관리해서 마스터 노드가 장애가 나면, 하둡의 기능이 정지합니다. 즉 마스터 노드가 SPOF(Single Point of Failure)가 됩니다. 그런데 glusterfs는 카산드라 처럼 모든 노드가 정보를 가지고 있어서(정확히는 카산드라는 키를 token으로 찾아낼 수 있는 거지만) 마스터 노드라는 개념이 없습니다.

설치한 장비는 우분투 11.04 장비이며, 설치 순서는 다음과 같습니다.  각 3대의 장비에 모두 실행해주어야 합니다.

거의 하단의 reference에서 참고하였습니다. 다만 reference를 보면 fstab 에 fuse 를 넣어라라고 되어있는데

먼저 glusterfs 는 nfs-common 에 의존성이 있고, nfs-common은 다시 libevent 에 의존성이 있으므로 설치를 해줘야 합니다.


sudo apt-get install libevent-dev

sudo apt-get install nfs-common

wget http://download.gluster.com/pub/gluster/glusterfs/3.3/3.3.0/Ubuntu/11.04/glusterfs_3.3.0-1_amd64.deb

sudo dpkg -i ./glusterfs_3.3.0-1_amd64.deb

그런 다음 /etc/hosts 파일에 설정을 위해서 각 노드로 사용될 서버를 지정해줍니다. ip는 각 장비에 맞도록 고쳐주시면 됩니다.


sudo vi /etc/hosts

#아래 부분을 /etc/hosts 에 추가

1.2.3.4 ucloud1
1.2.3.5 ucloud2
1.2.3.6 ucloud3

이제 glusterd를 기본 시작시 실행되도록 설정해 줍니다.


sudo update-rc.d glusterd defaults
sudo /etc/init.d/glusterd start

그리고 gluster 클러스터에 장비들을 추가합니다. 자기 자신을 추가 안해줘도 되지만 모두 추가합니다.


sudo gluster peer probe ucloud1
sudo gluster peer probe ucloud2
sudo gluster peer probe ucloud3

이제 replication 모드로 볼륨을 생성합니다.( 실제로 replication, strip 등으로 생성 가능합니다. )


sudo gluster volume create www-volume replica 3 transport tcp ucloud1:/exp1 ucloud2:/exp2 ucloud3:/exp3

이제 생성한 볼륨을 실행합니다.


sudo gluster volume start www-volume

실제로 해당 볼륨을 마운트할 디렉토리를 생성합니다. 그리고 마운트 합니다. 어느 장비껄 마운트 하셔도 상관 없습니다.


sudo mkdir -p /mnt/www-volume

sudo mount -t glusterfs -o log-level=WARNING,log-file=/var/log/gluster.log ucloud1:/www-volume /mnt/www-volume

이제 바로 사용하실 수 있습니다.  /mnt/www-volume 으로 가서 파일을 생성해보면 다른 서버에 즉각 반영되는 것을 볼 수 있습니다. 하지만 매번 재시작시에도 자동으로 마운트 하기 위해서는 fstab에 다음과 같이 추가가 필요합니다.


sudo vi /etc/fstab

#다음 내용을 추가

ucloud1:/www-volume /mnt/www-volume glusterfs defaults,_netdev,loglevel=WARNING,log-file=/var/log/gluster.log 0 0
ucloud2:/www-volume /mnt/www-volume glusterfs defaults,_netdev,loglevel=WARNING,log-file=/var/log/gluster.log 0 0
ucloud3:/www-volume /mnt/www-volume glusterfs defaults,_netdev,loglevel=WARNING,log-file=/var/log/gluster.log 0 0

그리고 /etc/modules 파일에 fuse 를 추가해줘야 합니다.(KT UCloud의 우분투 11.04는 해당 파일이 없고 추가하지 않아도 문제가 없었습니다. 아마도 커널에 아예 같이 컴파일 되지 않았을까 싶습니다. )


sudo vi /etc/modules

#아래 라인 추가

fuse

그리고 최종적으로 /etc/init.d/glusterd 파일을 수정해줘야 합니다. do_start() 를 다음과 같이 수정합니다. fstab의 것이 먼저 마운트를 시도하므로, 해당 데몬이 실행되기 전에 마운트를 시도해서 최초에 실패하기 때문에 데몬 구동 후에 강제로 다시 마운트를 시도하는 것입니다.

</pre>
do_start()
{
pidofproc -p $PIDFILE $DAEMON >/dev/null
status=$?
if [ $status -eq 0 ]; then
log_success_msg "glusterd service is already running with pid $PID"
else
log_daemon_msg "Starting glusterd service" "glusterd"
start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON -- -p $PIDFILE $GLUSTERD_OPTS
log_end_msg $?
start_daemon -p $PIDFILE $DAEMON -f $CONFIGFILE
#아래 줄을 추가
mount -a
return $?
fi
}
<pre>

이제 아무 서버에서 /mnt/www-volume 으로 가서 파일을 생성해보면 다른 서버에 바로 생성되거나 삭제되는 것을 볼 수 있습니다.
Reference: http://extremeshok.com/blog/clustering/ubuntu-11-04-server-3-node-glusterfs-3-2-2-replication/

[입 개발] Redis의 Replication은 Async 이다. Mysql의 Replication과 유사하다.

해당 블로그는 KT UCloud의 지원을 받고 있습니다.

Redis는 최근에 가장 이슈가 되는 NoSQL Cache 솔루션입니다 많은 사람들이 memcache와도 비교를 하는데, Redis의 경우에는 몇가지 이점이 더 있습니다. 그 중에 하나가 Replication 입니다. 그러나 실제로 이 Replication을 쓴다고 할 때도 그 내부 메커니즘이 어떻게 되는지 정확하게 이해해야만, 더 정확하게 사용할 수 있습니다

먼저, Redis 에서 Replication을 사용하는 방법은 아주 간단합니다. 슬레이브에서 conf에 마스터의 주소와 포트만 추가하면 됩니다.

slaveof <masterip> <masterport>

Redis는 마스터/슬레이브 리플레케이션만 지원하고, 마스터/마스터 리플리케이션은 지원하지 않습니다. 다만 계층형 리플리케이션은 지원합니다.

Redis는 성능을 위해서 Async 방식의 리플리케이션을 사용합니다. 만약에 Sync 방식을 이용한다면, 엄청나게 속도가 줄어들 것입니다.  그러나 그것 때문에 Redis를 사용할 때 Failover등을 걱정한다면, 좀 더 자세히 알아야 할 필요가 있습니다.

Redis에서 리플리케이션을 담당하는 부분의 소스 코드는 다음과 같습니다. 기본적으로 processCommand 라는 함수에서 처리가 되고 이것은 네트웍 이벤트 처리하는 부분에서 패킷이 완성되면 호출되게 됩니다. Redis는 text 프로토콜을 이용합니다. ae.c 파일의 284 라인의 aeProcessEvents에서 시작합니다. 실제 흐름은 다음과 같습니다.

그리고, Redis의 리플리케이션은 mysql과 유사합니다. mysql에서는 Async, Semi-Sync 라는 두 가지 방식의 리플리케이션을 제공합니다.

  • Async: 클라이언트에 성공을 리턴할 때, 리플리케이션에 대한 어떠한 동작도 보장해주지 않습니다.
  • Sync: 하나의 트랜잭션은 슬레이브 노드에도 모두 데이터가 제대로 적용이 되었을 때, 리턴하게 됩니다. 성능은 가장 떨어집니다.
  • Semi-Sync: 슬레이브 노드에 로그가 복사만 되면, 클라이언트에 리턴을 하는 방식입니다. 안전성은 Async 보다 높고, 속도는 Sync 보다 빠릅니다.

Async 와 Semi-Sync 방식을 비교해보면, Semi-Sync는 좀 더 데이터의 안전서을 제공합니다. 다만 Async 보다 느립니다.

다음은 Async 방식의 리플리케이션 흐름입니다.

다음은 Sync 방식의 리플리케이션 흐름입니다.

다음은 Semi-Sync 방식의 리플리케이션 흐름입니다.

Reference:

Follow

Get every new post delivered to your Inbox.

Join 28 other followers