2016년 5월 4일 수요일

Aliyun(Alibaba cloud) vs AWS vs NCLOUD(Naver Cloud)

AWS를 기준으로 평가한다.

1. NCLOUD
장점:
  • 한국어로 한국인 지원해준다.
  • 가격이 AWS 직관적이고 20~30% 정도 싼 듯 하다.
  • 안정성은 저장하는 S3같은 건 불안정하고 (지금은 개선됐다고 하나..) ECS는 쓸만하다.
단점:
  • API를 지원하는 프로그램 언어가 턱없이 적다.
  • 확장성 면에서 AWS에 비해 턱없이 부족하다.

2. Aliyun
장점
  • AWS 대비 많이 싸다. 특히 CDN은 가격은 정말 싸다.
  • 안정성은 그럭 저럭 쓸 만하다.
  • AWS만큼 지원하는 API언어가 많다. 심지어 golang도 있다~
  • S3같은 OSS는 초창기 S3와 비슷해서 S3를 쓰다가 OSS를 쓰는데 있어 불편함이 없다.
단점
  • AWS비해 확장성쪽 기능은 부족하다.
  • 가끔 중국어가 나와서 구글의 translation 기능이 필요하다.
  • OSS에 있는 파일을 외부에서 직접 호출할 때 가끔 session close error가 발생한다. CDN을 사용하는게 필수 인 듯 하다.

결론은... 스타트업 입장에서는 AWS를 쓰고 NCLOUD를 쓸 바에는 Aliyun을 쓰겠다. 일본 region도 조만간 오픈한다고 하니..

즉.. AWS에서 교육받고 실질적으로는 Aliyun을 쓰는 걸로... 가격이 깡패이므로..

2016년 4월 29일 금요일

javascript, css의 minify와 concat을 위한.. gulp vs grunt

web 환경.

angularjs 1.2.28 (angularjs 2로는 공부할 시간이 없다는 핑계로 미루는 중)

웹 최적화가 필요함.
알리윤 홍콩 리젼에 서버를 두고 테스트한 결과.. 웹 페이지가 보이기 까지 4~5초 정도 걸림.
문제는 많은 css파일과, javascript들..

grunt : 마치 autoconf를 이용해서 makefile 만드는 듯한 느낌.. minify를 위한 grunt라는 새로운 언어와 구조를 공부해야 하는 느낌.

gulp : 직접 Makefile을 만드는 느낌. 별거 없음. node.js깔고 node.js를 이용해서 스크립트 만듬.

grunt

장점
- 구조적으로 유지 보수하기가 쉬어 보임.

단점
- 공부하는데 익숙해지는데 시간과 노력이 필요함.

gulp
장점
- 배우는 데 10분 정도 걸림. 시행 착오 겪으면 한시간 정도.
(css, javascript 파일을 path/**/* 이런 식으로 쓰면 순서가 꼬여서 동작을 안 할 수 있음을 알고 파일 하나하나 적어줌) 

단점
- 파일이 커지고 소스가 커지면 유지보수할 때 문제가 생길 확률이 높아진다.


일단 초기에는 gulp가 최고이나.. 나중에 프로젝트가 커지고 협업하는 사람들이 아주 많아지면 grunt로 가야하지 않을까 하는 생각을 하게 된다.

2015년 5월 1일 금요일

solr admin에 password 추가하기

https://wiki.apache.org/solr/SolrSecurity

여기서 

Common servlet container example

Jetty realm example

이 두개를 따라 하면 된다.

