참조 : http://css.dzone.com/news/nosql-job-trends

 

요즘 Nosql 트렌드에 대해서 얘기해드리겠습니다.

indeed라는 취업 전문싸이트에서 job 검색을 통해서 검색이 가능합니다.

 

http://www.indeed.com/jobtrends 라는 싸이트를 통해서 비교해볼 수 있습니다.

 

키워드를 넣고 검색해보니. 최신 데이터는 이렇게 나옵니다.

 

mongoDB > cassandra > memcached > hbase > redis ....  이런 순이네요.

 

mongoDB가 넘사벽으로 쭉쭉 성장하고 있습니다. 안정성이 확보되면서 많이들 사용하고 있는 것 같네요.

 

cassandra, redis, voldemort, simpleDB, couchDB, mongoDb, hbase, hypertable, Riak, memcached Job Trends graph 

 

memcached를 제외한 성장율을 보겠습니다.

mongodb > redis > hbase ....

 

cassandra, redis, voldemort, simpleDB, couchDB, mongoDb, hbase, hypertable, Riak Job Trends graph 
 

여기 말고 simplyhired.com 에서의 정보도 보겠습니다.

 

cassandra = mongodb > hbase > redis ....

 

 

 

 

 

mongdodb를 선택하는 배경에는 설치와 사용이 쉽고, RDBMS 쿼리와 유사하게 실행할 수 있는 장점이 있었습니다.

Document (binary json)기반이고, 복잡한 쿼리를 사용할 수 있으며, 데이터를 잘 저장합니다.(consistency)

또한 규모에 상관없이 꾸준한 성능이 뒤받침되고 있습니다. 또한 php interface를 붙여 연동이 쉽게 되는 장점이 있습니다. 그리고,  master-master replication와 자동 sharding을 해줍니다.

 

해외의 일부 블로그는 새로운 Mysql 이다라고 얘기할 정도로 많이 mongo db를 선호하고 있네요.

 

앞으로 어떻게 될지 지켜봐야할 것 같네요..

 

 

 

 

Posted by 김용환 '김용환'
TAG NoSQL

Redis 소개

nosql 2011.08.18 16:59


<내용 다운로드>
 


<슬라이드>

Redis






<관련내용>


내가 알던 캐쉬 솔루션
- memcached 기반
- mysql 기반

But, 현실은 이 둘로 만족 못해.
그 이유는 mysql의 persistent, 데이터 크기와 memcache의 1mb데이터 크기 이슈가 있다.

다양한 데이터를 지원하고,  replication도 수직/수평으로 되고, 1mb 이상 데이터를 마음대로 쓰고, 속도나 여러 언어에서 사용할 수 있는 그런 캐쉬 솔루션을 원했다.


Redis?
- Vmware (2010.3.15 스폰서)에서 밀고 있음
-Remote Dictionary Server의 약자
-Key-value store, Cache
-사용하는 곳: Github, blizzard, digg, stackoverflow
-최신 버전 : 2.2.12 (stable) 2011/08/17
-http://redis.io/


장점
- Persistence
- Speed (간단한 데이터 2백만 건을 1.28초에 저장)
- Data Structure
- Atomic Operation (tx)
- Sharding / Replication 의 용이
- Pub/sub / notification (message queue 또는 comet)  - real time
- String(1G), Hash, List, Set, Sorted Set(score필요), intersection, union, difference
- In-memory
- 데이터 TTL, Expire
- Node.js를 포함하는 클라이언트가 다양한 언어에서 구현.
- operation cost : O(1)
- Multiple Instance에 접속해서 item를 수집(select)후 옮길(move) 수 있음(locking지원)

단점 / 이슈
- Ram mode에서는 이슈는 없지만, VM mode 를 이용해서 메모리 관리할 때 속도가 많이 느려짐
- In-memory라 메모리보다 큰 데이터는 적합하지 않을 수 있음(VM 모드를 사용할 때는 메모리 제한이 없음) -> 2.4부터 VM 모드 deprecated
Persistence 의 snapshotting 이용시 I/O 이슈가 있음
- 소스 컴파일 설치
- Sharding을 클라이언트에서 잘 지정할 필요가 있음
- Replication시 blocking됨 (2.4부터 non-blocking하면서 속도개선)

