CS 전공/리뷰2009.12.27 09:41
NoSQL Movement에 대한 기사를  읽어 내려가던 중에 다음과 같은 내용을 보았다.
(언제 기회가 되면 요새 MapReduce, Key-Value Store, NoSQL Movement 에 대한 내용을 싹 정리해서 글로 쓰고 싶다. survey paper를 내던, 블로깅을 하던.)

아무튼 기사를 보던 중에 이런 글귀가 눈에 띄었다.
 
예를 들어, 페이스북은 기존 데이터베이스인 MySQL이 아니라 카산드라(Cassandra) 데이터 스토어를 개발해 새로운 검색 기능을 추가했다. 페이스북 엔지니어인 아비나시 락시먼의 프리젠테이션에 따르면, 카산드라는 0.12ms 만에 50GB에 이르는 데이터 스토어를 디스크에 기록할 수 있는데, 이는 MySQL보다 2,500배 빠른 것이다."

우아~! 대단하다. 50GB를 0.12ms만에... 가만 그런데 이것이 가능한 일인가? 
도대체 어떤 기술을 썼길래... 갑자기 궁금해져서 NoSQL discussion에서 있었던 TP를 찾아 보았다. (http://static.last.fm/johan/nosql-20090611/cassandra_nosql.pdf)
  • MySQL > 50 GB Data
    Writes Average : ~300 ms
    Reads Average : ~350 ms

    •Cassandra > 50 GB Data
    Writes Average : 0.12 ms
    Reads Average : 15 ms

실제 위와 같이 써 놓았다. 0.12ms만에 50GBytes에 이르는 데이터를 디스크에 기록한다면,
1ms에 약 416GBytes (=50/0.12ms)를 디스크에 기록할 수 있다는 얘기이다. 
이게 말이 되는가? 이게 말이 된다면, 페이스북은 물리 법칙을 초월한 디스크를 가지고 운영되고 있다는 말이 된다 왜?

모든 디스크의 스펙을 보면 1)seek time, 2) rotational delay time, 3)transfer time이 나와 있다. 
1) seek time은 디스크 암을 움직여서 원하는 트랙으로 움직이는데 걸리는 시간이고,
2) rotational delay time(또는 latency)은 이 암이 트랙상에 위치한 임의 블럭 섹터를 만나는데 까지 걸리는 시간이고,
3) transfer time은 암이 실제 디스크로부터 데이터를 읽거나 쓰는데 걸리는 시간이다.
즉 데이터를 디스크에 기록하는데 있어 걸리는 시간은 1)+2)+3)이다.
그리고 이 중 2),3)은 모두 disk의 RPM에 의해 제한되는 물리적인 한계값을 가진다. 또한 1의 값은 디스크의 크기에 제한된다.(디스크 직경이 클수록 디스크 암이 움직이는 거리도 길어지며, seek time은 그만큼 늘어난다.)

RPM이 빠르면 빠를수록 delay time은 줄어들고 또한 그만큼 빨리 디스크로부터 블럭들을 쓰거나 읽을 수 있다. 하지만 현재 데이터 센터에서 이용되고 있는 디스크들이 갖는 가장 빠른 RPM은 15K이다.
RPM이 15K란 얘기는 디스크가 분당 15,000회 돈다는 얘기이다. 바꿔 말하면, 1회 회전하는데 60000/15000 =  4 ms가 걸린다는 의미이고, rotation delay는  평균 값으로 반바퀴 도는 시간을 재니 이의 절반인 2.0ms가 평균적으로 걸린다고 할 수 있다.  
실제 디스크의 스펙을 보면 더 명백해진다. Seagate의 Data center용 HDD인 Savvio '2.5Inch 15K의 스펙을  보자.
latency가 2ms이다. 

즉 ,어떠한 경우던지, 디스크에 데이터를 기록할 때에는 평균적으로 이 latency값이 먼저 먹고 들어가야 한다. 근데 Cassandra를 보면 seek time은 고사하고, 이 latency 값보다도 작은 값이 걸린다고 하고 있다.
물론 transfer time은 디스크를 병렬로 구성해서 병렬 I/O를 수행하는 식으로 개선할 수 있다. 
예를 들어 sequential write가 100MB/ms인 디스크 하나를 가지고 50GB를 저장하려면, 50*1,024/100= 512ms가 걸린다. 하지만, 50GB를 1000개로 쪼개어 1000개의 디스크에 병렬로 저장한다면 이상적으로 0.512ms가 걸리겠다. 하지만 이 때의 경우에도 각 디스크의 latency는 절대 피할 수가 없다. 결과적으로 평균적으로 걸리는 시간은 seek time + 2ms + 0.512ms이상이 나와야 물리 법칙을 깨지 않게 된다.

