Monthly Archives: February 2012
[후기] 자바 개발자 컨퍼런스 JCO(12회) 를 다녀와서…
국내 최대 개발자 행사중에 하나인 JCO에 이번에 강연자로써 참여를 했다. 그래서 다른 사람들과는 조금 다른 후기가 되지 않을까 싶다. 일단 내 세션의 제목은 “초보자를 위한 분산캐시 활용전략” 이었다. 사실 내 세션의 핵심은, “왜 캐시를 써야할까?” 에 초점을 맞추고 있었다. 그래서 특히 앞부분에서의 성능 이슈를 설명하는 것이 초점이었는데, 아뿔싸!!! “초보자를 위한” 이라는 걸 붙였지만… 초보자가 아닌 분들이 너무 많이들어오셨다.(일단 뒤에서 다시…)
일단 내가 들어간 세션만 소개하자면 이번에는 강연자로 참여를 해서 1세션과 5세션 밖에 듣지를 못했다. 1세션은 김형준 수석님의 “빅데이터 플랫폼 기반 소셜네트워크 분석 사례” 를 들었는데, 역시 김형준 수석님 강의는 들을 때 마다 좋다라고 해야할까? 특히 그루터에서의 실제 사례를 들어서 설명해 주시기 때문에(본인 입으로는 깔대기와 약을 판다고 하시지만) 상당한 도움이 되었다. 원래 김형준 수석님 성격이 하나를 물어보면(1분짜리 질문), 그것이 어디서 부터 시작되고, 왜 그렇게 되는지, 그리고 최종적으로 어떻게 해결해야 하는지(30분~60분 소요) 알려주시는 성격이라, 상당한 도움이 되는데, 그런 성격이 딱 묻어나는 강연이지 않았을까 싶다.
두번째 세션은 내 세션이 3번째라, 마지막 준비한다고 못들었고, 4번째 세션은 발표 후 너무 긴장이 되어서, 배가 너무 아픈 나머지, 꼭 듣고 싶었던 이용혁님의 “대용량 고가용성 분산 캐쉬서버(infinispan)를 활용한 웹서비스” 를 듣다가 나왔다.
마지막 세션은 양수열님의 “스타트업을위한 Rapid Development” 였는데, 사실 여자개발자 모임이 듣고 싶었는데, 철혁과장님이 거기 자리없어라는 말과 함께 날 끌고 가셔서 T.T(나중에 보니, 자리가 남았다고 T.T) 그래도 양수열님의 강의는 상당히 재미있었다. 핵심은 스타트업에서는 생산성이 높은 프레임웍을 사용하자라고 요약하면 될까?
이제 마지막으로 내 세션은… 시간을 잘못 계산해서 10분 일찍 끝났다 T.T 흑흑흑, 그러나, 끝나고 질문하신 분들이 3~4분 되셔서 1시간 다 채운듯 T.T, 개인적으로 memcached 등으로 replication은 권장하지 않는 방법인데, 대부분(나도 사실 처음에는…) 가장 관심을 가지는 부분이 memcached로 어떻게 리플리케이션 하나요? 였던거라는 점이 날 당황하게 했다. “권장하지 않는다. 캐시는 캐시답게 사용해야 합니다.” 라는 답변을 드리긴 했지만(사실이예요. 이게 정답입니다.) 좀 마음이 아프다고 해야할까…
강연자 입장에서 보면, 강연자들끼리 소개하는 시간이 있었으면 어떨까라는 생각이 들었다. 일단 같은 세션에 발표하신다고 준비하신 최홍식님, 이연희님, 마지막 세션에 발표해주신 진성주님 세분하고만 대기실에서는 인사를 할 수 있었다. 물론 뒷풀이 때는 양수열님과 인사를 나누긴 했지만…
상당히 개인적으로 아쉬움이 남는 발표라, 다음번에는 좀 더 알차게 준비해야 되지 않을까 라는 생각을 계속 들지만, 이런 자리가 지속적으로 있었으면 좋겠다라는 생각이 들고, JCO 운영진 여러분들 정말 고생하셨습니다.(이분들 정말 고생하셨습니다. 전부 자원봉사라고 보시면 된다는…)
클라우드의 불편한 진실…
우승님이 빅 데이터의 불편한 진실(
http://kimws.wordpress.com/2012/02/11/%EB%B9%85%EB%8D%B0%EC%9D%B4%ED%84%B0big-data%EC%9D%98-%EB%B6%88%ED%8E%B8%ED%95%9C-%EC%A7%84%EC%8B%A4/
) 이라는 멋진 글을 쓰신 걸 읽고 감동 받아서, 저는 클라우드에 대한 나름의 생각을 정리해보려고 합니다.(그래서 제목도 카피를 …)
빅 데이터 처럼 여기저기서 클라우드를 외치고 있고, 일반인의 대부분은 Storage Service 라고 생각하고 있지만, 여기서의 내용은 주로 IaaS 와 PaaS 수준까지만 얘기를 하겠습니다.(사실 이것도 말할 정도도 아니구요.)
저는 주변에 “클라우드를 쓰지 왜 서버를 사느냐?” 라고 항상 말하는 등의 클라우드 빠돌이라고 말할 정도로 클라우드에 대한 애정이 많습니다. 사실 아직도 많고, 여전히 클라우드로 가는 커다란 흐름은 꼭 주시해야 하고, 그 방향이 맞다고 생각합니다.
보통 개발자의 입장에서 클라우드 특히 IaaS를 말하면, 가상화에 대해서 떠올리게 됩니다. 그런데, AWS등의 기업은 모르겠지만, 일반적인 기업이 가상화를 서비스에 사용하려고 하면 다음과 같은 문제가 발생하게 됩니다.
1. 물리 서버의 장애, 패치등으로 가상 서버를 사용할 수 없는 케이스가 종종 생긴다.
- 당연한 얘기지만, 믈리 서버의 패치나, 장애등으로 가상화 서버를 사용할 수 없는 경우가 생깁니다. 얼마전에 AWS의 보안 패치로 인해서 가상 서버들을 리부팅 해야했던 사건(?) 이 대표적인 예라고 할 수 있습니다. 그리고 가상화 서버를 운영하는 업체 입장에서 보면, 기술력이 부족하면, 가상화 서버 관리 때문에 해당 서버들을 사용하기 어려운 상황이 종종 생깁니다.
2. 특정 타입의 가상화 서버들이 몰리면 전체적으로 서버의 성능이 저하됩니다.
- 당연한 얘기지만, 가상화는 서버의 자원을 효율적으로 사용하기 위해서 적용되는 것입니다. CPU, I/O, Memory 등, 어떤 서버는 CPU만 많이 쓰고, 어떤 서버는 I/O(웹서버)만 많이 쓴다면 이런 서버들이 한군데에 고루 고루 섞이면, 적절한 성능이 나오겠지만, 어떤 서버가 어디로 할당될지 모르는 상황에서 I/O가 많은 서버들끼리 한 곳으로 가거나, CPU만 많이 쓰는 서버들이 모이게 되면, 성능의 저하가 일어나게 됩니다. 또한, 클라우드 벤더등은 어느 정도 적절한 서버 사양이나, 가상화 서버 수가 예상이 되겠지만, 처음 적용하는 업체들은 많은 시행 착오를 하게 될 것 같습니다.
그래서 이런 저런 이유로, 많은 기업이 성공적으로 클라우드로 이동하고 있고, 이동하는 중이지만( Netflix) 클라우드로 이동했던 업체들이 다시 일반 서버로 돌아오는 케이스도 많습니다. 또한 특정 업체들은 가상화를 제외하고, 물리 서버 팜을 구성하고 이를 돌려쓰는 방안에 대해서 고민하는 업체들이 많더군요. 클라우드가 꼭 가상화를 포함할 필요는 없으니…
그리고 사실 AWS를 사용하는 것만으로 Lock-in 이 되는 걸 피하기가 어렵습니다. 아마존의 특별한 서비스를 사용한다면, 그냥 100% 이미 Lock-In이 된 것이고, AWS API만 이용하더라도 어느 정도 Lock-In이 되었다고 봐야할 듯 합니다. 그래서 차후에 후발주자나 오픈 소스에서는, 아마존의 서비스를 사용하더라도 같은 API 기반에 오픈소스나 이동할 수 있는 방안이 제공될 듯 합니다.( 예를 들자면, 오픈소스로, 아마존 Queue 서비스와 같은 기능을 구축한다든지…) 즉, PasS 서비스등을 이용하게 되면, 어쩔 수 없게 Lock-In이 디폴트 속성으로 딸려오게 됩니다. 예를 들어 Google App Engine으로 서비스를 하는데, 구글이 사용료를 올리면, 다른 서비스로 옮기기 매우 힘들껍니다.
그리고 아마존 AWS를 사용하기가 어렵습니다. 많이 써보신 분들의 얘기를 들어보면, 공통적으로 여러가지 장애가 있고, 원인을 찾기 힘들때가 많다라든지, 실제 물리 서버들을 쓸 때는 쉽게 해결 할 수 있는 것들을, AWS에서는 쓸 수가 없거나 환경이 달라서 힘들다 라는 얘기들을 듣게 됩니다.
결정적으로, Startup 에게 기존의 클라우드 서비스는 비쌉니다. 저도 몇몇 Startup 분들에게 들고, 계산해봐서 알게 된 것이지만, Startup은 기본적으로 돈이 부족합니다. 즉, 돈을 인력과 시간을 들여서, 처리하게 되는데, 아마존 AWS등의 클라우드 서비스를 쓰게되면 한달 서버비만, 감당할 수 없는 돈이 나오게 됩니다. 서버 몇대로 거의 2배 이상의 운영비가 차이가 난다고 하더군요. 즉, StartUp 이라면 그냥 서버 사서, 몸빵을 하시는게 돈을 아끼게 됩니다.
클라우드가 항상 강점을 가지는 부분은 순간적으로 서버가 많이 필요할 때, 예측 하기 어려울 때가 아닐까 싶습니다. 하루 이틀 잠시 쓰고 반납을 해야하기에는 지금의 클라우는 어떻게 보면 정말 좋은 툴입니다. 즉, 클라우드의 최대 장점은 On-Demand 에 바로 바로 대응이 가능하다 이지 않을까 싶습니다.
불편한 진실이라는 이름으로, 남들이 다 아는 얘기를 블라블라 하게 되었는데 클라우드로의 전향이라는 큰 흐름은 바뀌지는 않을꺼라는 생각이 듭니다. 빅 데이터에 대한 대비가 되어 있지 않아서, 빅 데이터에 수 많은 시행 착오를 겪어야 하는 것 처럼, 우리는 클라우드에 대해서도 대비가 되어 있는 기업이 별로 없는 듯 합니다. 자, 클라우드에 대해서 다들 삽질한 준비가 되어 있는지 우리 모두 돌이켜보면 좋을듯 합니다.
아주 간단한 띄워쓰기 교정 아이디어와 테스트
자주 참고하는 블로그인
http://freesearch.pe.kr/
의 고감자님이 띄워쓰기 교정을 간단하게 만드시겠다라는 글을 보고, 간단하게 만들어 볼 수 있지 않을까 라는 생각이 들었다.
처음 생각한 것은, 단어 사전을 구축하고, 어미/어간을 분석해서 조사 뒤에서 끊어주면 되지 않게냐라는 생각이 들었는데, 이러면, 형태소 분석기가 필요하다. -_-(덜덜덜, 이게 핵심이 될듯) 그러다가, 빅데이터 시대에, 메모리에 웬만한 데이터를 다 올리면 간단하게 만들 수 있지 않을까?( 어려운 지식은 모두 제외하고 -_-) 라는 생각이 들어서, 간단하게 만들어보았다. 오늘 생각해서 오늘 몇시간 만에 만들었으니, 어려운 건 아님… -_-(어려운건 못만들어요.)
일단 생각의 아이디어의 핵심은 trie 자료구조와 띄워쓰기 용례사전이다. 어떤 아이디어인가 하면, 신문의 사설 데이터들을 요새는 쉽게 구할 수 있는데, 이를 메모리에 다 올려놓고, 최장일치로 일치하는 부분을 찾고, 이에 실패하는 부분에서 띄워주면 띄워쓰기가 되지 않을까라는 심플한 아이디어였다. -_-
위와 같이 trie로 저장되어 있을때 “한국민은한다” 라고 되어 있으면 한국민은 에서 최장일치로 발견이 되고, “한국민은한” 은 일치하지 않으므로, 여기서 띄워쓰기를 해주면 된다라는 간단한 아이디어이다. 그리고 이를 위한 것들이 다음과 같이 필요했다.
1. trie 자료 구조
2. 용례 사전 구축
위의 두 가지를 어떻게 해결해야 할까? 1번의 경우 직접 코딩을 하는 방법도 있었지만, 그러면 실제로 시간을 너무 많이 쓸 거 같아서, 일단은 패스를 하고 trie 라이브러리를 찾아보았다. 인터넷 서핑중에 rein 님 블로그에서 좋은 trie 라이브러리를 찾을 수 있었다.(
http://rein.kr/blog/archives/1443
)
DASTrie 라는 것인데,
http://www.chokkan.org/software/dastrie/
들어가는 사전은 사전순으로 정렬되어야 한다.(이거 몰라서 잠시 삽질을…)
이제 용례 사전의 구축의 경우, 신문 사설이 생각이 났다. 신문 사설의 경우, 논술등에서도 많이 참고하므로, 띄워쓰기가 잘 되어 있을 것이고, 신문사 등에 쉽게 크롤링이 되지 않을까 싶어서였다. 그리고 샘플을 조금 띄어 고치기 시작했는데, 이제부터 삽질이 시작되었다. 머리 속으로 명확한 알고리즘을 만든것이 아니었고, 또한 DAStrie의 특성이 내가 생각한 것들과 달라서( 정확히는 내가 trie를 잘못 이해해서) 좀 삽질을 하게되었다.
아이디어가 동작하는가를 검증하는게 주 목표여서 코드를 그냥 대충 짜고 정리도 안되어있다. (알고리즘은 좀 고민할걸 T.T)
#include <fstream>
#include <iostream>
#include <string>
#include <dastrie.h>
typedef dastrie::builder<char*, int> builder_type;
typedef dastrie::trie<int> trie_type;
typedef builder_type::record_type record_type;
#include "record.h"
int get_code_size( char data )
{
unsigned char bit_mask = 0x80;
int shift_count = 0;
if( (data & bit_mask) == bit_mask )
{
for( ; shift_count < 8; shift_count++ )
{
if( 0 == ( data & ( bit_mask >> shift_count ) ) )
{
break;
}
}
}
else
{
return 1;
}
return shift_count;
}
int main(int argc, char *argv[])
{
try {
// Build a double-array trie from the records.
builder_type builder;
builder.build(records, records + sizeof(records)/sizeof(records[0]));
// Store the double-array trie to a file.
std::ofstream ofs("sample.db", std::ios::binary);
builder.write(ofs);
ofs.close();
} catch (const builder_type::exception& e) {
// Abort if something went wrong...
std::cerr << "ERROR: " << e.what() << std::endl;
return 1;
}
// Open the trie file.
std::ifstream ifs("sample.db", std::ios::binary);
if (ifs.fail()) {
std::cerr << "ERROR: Failed to open a trie file." << std::endl;
return 1;
}
// Read the trie.
trie_type trie;
if (trie.read(ifs) == 0) {
std::cerr << "ERROR: Failed to read a trie file." << std::endl;
return 1;
}
char buffer[256];
char showbuffer[256];
char blankbuffer[256];
char *start_ptr = buffer;
char *code_ptr = buffer;
char *copy_ptr = showbuffer;
memset( showbuffer, 0, 256 );
memset( blankbuffer, 0, 256 );
std::cin.getline( buffer, sizeof(buffer)-1 );
int size = strlen( buffer );
int count = 0;
bool flag = false;
bool pass_flag = false;
for( int i = 0; i < size; )
{
int code_size = get_code_size( *(start_ptr+count) );
if( code_size == 1 && *(start_ptr+count) == ' ' )
{
memset( blankbuffer, 0, 256 );
memcpy( copy_ptr, start_ptr + count, code_size );
copy_ptr += code_size;
i += code_size;
start_ptr += count;
start_ptr += code_size;
count = 0;
flag = false;
continue;
}
else
{
memcpy( blankbuffer, start_ptr, count+code_size );
int ret = trie.in( blankbuffer );
std::cout << blankbuffer << ": " << ret << "," << code_size << "," << count << "," << i << "," << size << std::endl;
if( ret == 0 && flag )
{
*copy_ptr++ = ' ';
memset( blankbuffer, 0, 256 );
start_ptr += count;
count = 0;
flag = false;
}
else if( ret == 1 )
{
flag = true;
}
}
memcpy( copy_ptr, start_ptr + count, code_size );
count += code_size;
std::cout << copy_ptr << std::endl;
copy_ptr += code_size;
i += code_size;
}
std::cout << "Result: " << showbuffer << std::endl;
return 0;
}
용례는 웹페이지를 다운 받아서, 사전 부분만 추출해서 이를 가공했다.
record_type records[] = {
{ "16조원이",1 },
{ "17조원이",2 },
{ "1만4525명",3 },
{ "1만6242명으로",4 },
{ "1만8170명",5 },
{ "2011년판",6 },
{ "2457만명이다",7 },
{ "25%로",8 },
{ "25만원씩",9 },
{ "2만2250명",10 },
{ "2배",11 },
{ "30만원씩",12 },
{ "3배다",13 },
...
...
{ "할당제를",458 },
{ "합쳐",459 },
{ "해도",460 },
{ "해보려면",461 },
{ "해에",462 },
{ "허약한",463 },
{ "현대",464 },
{ "현재",465 },
};
이제 간단하게 테스트를 해보면
입력문장: “국민이 정치에둘리지않으려면 지금이 어느 때이고 여기가 어느세상인지를 정확하게알아야한다”
결과: “국민이 정치에 둘리지 않으려면 지금이 어느 때이고 여기가 어느 세상인지를 정확하게 알아야 한다”
잘나오는 것 같이 보이지만, 아직 문제가 많이 있다.
1. 용례에 없는 부분은 그냥 하나로 나온다. -_-, 사실 이부분은 용례가 많아지면, 어느정도 충분히 커버가 가능할 듯 하다.
2. “아버지가방에들어가신다”의 경우 “아버지가 방에 들어가신다” 와 “아버지 가방에 들어가신다” 어느것이 옳은 것일까?
-> 여기서는 최장일치이므로 “아버지가 방에 들어가신다” 가 된다.
3. 특수문자나 이런 부분도 아직 처리가 미흡하다.(버그가 많다)
그냥 갑자기 든 생각을 구현해 본것이라서 완전 엉터리지만, 수많은 인터넷 데이터를 용례 사전으로 만들고 속도를 빠르게 하면, 상당히 뛰어난 성능이 나오지 않을까 하는 혼자만의 생각을 해본다. 클라우드랑 연동하고 용례 사전이 특정 영역에 맞춰지면, 과학분야와 문학분야에 서로 다른 띄워쓰기를 해줄수도… 그리고 단순 트라이 매칭이므로, 용례 사전만 바뀌면, 외국어도 가능할 듯 하다.
그리고 trie 자료구조가 딱 내가 원하는 형태가 아니라 코드가 복잡해지고 거의 그냥 맵처럼 되어버렸는데, 이쪽 코드를 새로 짜서, 실시간 추가 가능하고 띄워쓰기에 맞게 코드를 만들 필요가 있을듯하다.
간단한 thrift를 이용한 cassandra 예제
간단한 thrift를 이용한 카산드라 예제 흐음…
create keyspace BLOG with strategy_options={replication_factor:1} and placement_strategy = ‘org.apache.cassandra.locator.SimpleStrategy’;
create column family category with comparator=UTF8Type
and default_validation_class=UTF8Type and key_validation_class=UTF8Type
and column_metadata=[
{column_name: category_id, validation_class: UTF8Type},
{column_name: category_name, validation_class: UTF8Type}];
create column family posts with comparator=UTF8Type
and default_validation_class=LongType and key_validation_class=LongType
and column_metadata=[
{column_name: id, validation_class: UTF8Type},
{column_name: title, validation_class: UTF8Type},
{column_name: post, validation_class: UTF8Type},
{column_name: category_id, validation_class: UTF8Type, index_name: category_index, index_type: 0},
{column_name: post_date, validation_class: LongType}];
create column family comments with comparator=UTF8Type
and default_validation_class=LongType and key_validation_class=LongType
and column_metadata=[
{column_name: post_id, validation_class: UTF8Type, index_name: post_index, index_type: 0},
{column_name: comment, validation_class: UTF8Type},
{column_name: comment_date, validation_class: LongType}];
<pre>import java.io.UnsupportedEncodingException;
import java.nio.ByteBuffer;
import java.util.List;
import java.util.Collections;
import org.apache.cassandra.thrift.Cassandra;
import org.apache.cassandra.thrift.Column;
import org.apache.cassandra.thrift.ColumnOrSuperColumn;
import org.apache.cassandra.thrift.ColumnParent;
import org.apache.cassandra.thrift.ColumnPath;
import org.apache.cassandra.thrift.ConsistencyLevel;
import org.apache.cassandra.thrift.InvalidRequestException;
import org.apache.cassandra.thrift.NotFoundException;
import org.apache.cassandra.thrift.SlicePredicate;
import org.apache.cassandra.thrift.SliceRange;
import org.apache.cassandra.thrift.KeyRange;
import org.apache.cassandra.thrift.KeySlice;
import org.apache.cassandra.thrift.TimedOutException;
import org.apache.cassandra.thrift.UnavailableException;
import org.apache.thrift.TException;
import org.apache.thrift.protocol.TBinaryProtocol;
import org.apache.thrift.protocol.TProtocol;
import org.apache.thrift.transport.TFramedTransport;
import org.apache.thrift.transport.TSocket;
import org.apache.thrift.transport.TTransport;
public class CClient
{
public static void main(String[] args)
throws TException, InvalidRequestException, UnavailableException, UnsupportedEncodingException, NotFoundException, TimedOu
tException
{
TTransport tr = new TFramedTransport(new TSocket("10.64.81.181", 9160));
TProtocol proto = new TBinaryProtocol(tr);
Cassandra.Client client = new Cassandra.Client(proto);
tr.open();
String key_user_id = "1";
// insert data
long timestamp = System.currentTimeMillis();
client.set_keyspace("BLOG");
ColumnParent parent = new ColumnParent("category");
Column idColumn = new Column(toByteBuffer("category_id"));
idColumn.setValue(toByteBuffer("3"));
idColumn.setTimestamp(timestamp);
client.insert(toByteBuffer("3"), parent, idColumn, ConsistencyLevel.ONE);
Column nameColumn = new Column(toByteBuffer("category_name"));
nameColumn.setValue(toByteBuffer("NoSQL"));
nameColumn.setTimestamp(timestamp);
client.insert(toByteBuffer("3"), parent, nameColumn, ConsistencyLevel.ONE);
ColumnPath path = new ColumnPath("category");
// read single column
path.setColumn(toByteBuffer("category_id"));
System.out.println(client.get(toByteBuffer(key_user_id), path, ConsistencyLevel.ONE));
// read entire row
SlicePredicate predicate = new SlicePredicate();
SliceRange sliceRange = new SliceRange(toByteBuffer(""), toByteBuffer(""), false, 10);
predicate.setSlice_range(sliceRange);
// predicate.addToColumn_names( ByteBuffer.wrap("category_id".getBytes("UTF8")));
// predicate.addToColumn_names( ByteBuffer.wrap("category_name".getBytes("UTF8")));
KeyRange keyRange = new KeyRange();
keyRange.start_key = ByteBuffer.allocate(0);
keyRange.end_key = ByteBuffer.allocate(0);
keyRange.count = 2;
List<KeySlice> results = client.get_range_slices( parent, predicate, keyRange, ConsistencyLevel.ONE);
for( KeySlice keySlice : results ){
List<ColumnOrSuperColumn> columns = keySlice.getColumns();
for (ColumnOrSuperColumn result : columns)
{
Column column = result.column;
System.out.println(toString(column.name) + " -> " + toString(column.value));
}
}
tr.close();
}
public static ByteBuffer toByteBuffer(String value)
throws UnsupportedEncodingException
{
return ByteBuffer.wrap(value.getBytes("UTF-8"));
}
public static String toString(ByteBuffer buffer)
throws UnsupportedEncodingException
{
byte[] bytes = new byte[buffer.remaining()];
buffer.get(bytes);
return new String(bytes, "UTF-8");
}
}
[Cassandra] DataSax의 OpsCenter 설치 방법
Cassandra 모니터링 툴중에 DataSax에서 개발한 OpsCenter 라는 툴이 있습니다. Community 버전과, Enterprise 버전이 있고, Community 버전의 경우는 감사하게도 공짜입니다.
간단하게
http://www.datastax.com/docs/opscenter/install_opscenter#opscenterd-install
이 페이지에 설치내용이 있는데, 설치는 굉장히 쉽습니다.
다음과 같은 순서를 이용합니다.
1. OpsCenter Download
-> wget http://downloads.datastax.com/community/opscenter.tar.gz
2. 압축 해제
-> tar zxvf opscenter.tar.gz
3. conf 수정
-> vi conf/opscenterd.conf
-> seed 주소와 웹서버 bind 주소 정도만 바꿔주시면 될듯 합니다.
[webserver]
port = 8888
interface = 0.0.0.0
4. setup
-> ./bin/setup.py
5. 실행
-> ./bin/opscenter
그리고 http://서버주소:8888/ 로 접속하면 opscenter 가 실행되게 됩니다.
아주 간단한 java 명령들
자바를 너무 몰라서 기록해 둡니다.
javac -d . net/sjava/cassandra/CassandraBlogExample.java
jar cvf cassandra_example.jar net
java -cp ./cassandra_example.jar net.sjava.cassandra.CassandraBlogExample
간단한 lucene demo 실행
lucene version: 3.5.0
tar zxvf lucene-3.5.0.tgz
export CLASSPATH=~/repo/charsyam/lucene-3.5.0/lucene-core-3.5.0.jar:~/repo/charsyam/lucene-3.5.0/contrib/demo/lucene-demo-3.5.0.jar
time java org.apache.lucene.demo.IndexFiles -docs docs/
java org.apache.lucene.demo.SearchFiles