왜 Redis를 주목하는가?
- Vmware의 CloudFoundry Stroage 엔진으로 사용 (mysql, mongoDB와 함께 선정).
- 성능은 memcached와 비슷 함 (리얼 환경에 따라 달라질 수 있음)
- Non blocking IO, Single Threaded
- epoll, kqueue and select 이용
- Libevent (이벤트 처리 오픈 소스) 를 이용하는 대신 자체 구현.
 => Dependent가 없음. 심플해지는 코드
- Single-thread Server
- ANSI C 구현
- 임베디드 / 서버에서 porting이 편함
- Portable 코드!
- 2.4부터는 비동기로 Replication 구성이 가능

* Node.js + redis 사용하는 사례들이 최근에 늘고 있음
* 2011년 안으로 Redis clustering을 구현할 예정    (처음부터 분산 테이블을 목표로 만들어졌기 때문에 이 부분이 구현되면 엄청난 일이 벌어질 듯..)



2.4 Release 내용들
http://antirez.com/post/everything-about-redis-24
Redis Main 개발자 블로그
- 속도개선
- Replication시 non-blocking으로 동작
- jemalloc 추가
- set또는 list에 multi adding 기능
- 그외짜잘한 성능/기선 개선




간단한 데모
http://try.redis-db.com
2.0.2 version 이라서 그 이상의 버전에서 제공하는 API를 활용할 수 없음
- mset 버그 있음..




설치/실행 방법


// 설치 (http://redis.io/download)
$ wget http://redis.googlecode.com/files/redis-2.2.12.tar.gz
$ tar xzf redis-2.2.12.tar.gz
$ cd redis-2.2.12
$ make

// 데몬 실행
$ cd src
$ cd redis-server
(daemon).. Log..



 

// 클라이언트 실행 - 다른 쉘에서 실행
$ cd 소스설치/src ; redis-cli
redis> set foo bar
OK
redis> get foo
"bar"




예제 코드

> set hello world
"OK"
> get hello
"world"



 

 
 >  set a 1
‘1’
> expire a 100
true
> get a
"`1"
> get a
"`1“
(100초 뒤)
> get a
null

 

> set foo 0
"OK"
> incr foo
1
> incr foo
2
> incr foo
3
> get foo
"3“
> decr foo
2

  

> set hello world
"OK"
> get hello
"world"
> exists hello
true
> type hello
"string"
> rename hello olleh
"OK"
> get olleh
"world"
> del olleh
1
> get olleh
null


 

 

> set a 1
"OK"
> set b 2
"OK"
> set c 3
"OK"
> mget a b c
["1","2","3"]


 

 

> sadd seta foo
true
> sadd seta bar
true
> sadd setb foo
true
> sinter seta setb
["foo"]

 





 

> lpush list a
1
> lpush list b
2
> lpush list c
3
> lpush list d
4
> lrange list 0 2
["d","c","b"]
> lrange list 0 3
["d","c","b","a"]
> lrange list 2 3
["b","a"]

 


 


 

> sadd set 1
true
> sadd set 2
true
> sadd set 3
true
> smembers set
["3","1","2"]

  

> zadd ss 1 aa
true
> zadd ss 10 zz
true
> zadd ss 9 yy
true
> zadd ss 2 bb
true
> zrange ss 0 -1
["aa","bb","yy","zz"]

 

 > hset user:1 name x
true
> hset user:1 lastname y
true
> hset user:2 name aa
true
> hget user:1
wrong number of arguments (1 for 2)
> hget user:1 name
"x"
> hgetall user:1
{"name":"x","lastname":"y"}
> hget user:2
wrong number of arguments (1 for 2)
> hget user:2 name
"aa"

  

> multi
"OK"
> lpush clist a
"QUEUED"
> lpush clist b
"QUEUED"
> lpush clist c
"QUEUED"
> lrange clist 0 -1
"QUEUED"
> exec
[1,2,3,["c","b","a"]]

  


> multi
"OK"
> lpush dlist a
"QUEUED"
> lpush dlist b
"QUEUED"
> discard
"OK"


 

 pub/sub 코드

1. subscribe 함

[test /home/www/redis/redis-2.2.12/src]# ./redis-cli
redis 127.0.0.1:6379> psubscribe news.article.*;
Reading messages... (press Ctrl-C to quit)
1) "psubscribe"
2) "news.*;"
3) (integer) 1


 