그러면, latency가 HDD에 비해 훨씬 낮은 최근의 SSD를 쓰는 경우는 어떠한가?  
요사이 SSD 중 성능이 우수하다는 Intel X25-E Gen2 160GB의 스펙을 보면, 
  • read/write latency가 각각 75/85um, 
  • Random 4K Read/Write는 35K/3.3K IOPS, 
  • Sequential Read/Write가 250/170MB/S
이다. SSD의 latency 85um은 0.12ms = 120us보다는 작다.  즉 SSD로는 0.12ms라는 writing time이 불가능한 것은 아니다. 
그런데, 이 값에서 latency를 제외한 transfer time만을 계산해보면, 45us동안만 데이터를 디스크에 썼다는 얘기가 된다. Sequential write transfer time도 170MB/S이니까 45us동안에는 약 7.84KBytes만을 쓸 수 있다. 그렇다면, 50GB 기록을 위해 50GB/7.84KBytes= 약 660여만개의 SSD가 필요하다는 얘기가 된다.
이게 말이 되는가? SSD 하나 가격이 50만원이라고 해도, 660여만개를 구비하려면  3조 3천억원이상이 필요하다.

결국엔 Cassandra를 만들었다는 저 엔지니어들은 잘못되거나 왜곡된 실험 결과를 내놓은 거라고 밖에 생각할 수가 없다. 우리나라에서도 학부 2-3학년에 배우는 디스크가 어떤 구조인지, 디스크의 cost model도 모른다는 얘기가 된다.
 필시 메모리에 50GB 데이터를 유지하는 상태에서 저렇게 얘기하는 것으로 밖에 보이지 않는다.
근데 여기서 다시 또 생각해보면, 디스크의 데이터를 메모리에 올리는데 걸리는 시간은 디스크 읽기 속도에 의존적일 수밖에 없다.  이때도 쓰기 때와 비슷한 속도가 나올텐데, 도대체 어떻게 저런 실험 결과가 나왔다고 주장할 수 있는지 참 궁금할 따름이다. 
Posted by Bart

댓글을 달아 주세요

  1. 비밀댓글입니다

    2009.12.28 20:35 [ ADDR : EDIT/ DEL : REPLY ]
    • 네. 데이터를 디스크에 기록하는 시간은 절대 될 수 없습니다.
      말씀하신 바는 query 를 각 노드에 배분하여 writing 작업수행 준비에 걸리는 시간이 아닌가 하는거죠?

      그럴 가능성은 있겠네요. SQL은 질의 parsing하고, query plan 작성하고 이에 따라 subquery들을 각 노드에 배분해야 하니까, 시간이 좀더 걸릴 수 있겠네요.
      그런데 사실 이것도 일장일단이 있지요. 간다하고 몇개 안되는 질의들은 직접 프로그래밍 해서 뜨는게 나을 수 있고, 좀더 복잡하고, 재사용될 수 있는 질의들은 SQL로 뜨는게 더 낫겠고요.

      근데 질의 배분 시간을 의미한다면, 저렇게 write average란 단어를 TP에 쓰면 안되겠죠. 그리고 데이터 사이즈는 또 뭐란 말인지.

      2009.12.29 03:07 신고 [ ADDR : EDIT/ DEL ]
  2. 뫈퐁

    카산드라 관련 포스팅을 찾아 다니다 좋은 의견의 글을 보고 댓글 남깁니다.
    아무리 생각해도 물리적으로 디스크에 쓰는 경우 저 성능은 나올 수가 없겠지요.
    http://www.mikeperham.com/2010/03/13/cassandra-internals-writing/
    위 글을 보면 바로 디스크에 동기화 하지 않아도 되니 저 성능을 보이는군요.
    올리신 글이 작년 글이긴 하지만 몇 줄 남깁니다.

    2010.10.01 10:58 [ ADDR : EDIT/ DEL : REPLY ]
    • 글 감사합니다.

      네. 올리신 주소의 글에서 보이는 바와 같이 Cassandra도 BigTable에서와 마찬가지로 데이터를 메모리에 유지하고 있다가 disk에 임계값이 넘을 때 이것을 그대로 immutable image로 디스크에 쓰는 것으로 압니다. 더 구체적오르는 Patrick O'Neil의 LSM-tree에서 언급되었던 update-intensive한 작업 처리를 위해 인덱스 갱신을 sequential workload로 만드는 방법을 차용한 것으로 보여집니다. 이래놓고는 디스크에 기록한다고 해서 사람들 헷갈리게 만들었으니...

      2010.10.03 14:20 신고 [ ADDR : EDIT/ DEL ]