<jetty.xml>
    <Call name="addBean">
      <Arg>
        <New id="DeploymentManager" class="org.eclipse.jetty.deploy.DeploymentManager">
          <Set name="contexts">
            <Ref id="Contexts" />
          </Set>
          <Call name="setContextAttribute">
            <Arg>org.eclipse.jetty.server.webapp.ContainerIncludeJarPattern</Arg>
            <Arg>.*/servlet-api-[^/]*\.jar$</Arg>
          </Call>
          
          
          <!-- Add a customize step to the deployment lifecycle -->
          <!-- uncomment and replace DebugBinding with your extended AppLifeCycle.Binding class 
          <Call name="insertLifeCycleNode">
            <Arg>deployed</Arg>
            <Arg>starting</Arg>
            <Arg>customise</Arg>
          </Call>
          <Call name="addLifeCycleBinding">
            <Arg>
              <New class="org.eclipse.jetty.deploy.bindings.DebugBinding">
                <Arg>customise</Arg>
              </New>
            </Arg>
          </Call>
          -->
          
        </New>
      </Arg>
    </Call>
    <Call name="addBean">
      <Arg>
        <New class="org.eclipse.jetty.security.HashLoginService">
          <Set name="name">Test Realm</Set>
          <Set name="config"><SystemProperty name="jetty.home" default="."/>/etc/realm.properties</Set>
          <Set name="refreshInterval">0</Set>
        </New>
      </Arg>
    </Call>
    
    <Ref id="DeploymentManager">
      <Call name="addAppProvider">
        <Arg>
          <New class="org.eclipse.jetty.deploy.providers.ContextProvider">
            <Set name="monitoredDirName"><SystemProperty name="jetty.home" default="."/>/contexts</Set>
            <Set name="scanInterval">0</Set>
          </New>
        </Arg>
      </Call>

    </Ref>