2. publish 함

redis 127.0.0.1:6379> multi
OK
redis 127.0.0.1:6379> set article.tech.1000 "Google"
QUEUED
redis 127.0.0.1:6379> sadd article.tech 1000
QUEUED
redis 127.0.0.1:6379> publish news.article.tech 1000
QUEUED
redis 127.0.0.1:6379> exec
1) OK
2) (integer) 1
3) (integer) 0



3. subscribe 하던 부분에서 subscription 받음

1) "pmessage"
2) "news.article.*"
3) "news.article.tech"
4) "1000"






java client API - jedis (가장 괜찮은 것 같음)

<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.0.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>




가장 좋은 java 클라이언트 라이브러리
- https://github.com/xetorthio/jedis
- 자바의 Map, Set 같은 Collection과 연동되어 사용 가능
- Sharding이 지원되다고 적혀있지만, 테스트는 해보지 않음

 

@Controller
@RequestMapping("/restful")
@ResponseStatus(value = HttpStatus.ACCEPTED)
public class RestfulController {

@RequestMapping(value = "/set/key/{key}/value/{value}", method = RequestMethod.GET)
public String getString(@PathVariable String key, @PathVariable String value, ModelMap model) {
System.out.println("key : " + key);
System.out.println("value : " + value);

Jedis jedis = new Jedis("1.1.1.1");
jedis.set(key, value);
String kValue = jedis.get(key);

model.addAttribute("key", key);
model.addAttribute("value", kValue);
return "test";
}
}




 
운영상 장점
- 백업은 리얼타임으로 진행
-0 Master – Slave Replication이 수직/수평적으로 scale 가능
- (지금 당장은 없지만) 올해 안으로 Clustering 기능 추가 예정
https://github.com/antirez/redis/blob/master/design-documents/REDIS-CLUSTER
- 대형 데이터 cache용 용도로 생각
 memcached는 크기가 큰 데이터에 취약
- Slave 구성시 서버를 내리지 않고 사용가능. Replication 순서
slave asks for SYNC
master BGSAVE, slave waits
master BGSAVE finished, the initial bulk data (the .rdb file) is transfered to slave
master accumulates all the new differences for the slave
master finishes sending the whole initial rdb file to slave
master start feeding the slave with the accumulated buffer, and with anything new arriving from clients, if they are writes.




운영상 이슈 & 편리
- 메모리에 있는 데이터들을 File system으로 덤프
   1) Snapshotting  (디폴트)
자식 프로세스 실행(fork)하고 자식프로세스가 임시(new) RDB파일 만들고, 그것을 다 저장하면 예전(old) 파일 이름으로 교체 (copy-on-write)
속도 이슈로 인해서 많이 고민했음

   2) Append-only file (AOF)  - 괜찮은 방법
2.0과 2.2가 절차가 다름.
만약 Snapshotting 하다가 Kill 되거나 비정상적 종료에 대비해서 실행 로그들을 따로 저장(Log Rewriting)하여 만약 재시작시 상태를 유지하기 위해서 AOF 파일을 읽음
자식 프로세스 실행(fork)하고, 자식 프로세스는 임시 AOF 파일을 저장한다. 부모 프로세스는 in-memory buffer에 새로 변경된 내용을 계산한다. 자식 프로세스는 쓰기 작업이 완료후에 부모 프로세스는 in-memory buffer의 내용을 AOF 파일에 저장한다. 새로운 파일로 교체.


 

운영상 편리
AOF를 이용한다면, 서버 관점에서는 정지시간 없이 Redis 재시작 / 업그레이드 가능 (서버 편함)
환경
설정 정보 변경시 재실행
새로운 버전의 redis 서버 재실행
포트 변경 필요,
서버의 포트를 변경하기 때문에 client의 서버 접속 포트를 수정하고 재시작 필요. (client 불편)
=> 오히려 이거 불편. 기존 방법 사용 필요




운영에 대한 모니터링툴  지원
https://scoutapp.com/plugin_urls/271-redis-monitoring
운영상, cache hit에 대한 정확한 내용은 필요없음. 요청오면 요청 그대로 보내주는 걸로..




운영상 불편할 점
- consistent hashing 을 지원하는 client를 이용해야 distribute 가능
- Sharding을 일일이 클라이언트 API를 이용해서 해줘야 함. API에서 반드시 지원


