사실 글 쓰기 전에 카테고리를 어디에 넣어야 할지 정말 많은 고민을 했다 ㅋㅋㅋ
Valgrind는 여러 CPU family에서 사용 가능하고 또한 지원하는 언어도 다양하기 때문에 거의 어디서든 사용할 수 있기 때문이다.
그래서 그냥 programing에 넣어버렸다.
각설하고, Valgrind는 memory trace tool로 대부분 memory leak이나 잘못된 포인터의 접근 등을 알아보는데 쓰이지만 나는 현재 진행하고 있는 in-memory 프로젝트에서 Cassandra가 현재 어떻게, 얼마나 메모리를 사용하고 있는지 알아보기 위해 사용하도록 하겠다.
1. 다운 & 설치
# wget http://www.valgrind.org/downloads/valgrind-3.7.0.tar.bz2
# tar -xvjf valgrind-3.7.0.tar.bz2
리눅스의 기본 3대 설치법
./configure
make
make install
끗!
단, 주의할 점이 있는데 README를 읽어보자.
Important! Do not move the valgrind installation into a place
different from that specified by --prefix at build time. This will
cause things to break in subtle ways, mostly when Valgrind handles
fork/exec calls.
라고 합니다. 난 걍 설치 ㄱㄱ
구동하기 위해선 다음과 같은 패키지가 필요한듯.
On Debian, Ubuntu: libc6-dbg
On SuSE, openSuSE, Fedora, RHEL: glibc-debuginfo
테스트 해보자 ! ls -l 을 가지고 테스트해 보겠다
# valgrind ls -l
leak check을 위해서는 --leak-check=yes 옵션을 붙여준다.
==8275== HEAP SUMMARY:
==8275== in use at exit: 15,212 bytes in 109 blocks
==8275== total heap usage: 604 allocs, 495 frees, 102,693 bytes allocated
==8275==
==8275== LEAK SUMMARY:
==8275== definitely lost: 80 bytes in 2 blocks
==8275== indirectly lost: 240 bytes in 20 blocks
==8275== possibly lost: 0 bytes in 0 blocks
==8275== still reachable: 14,892 bytes in 87 blocks
==8275== suppressed: 0 bytes in 0 blocks
==8275== Rerun with --leak-check=full to see details of leaked memory
==8275==
==8275== For counts of detected and suppressed errors, rerun with: -v
==8275== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 31 from 8)
다음과 같은 결과가 잘 나오는 것을 볼 수 있다.
드디어 Cassandra 를 In-memory에서 돌려보기 위한 준비가 끝났다.
Memtable threshold를 조정하여 가능한 한 disk로 flushing되지 않고 메모리에서 동작하게 해보자.
MemtableObjectCountInMillions의 memtable_throughput_in_mb는 Memtable에서 SSTable로 disk에 flushing하기 전에 단일 Memtable에 저장했던 coloumn의 최대 개수를 말한다.
기본값은 0.3이고, 이것은 약 333,000컬럼을 말한다.
또한 Memtable을 disk에 flushing한 뒤에 얼마나 오래 메모리에 남겨둘 것인가에 대한 threshold가 존재하는데 이것은 memtable_flush_after_mins 값을 변경하면 된다고 한다.
그리고 flush를 수행할 때, Memtable을 flush buffer에 쓰게 되는데, flush_data_buffer_size_in_mb값으로 buffer의 크기를 조절할 수 있다.
마지막으로 memtable_flush_writers값이 있는데 이것은 필요할 때 Memtable에 write명령을 수행하기 위한 thread의 개수를 지정하게 된다.
BUT!!
이렇게 쉽게 안 넘어갈 줄 알았다.
위의 값들은 0.8 대의 버전에서는 사용하지 않으며, 각각은 기본값으로 주석처리 되어 있고, 몇몇 값들은 아예 column family에 종속되어 버렸다.
따라서 우리는 이 값들을 다시 볼 필요가 있는데, Cassandra에서 column family의 정보를 보면 다음과 같이 나오는 것을 알 수 있다.
[default@usertable] show schema;
create keyspace usertable
with placement_strategy = 'NetworkTopologyStrategy'
and strategy_options = [{datacenter1 : 1}]
and durable_writes = true;
use usertable;
create column family data
with column_type = 'Standard'
and comparator = 'BytesType'
and default_validation_class = 'BytesType'
and key_validation_class = 'BytesType'
and memtable_operations = 2.3203125
and memtable_throughput = 495
and memtable_flush_after = 1440
and rows_cached = 0.0
and row_cache_save_period = 0
and keys_cached = 200000.0
and key_cache_save_period = 14400
and read_repair_chance = 1.0
and gc_grace = 864000
and min_compaction_threshold = 4
and max_compaction_threshold = 32
and replicate_on_write = true
and row_cache_provider = 'ConcurrentLinkedHashCacheProvider';
빨간색으로 칠해놓은 저 세가지의 threshold가 보이는가!?
이제 설치된 카산드라 위에 YCSB를 돌려보자.
전에도 말했듯이 소스로 받는 것이 조금 불편할 수 있으나 확실한 동작을 보장한다고 할 수 있으므로 소스로 가겠다 ㄱㄱㄱㄱ
이번엔 git을 이용해서 받아보자
# git clone git://github.com/brianfrankcooper/YCSB.git
git이 없으면
# apt-get install git-core
다 받아졌으면 YCSB폴더로 들어가서 빌드를 하자. 이번엔 maven을 사용한다.
# mvn clean package
역시 maven이 없으면 설치
# apt-get install maven2
하다가 에러가 났다.
으아니! 문제는 asm-3.1.jar 파일이군!
받아준다
http://www.java2s.com/Code/Jar/a/Downloadasm31jar.htm
문제가 발생한 디렉토리에 덮어씌워주고 다시
# mvn clean package
끝나면 workload를 돌리면 된다.
script를 짜도 되고 걍 돌려도 된다.
(뒤에 처자는 애교로 넘기져)
만약 다음과 같은 오류가 발생한다면 이것은 client disclosed를 의미하는 내용이기 때문에
무시해도 상관 없다고 한다.
DEBUG [pool-2-thread-2] 2011-10-05 12:00:49,374 CustomTThreadPoolServer.java (line 197) Thrift transport error occurred during processing of message. org.apache.thrift.transport.TTransportException at org.apache.thrift.transport.TIOStreamTransport.read(TIOStreamTransport.java:132) at org.apache.thrift.transport.TTransport.readAll(TTransport.java:84) at org.apache.thrift.transport.TFramedTransport.readFrame(TFramedTransport.java:129) at org.apache.thrift.transport.TFramedTransport.read(TFramedTransport.java:101) at org.apache.thrift.transport.TTransport.readAll(TTransport.java:84) at org.apache.thrift.protocol.TBinaryProtocol.readAll(TBinaryProtocol.java:378) at org.apache.thrift.protocol.TBinaryProtocol.readI32(TBinaryProtocol.java:297) at org.apache.thrift.protocol.TBinaryProtocol.readMessageBegin(TBinaryProtocol.java:204) at org.apache.cassandra.thrift.Cassandra$Processor.process(Cassandra.java:2877) at org.apache.cassandra.thrift.CustomTThreadPoolServer$WorkerProcess.run(CustomTThreadPoolServer.java:187) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603) at java.lang.Thread.run(Thread.java:636) DEBUG [pool-2-thread-2] 2011-10-05 12:00:49,376 ClientState.java (line 94) logged out: #<User allow_all groups=[]>
자세한 내용은 여기