<web.xml>
  <welcome-file-list>
    <welcome-file>admin.html</welcome-file>
  </welcome-file-list>

  <security-constraint>
    <web-resource-collection>
      <web-resource-name>Solr authenticated application</web-resource-name>
      <url-pattern>/*</url-pattern>
    </web-resource-collection>
    <auth-constraint>
        <role-name>admin</role-name>
    </auth-constraint>
  </security-constraint>
  <login-config>
    <auth-method>BASIC</auth-method>
    <realm-name>Test Realm</realm-name>
  </login-config>
    
</web-app>

<realm.properties>
admin: 12345, admin

암호 부분을 강화하려면..
여기에 있는 방법대로..
$ cd ./lib
$ java -cp jetty-util-8.1.10.v20130312.jar org.eclipse.jetty.util.security.Password admin 12345
12345
OBF:19bv19bx19bz19c119c3
MD5:827ccb0eea8a706c4c34a16891f84e7b
CRYPT:adpliAB3dA.06

<realm.properties>
adminMD5:827ccb0eea8a706c4c34a16891f84e7b, admin


Solr ubuntu 설치

Solr를 ubuntu에 설치해보자. 형태소 분석기는 은전한닢을 사용한다. 요즘 핫한 건 elastic search이긴 하나 Solr를 선택한 이유는 admin이 보다 편리하게 되어 있고 예제도 아직은 elastic search보다 많기 때문이다. 결정적으로 분산 Indexing을 많이 안 하지 않을까? 해도 Solr에서 제안하는 Zookeeper를 사용한 분산 Indexing을 써도 돼지 않을까? 싶었고 Solr에서 elastic search로 옮기는 예제는 많은데 반대는 거이 찾아보기 힘들었다. 나중에 필요하면 elastic search로 옮겨가는 걸로...

즉, Solr를 선택한 이유는 초기 공부 및 도입 비용이 elastic search와 비교해 봤을 때 적어 보였기 때문이다.

형태소 분석기 은전한닢은 다음 URL를 보고 설치
http://eunjeon.blogspot.kr/

분석기
wget https://bitbucket.org/eunjeon/mecab-ko-lucene-analyzer/downloads/mecab-ko-lucene-analyzer-0.17.0.tar.gz
설치 URL
https://bitbucket.org/eunjeon/mecab-ko-lucene-analyzer/src/2397c65dccf333eec2613448c32c2694092f09b4/README.md?at=release-0.17.0

mecab-ko
wget https://bitbucket.org/eunjeon/mecab-ko/downloads/mecab-0.996-ko-0.9.2.tar.gz
설치 URL
https://bitbucket.org/eunjeon/mecab-ko

mecab-ko-dic
wget https://bitbucket.org/eunjeon/mecab-ko-dic/downloads/mecab-ko-dic-2.0.0-20150517.tar.gz
설치 URL
https://bitbucket.org/eunjeon/mecab-ko-dic

mecab-java
wget https://bitbucket.org/eunjeon/mecab-java/downloads/mecab-java-0.996.tar.gz

팁이라고 하면.. mecab-ko 는 최신거 사용
mecab-ko-dic은 알파 아닌 최신거 사용

설치할 때 에러나는 경우
1. mecab-0.996-ko-0.9.2에서 ./configure  할 때 에러난 경우
>> sudo apt-get install g++
2. he program 'make' is currently not installed.  To run 'make' please ask your administrator to install the package 'make'
라고 에러난 경우
>> sudo apt-get install build-essential
3. /usr/local/libexec/mecab/mecab-dict-index: error while loading shared libraries: libmecab.so.2: cannot open shared object file: No such file or directory
라고 에러난 경우
>> vi ~/.bashrc 혹은 vi ~/.bash_profile 에 아래 거 추가
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH
4. mecab-java 컴파일 하다가
unmappable character for encoding ASCII
라고 에러나면
>> export JAVA_TOOL_OPTIONS=-Dfile.encoding=UTF8



설치 시작하기 은전한닢이 solr 5 번전을 지원 못 하기 때문에 4.10.4로 설치

$ wget http://mirror.apache-kr.org/lucene/solr/4.10.4/solr-4.10.4.tgz
$ tar xvzf solr-4.10.4.tgz
$ cd solr-4.10.4
$ ./bin/solr start

이제부터는 설정 및 스키마 추가등은 메뉴얼대로~

2015년 4월 28일 화요일

Spark ubunto에서 설치

Spark는 버클리 학생들이 아이디어를 제안해서 만들어진 프로젝트이다. 빠르게 버전업 되는 핫한 프레임워크이다. 단지 워낙 빠르게 버전업되고 만들어진지 얼마 안 돼다보니 안정화가 들 돼어 있다. 즉 버그가 많다. 그렇지만 큰 데이터를 분석할 때 그런 듯 싶고 우리가 쓰는 환경은 한 번에 최대 50Mbyte 정도의 데이터만 처리하면 돼기 때문에 In-memory에서 메모리가 깨지는 문제는 아직까진 발견할 수 없다. Gbyte단위로 분석하면 깨지지 않을까 추측을 해본다.

설치라고 해서 할 건 별로 없다. 실행 이미지가 들어 있기 때문이다.

아래주소로 방문해서
http://spark.apache.org/downloads.html

원하는 패키지를 다운 받는다.

wget http://apache.mirror.cdnetworks.com/spark/spark-1.3.1/spark-1.3.1-bin-hadoop2.6.tgz

$ tar xvzf spark-1.3.1-bin-hadoop2.6.tgz

$ cd conf/
$ cp spark-env.sh.template spark-env.sh
$ vi spark-env.sh

# 원하는 설정을 넣어주면 된다. 우리는 다음과 같이 넣었다.
export SPARK_WORKER_OPTS="-Dspark.worker.cleanup.enabled=true -Dspark.worker.cleanup.appDataTtl=3600"
export SPARK_MASTER_IP=192.168.0.1

export SPARK_WORKER_MEMORY=8g
export LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH

$ cp spark-defaults.conf.template spark-defaults.conf
$ vi spark-defaults.conf

# 여기에도 원하는 설정을 넣어주면 된다.
park.master    spark://192.168.0.1:7077
spark.default.parallelism   4

$ cp slaves.template slaves
$ vi slaves
# 노예들을 다 적어 주면 된다. 일할 서버 아이피들..
192.168.0.1
#192.168.0.2
#192.168.0.3

$ cd ..
$ ./sbin/start-all.sh

만약 다음과 같은 에러가 났다면..
Exception in thread "main" java.net.UnknownHostException: test: test: unknown error
        at java.net.InetAddress.getLocalHost(InetAddress.java:1484)
        at org.apache.spark.util.Utils$.findLocalIpAddress(Utils.scala:771)
        at org.apache.spark.util.Utils$.localIpAddress$lzycompute(Utils.scala:763)
        at org.apache.spark.util.Utils$.localIpAddress(Utils.scala:763)
        at org.apache.spark.util.Utils$.localIpAddressHostname$lzycompute(Utils.scala:764)
        at org.apache.spark.util.Utils$.localIpAddressHostname(Utils.scala:764)
        at org.apache.spark.util.Utils$$anonfun$localHostName$1.apply(Utils.scala:816)
        at org.apache.spark.util.Utils$$anonfun$localHostName$1.apply(Utils.scala:816)
        at scala.Option.getOrElse(Option.scala:120)
        at org.apache.spark.util.Utils$.localHostName(Utils.scala:816)
        at org.apache.spark.deploy.worker.WorkerArguments.<init>(WorkerArguments.scala:29)
        at org.apache.spark.deploy.worker.Worker$.main(Worker.scala:528)
        at org.apache.spark.deploy.worker.Worker.main(Worker.scala)
Caused by: java.net.UnknownHostException: anal01: unknown error
        at java.net.Inet4AddressImpl.lookupAllHostAddr(Native Method)
        at java.net.InetAddress$2.lookupAllHostAddr(InetAddress.java:907)
        at java.net.InetAddress.getAddressesFromNameService(InetAddress.java:1302)
        at java.net.InetAddress.getLocalHost(InetAddress.java:1479)

        ... 12 more

아래를 추가해주고
$ sudo vi /etc/hosts
127.0.1.1       test

다시 실행
$ ./sbin/start-all.sh


2014년 10월 6일 월요일

Install Graphite and statsd on Ubuntu 12.04 LTS

https://gist.github.com/bhang/2703599

여기에 있는 스크립트 대로 실행하고

sudo python manage.py syncdb

이거 실행할 때 에러가 나면..

/tmp/graphite_reqs.txt 파일에
django-tagging

이렇게된 부분을

django-tagging==0.3.1

이렇게 수정하고.

아래 부분을 다시 한 번 실행시키면 된다.
sudo pip install -r /tmp/graphite_reqs.txt

2014년 9월 26일 금요일

requirejs + angularjs 에서 requirejs 걷어내기와 grunt 적용하기

requirejs 걷어내는 이유


  • requirejs에서 제공하는 r.js를 사용하여 minify, gzip, versioning을 하면 오래 걸린다. 800초 정도. (1 core CPU, 2GB Memory).
  • concatenation이 안 된다. 이 부분은 우리 소스 구현 방식 때문인지 play!framework에서 제공된 r.js가 안 해주는지 아님 몰라서 못 하는 건지 모르지만 현재 안 되고 있다.
  • angularjs 개념도 어려운데 requirejs까지 넣었더니 이해를 못 하는 부분이 너무 많다. 이해하는데 시간도 부족하고 angualrjs만으로도 충분히 프로젝트를 진행시킬 수 있다는 판단이 들며 특히나 requirejs가 해주는 부분이 미약하다. 외부 library의 의존성 정도 유지 보수 하는 정도. 이것 또한 angularjs가 충분히 할 수 있다고 판단되어진다.

작업내용

index.scalar.html에 해당 js 파일을 모두 include 시킨다. 





여기서 /assets/admin/js/admin.js를 삭제하고 /assets/admin/js/app.js에 chucar.admin 모듈을 다음과 같이 선언해주고 그 모듈에 모든 서비스 관련 directives, services, controllers 등을 추가한다.












Grunt를 적용하는 이유

  • requirejs를 걷어 냄으로써 대신 minify, concatenation, gzip를 해주는 스크립트이다.

작업내용

node.js 설치

grunt 설치
$ npm install -g grunt-cli
$ npm install grunt --save-dev
$ npm init
--> 이 때 name을 js나 node로 넣지 말랜다. It's assumed that it's js, since you're writing a package.json file, and you can specify the engine using the "engines" field.
Gruntfile.js 파일 생성

grunt-contrib-uglify, grunt-contrib-concat 은 없기 때문에 다음과 같이 설치
npm install grunt-contrib-uglify --save-dev
npm install grunt-contrib-concat --save-dev