용도
- Ehcache 와 같이 expire 해도 되는 item 용도
- counter
- 최근 30개를 순서대로
- 랭킹 정보
- 일반 캐쉬 용도


Arcus 개발팀 Redis 한계를 지적한 부분 (SDEC 2011.6)
Radis 1.2 검토 대비 최신 버전 2.2 비교

- Sorted set에는 no (offset, count) option
 => 최신 버전에서는 offset, count 기능 추가
- No capped collection
=> 용량제한이 있으며, FIFO기능을 갖고 있는 고성능의 테이블을 capped collection이라고 함. 원래 Redis 지원 안함. 원래 빠르게 개발하면 의미가 없어짐
- Not enough cache statistics
- Cannot control memory use
 => info 명령어를 이용해서 간단하게 메모리 사용량 측정 가능


공부했던 레퍼런스 자료들

http://redis.io/   , http://redis.io/topics/faq
http://simonwillison.net/static/2010/redis-tutorial/
http://www.slideshare.net/tag/redis/
http://blog.mjrusso.com/2010/10/17/redis-from-the-ground-up.html
http://www.slideshare.net/Cyworld/004-cto
http://pauladamsmith.com/articles/redis-under-the-hood.html
http://hi.baidu.com/roger_long/blog/item/611b1d017f57f89de950cd87.html
http://redis.io/presentation/Redis_Cluster.pdf
http://www.slideshare.net/karmi/redis-the-ak47-of-postrelational-databases
http://pauladamsmith.com/blog/2011/03/redis_get_set.html

 

 

 


 

Posted by 김용환 '김용환'

아래 내용은 Memcached와 Redis간의 성능 테스트를 했던 블로그의 내용을 발번역한 자료이다.
원래 원문은 아래 링크이며, 나는 블로그들을 살펴보며, 무슨 말을 하려고 했는지 보고 싶었다.
http://nosql.mypopescu.com/post/1462969783/redis-and-memcached-benchmarks

수많은 테스트를 통해서 나는 벤치마크 테스트 셋을 잘 믿지 않는 편이다.
내가 속해 있는 App-Data 환경에서 테스트해야 좀 믿는다.

하지만 다양한 테스트 결과가 봄으로서, 통찰력이 생길 수 있다는 점은 좋은 것 같다. ^^



1. 블로그 #1
2009년 11월에 한 블로거가 redis와 memcached와 tokyo tyrant와 mysql을 테스트를 하였다.

http://www.ruturaj.net/redis-memcached-tokyo-tyrant-mysql-comparison

redis가 특정 벤치마크테스트에서 get/set에 뛰어난 성능을 보여주였다.

throughput set

throughput get

2. 사건 #2

2010년 8월에 또다른 블로거가 이에 대해서 글을 작성했다.
http://systoilet.wordpress.com/2010/08/09/redis-vs-memcached/

3바이트 키을 가진 10만개 데이터를 넣고, 얼마나 빨리 찾는지 보여주는 테스트이다.




Muti-get 테스트할 때는 Redis가 상당히 안좋게 나왔다. 당시에는 Redis가 multi-bulk 전송기능이 후졌을 때를 기준으로 테스트된 거라, 지금 (2011.8월)은 어떻게 나올지는 모르겠다.



10바이트 키에 최대로 16KB까지 처리할 수 있는 가변 데이터를 테스트했다.
Memcached는 데이터의 길이가 커지면 성능이 떨어지는 이슈가 생겼다. (문서에서는 1Mbyte까지 지원한다고 하지만, 실제로는 상당히 좋지 않은 결과가 나왔다)

memcached가 원래 대용량에 약하며, 길이 제한이 제일 강하다. Amazon Simple DB가 memcached 기반이다.


내용을 봤을 때는 작은용량일때는 memcached가  redis보다 성능이 좋은 것 같다.


3. 블로그 #3

또다른 블로거가 발끈하고 2010년 9월에 쓴 자료가 있다.

http://antirez.com/post/redis-memcached-benchmark.html

벤치마크 테스트를 수정해서 테스트했더니. redis가 더 좋게 나왔다.

블로그 #2의 테스트 결과는 잘 못 테스트했다라는 것이다. busy loop나, 클라이언트 lib, 동일하지 않은 클라이언트 lib 문제로 테스트결과는 잘못되었다가 얘기했다.

Redis VS memcached 

그리고, 백만 key를 get/set 테스트해서 cpu 사용률 결과를 공유했다. 거의 큰 차이가 없었다.

  • memcache: user 8.640 seconds, system 19.370 seconds
  • redis: user 8.95 seconds, system 20.59 seconds

Redis는 set/list/hash에 대해서 atomic하게 get/set를 해줄 수 있기 때문에 하드웨어의 영향을 받을 수 있다. 또한 한계가 있는 상황에서 Redis가 memcached보다 빠르다라고 말할 수 없으며, 테스트 환경에 따라서 둘 중의 하나가 빠르다고 결과가 나올 것이다.


4. 블로그 #4

어떤 분이 성능 비교 글을 쓰며, 블로그 #2, 블고그 #3 모두 똑같은 이슈가 있다고 했다. 한 물리 서버에서 하나의 서버에  하나의 클라이언트를 돌려서 테스트하는 것은 잘못된 경과라고 했다. 그리고, 블로그 #3의 결과가 좀더 괜찮다고 했다.

http://dormando.livejournal.com/525147.html

블로그 #3의 코드를 조금 다듬어 paralle(병렬)로 테스트를 했더니 다음과 같은 결과가 나왔다.







이 블로거는 테스트결과를 공유하고, memcached는 multi-thread로 매우 좋은 결과를 만들었고, redis는 single -thread 때문에 퍼포먼스가 별로였다고 언급했다.

Redis를 가지고 single thread와 multi thread 로 테스트를 했더니 오히려 single thread쪽이 더 좋은 결과를 내었다고 얘기했다.

 


5. 블로그 #5

블로그 #3의 주인이 블로그 #4에 대해서 쓴 글이다.
http://antirez.com/post/update-on-memcached-redis-benchmark.html


이 사람은 2코어의 cpu 사용의 한계를 주고, 100개의 클라이언트로 테스트했다.
  • Memcached was serving 130k SETs per second and 150k GETs per second.
  • Redis was serving 200k SETs per second and 200k GETs per second.
memcached는 멀티 코어를 사용하는 하나의 인스턴스에 대해서는 scale을 못하는 문제가 있음을 얘기했다.
그래서 2개의 memcached를 실행했더니 Redis와 비슷한 성능을 나오는 것을 발견했다.

  • Memcached was serving 200k SETs per second and 200k GETs per second.


Redis가 memcached보다 복잡해서 안정성과 속도를 적절히 유지하면서 쓰레드 기반의 구현이 어려울 수 있다고 했다. Redis는 MGET 성능이 좋지 않기 때문에 Hash데이터를 저장하여 HGETALL 을 써서 한번에 읽고 쓰도록 하는 것이 좋다고 했다.


6. 결론
괜찮은 벤치마크 테스트를 만드는 것은 쉽지 않다. 대부분의 벤치마크 테스트는 잘못된 테스트를 하거나, 실제 개발에서는 사용하지 않는 것들을 테스트하기 때문이다. 따라서 벤치 마크 자료를 보았을 때는 그 자료를 100% 신뢰하지 말라는 것이다. 사용을 위해서는 App 개발 환경에서 사용할 수 있는 테스트 시나리오(data 크기, 동시성 레벨) 를 진행하는 것이 좋다. (당근 옳소~)


Posted by 김용환 '김용환'

okcupid.com 이라는 회사는 짝 매칭 서비스 이다. 

 

 발표 동영상은 다음과 같다.




PT가 공개가 아직 안된 관계로 캡쳐화면과 발번역으로 내용을 소개한다. 

okcupid.com 에 접속해서, 내가 원하는 조건을 가지고 내가 원하는 타입을 찾아낼 수 있다.



내가 원하는 타입이 match 율에 따라서 보여준다.


 
중요한 점은 웹 페이지에서는 개인적인 정보(preference)를 가지고 있지 않다. 즉 개인 정보는 최대한 보호할 수 있다.

DB에 개인정보를 보면 질문에 대한 답(취향), 숨겨질 정보, 투표, demo data(자신의 외모,키), demo prefs(내가 찾는 이성 정보) 등이 저장되어 있다.




만약 웹서버에서 DB에 접속해서 개인 정보를 얻어오려고 한다면, 얼마나 많이 검색해야 할까? 1K 디스크 seek만 해도 천3백만명이면, 1억 3천만개의 seek를 해야 한다.



우리는 scalable, low cost, fast, reliable 관점으로 시스템을 구축했다.


* scalable 관점
worker는 분산 아키텍처기반으로 나누어져 있다. 이렇게 하면 2배이상의 효율을 얻어낼 수 있다.




웹 서버의 요청을 받아 merger를 통해 worker로 정보를 읽어오게 하고, 그것을 하나로 데이터를 만들어 웹 서버로 전달했다.



* low cost 관점
c++은 java보다 3배 빠르고, 4배 메모리를 적게 먹어서 서버를 적게 사용할 수 있었다.
12core에 맞게 12개의 worker를 두었다. 


* fast 관점
어떻게 해야 가장 빨리 검색할 수 있을까? location, last login을 기준으로 검색해야 했다.
quadtree를 이용해서 지역과 last login정보를 검색하도록 해서 high dimension tree보다 2배 이상 빨리 검색할 수 있었다. 
(@김용환 코멘트 : 사실 이미지 검색쪽에서 많이 사용되었던 알고리즘이다. jpeg2000에서 이 알고리즘을 보고 좋아했었다. location 시스템에서 quadtree는 속도가 엄청빠르다. 일부 표준 문서에 jpeg2000으로 이미지를 압축해서 보내는 것을 넣는 것을 했었다.)


[##_http://knight76.tistory.com/script/powerEditor/pages/1C%7Ccfile23.uf@131D724D4E2FB6710C9809.png%7Cwidth=%22600%22%20height=%22305%22%20alt=%22%22%20filename=%22cupid8.png%22%20filemime=%22image/jpeg%22%7C_##]


(@김용환 코멘트 : quardtree가 속도가 좋을 수 밖에 없는 것은 바로 밀집성과 연관되어 있다. 지도에서 보면, 미국 동북부 지방, 캘리포니아 지방에 사각형이 세밀하게 있고, 텍사스쪽은 허허 벌판이다. 즉 사람 정보가 거의 없다는 것을 의미한다. 인구의 밀집성에 맞춘 검색에 적합하다고 할 수 있다.)




 
[##_http://knight76.tistory.com/script/powerEditor/pages/1C%7Ccfile5.uf@121D724D4E2FB6710B32CC.png%7Cwidth=%22600%22%20height=%22303%22%20alt=%22%22%20filename=%22cupid10.png%22%20filemime=%22image/jpeg%22%7C_##]

* Reliable 관점
work 장비가 죽어도, 작동되게 하기 위해서 여러개의worker 인스턴스가 동작될 수 있다.




worker 장비의 속도는 생명이기 때문에 일반적인 정보를 caching한다. 리스타트하면서 DB 정보를 읽어온다. 
10만명의 개인 사용자 정보를 읽어오는 worker가 있다면, 디스크 정보 얻어오려면 10만번을 해야 한다. 이 방법은 좋지 않았다.



그래서 nosql을 사용해서 10만명의 정보를 읽어왔다. 좋았다. (@김용환 코멘트 : 얼마나 좋은지 지표를 주면 좋았을 뻔)



맘에 들지 않지는 사람은 hide를 시킬 때, 이 정보를 mysql, worker, nosql로 복제를 해야 한다. 



nosql은 SSD를 사용해서 효과를 얻을 수 있다. SSD는 4배 정보 비싸지만 12배 정보 write 속도가 빠르다. 



이 방식을 사용하여 3배 정보의 비용 절감 효과를 보았다. (@김용환 코멘트 : 예전에 프로젝트할 때 부팅 속도빠르게 플래쉬를 쓰려고 했었다. 빠른 부팅속도, 빠른 IO를 사용하여 성능을 최적화는 것도 좋은 방법 중의 하나)



SSD에서는 write는 read를 block한다.
write 때문에 read 속도가 팍 늘어나는 것을 볼 수 있다. 



이런 부분 때문에 최대한 write를 피해야 하고, SSD 벤치마킹을 잘해서 critical한 부분에서는 read 속도 때문에 문제가 되지 않도록 충분히 피해야 한다.



Last Look
- C++
- Optimized heavily
- Single threaded procs
- SSDs


Posted by 김용환 '김용환'