2013년 12월 19일 목요일

Managing Solr Cores

solr를 운영하다 보면 하나의 core 보다는 여러개의 core를 운영하는 경우가 많다. 여기서는 이러한 solr의 core를 쉽게 관리할 수 있는 방법을 다룬다.

core의 관리는 HTTP를 통해 이루어 지며 이러한 편리성은 다른 어플리케이션에 쉽게 이식될 수 있다. 또한 core 관리를 위한 특정 commad 수행시 적용을 위해 solr를 restart 하지 않고 runtime 상태에서 적용되게 할 수 있다.
이를 위해서는 solr home 디렉토리의 solr.xml 파일에서 persistent="false"로 설정이 되어야 한다.

아래는 core 관리를 위한 명령들이며, 모두 solr 서버를 재시작 하지 않고(on the fly) 적용할 수 있다.

STATUS


모든 core의 또는 특정 core의 상태를 확인할 수 있다.
  http://localhost:8983/solr/admin/cores?action=STATUS&core=core0

schema.xml, solrconfig.xml 등의 정보가 수정되었을 경우 reload 한다.

MERGE


Multi-core로 나뉘어진 인덱싱 데이터를 재인덱싱 하지 않고 single index로 merge 한다.
Before solr1.4
After solr3.3

위의 명령은 core1과 core2를 core0로 merge한다.
이 명령을 실행하기 이전에 core1과 core2에 대해 commit 명령이 호출되어야 한다. 이는 해당 core에 대해 merge 작업이 완료될 때까지 write를 막기 위해서 IndexWriter를 닫는 것이다. merge가 완료되면 core0에 대해 commit 명령을 호출함으로써 검색이 가능한 상태가 된다.

[INFO]
"The above command will merge the indexes of core1 and core2 into core0.
The path for this command is the 'adminPath' defined in solr.xml (default is /admin/cores).
Before executing this command, one must make sure to call commit on core1 and core2 (in order to close IndexWriter) and no writes should happen on core1 and core2 until the merge command completes. Failure to do so may corrupt the core0 index. Once the merge is completed, a commit should be called on core0 to make the changes visible to searchers."

   http://127.0.0.1:8983/solr2/jptr01/update?optimize=true

NOTE: In this example core0 must exist and have a compatible schema with core1 and core2. The 'mergeindexes' command will not create a new core named 'core0' if it does not already exist.

pyinstaller 사용하여 python .exe 파일 만들기

pyinstaller를 사용하면 python으로 작성한 스크립트를 .exe 형태로 실행가능하게 만들수 있다. 아래는 각각 console mode와 window mode의 .exe 파일 생성을 위한 사용예이다.

# Console Mode
python c:\pyinstaller-2.0\utils\Makespec.py --onefile --out=dist ProSolManager.py
# 아래는 multiprocessing.Manager() 를 사용할 경우사용. (onefile 옵션은 에러발생)
# python c:\pyinstaller-2.0\utils\Makespec.py --onedir --out=dist ProSolManager.py
python c:\pyinstaller-2.0\utils\Build.py dist\ProSolManager.spec

# Window Mode
python c:\pyinstaller-2.0\utils\Makespec.py --onefile --windowed --icon=.\icon\kipi.ico --out=dist ProSolManagerGui.py
# 위의 옵션 대신 아래 옵션도 사용가능
# python c:\pyinstaller-2.0\utils\Makespec.py --onedir --windowed --icon=.\icon\kipi.ico --out=dist ProSolManagerGui.py
python c:\pyinstaller-2.0\utils\Build.py dist\ProSolManagerGui.spec
copy icon output_dir
위의 옵션을 사용하면 스크립트에서 사용하는 라이브러리 들을 하나의 .exe로 만들어 준다.


pyinstaller를 사용하는 경우 다음 두 가지를 기억하자.

첫째, 스크립트 내에서 multiprocessing 모듈을 사용할 경우에는 아래와 같이 main 모듈의 if __name__=='__main__': 아래에 multiprocessing.freeze_support()를 명시해야 한다.
if __name__ == '__main__':
    # On Windows calling this function is necessary.
    if sys.platform.startswith('win'):
        multiprocessing.freeze_support()

둘째, 스크립트 내에서 import psycopg2 를 사용면서 동시에 multiprocessing을 사용하는 경우 .exe 실행시 fork로 생성된 프로세스에서 psycopg2를 찾지 못하는 ImportError가 발생되며, pyinstaller의 bug로 판단된다.
이를 회피하기 위해 psycopg2 패키지 전체("C:\Python26_64\Lib\site-packages\psycopg2")를 pyinstall에 의해 생성된 .exe 파일과 같은 폴더내에 위치시킨다.
그러면 꼼수이긴 하지만 ImportError를 회피할 수 있다.

Solrconfig Basic Setting

<lib>

solr에서 사용할 외부 라이브러리의 위치를 지정한다.

<dataDir>

Index data를 저장할 위치를 지정한다. Solr Home 아래의 ./data 디렉토리를 기본으로 사용하며, 이외에 다른 곳에 저장할 경우 사용한다.

<indexConfig> section

useCompoundFile
Index 파일의 압축여부를 지정한다. true일 경우 압축을 사용한다. 이경우 index size는 줄어들지만 performance가 감소할 수 있다.

ramBufferSizeMB
색인은 메모리에 색인을 구축하다가 일정 기준이 되면 파일에 write를 하게끔 되어 있으며, 이러한 과정을 반복하면서 색인이 진행된다.
이때 사용될 메모리의 크기를 지정한다. 색인이 지정된 크기에 도달하면 파일에 write한다.

maxBufferedDocs
ramBufferSizeMB와 유사한 기능을 수행하는 것으로서 메모리에서 색인될 수 있는 최대 문서수를 지정한다.
최대 문서수에 도달하면 파일에 write 한다.

mergeFactor
색인 파일은 segment 단위로 구성된다. 메모리에 색인된 내용이 파일에 write 될 경우 하나의 segment가 생성된다.
이러한 segment가 merge되는 기준을 지정한다. default는 10으로 10개의 segment가 생성되면 merge가 수행되어 하나의 segment로 통합된다.

<updateHandler> section

listener
색인 완료단계에서는 commit 또는 optimize 명령이 수행되게 되있다. 이러한 명령 이후에 추가적으로 수행하고자 하는 프로그램 및 스크립트 등을 등록한다.
아래는 간단한 사용예제이다.

<query> section

maxBooleanClauses
일반적으로 query에서 사용되는 최대 색인어의 수를 지정하는 것으로서 주로 wildcard 또는 range query 등이 영향을 받는다.
너무 과도한 질의어로(또는 악의적인 공격) 인한 검색엔진의 오버헤드를 막을 수 있는 방안이 될 수 있다.
검색 query에 사용된 키워드의 수가 이 값을 초과하면 오류가 발생된다. 예를들어 app* 와 같은 질의어의 경우 app로 시작되는 색인어의 개수가 질의어에 포함된 키워드의 총 개수가 된다.

Cache
filterCache : filterquery(fq)나 facet에 사용된 query에 대한 document id의 unordered set을 저장한다.
queryResultCache : query에 일치하는 document id의 ordered list를 cache한다.
documentCache : disk에 저장된 lucene document object(stored fields for each document)를 cache한다. (참고 - http://solr.pl/en/2011/08/29/optimization-document-cache/)

(참고 - http://solr.pl/en/2011/02/07/optimization-filter-cache/)

enableLazyFieldLoading
true로 설정될 경우 query 요청시 fl 파라메터에 없는 field는 lazy load를 사용한다. 즉, 사용자가 요청한 field 만 index로 부터 fetch하여 documentCache에 놓고, 나머지 field는 다음에 요청이 있을 경우에 fetch 한다. large text stored field 와 같은 경우 대부분 필요시에만 요구하기 때문에 이를 사용할 경우 속도가 향상된다.

queryResultWindowSize
이 값은 검색결과를 가져올때 index로 부터 몇개의 document를 fetch 할지를 지정한다.  query 요청시 rows 파라메터에 사용된 값과 관련이 깊으며, queryResultCache의 각 entry마다 저장되는 문서의 수를 결정한다. 사용자가 검색결과에 대해 paging 기능을 많이 사용할 경우 이 값을 크게 설정하면 도움이 된다. 예를들어, 검색결과를 100건씩 보여준다고 가정할때, 만약 사용자가 100건 이후의 결과에 대해서도 조회를 많이 한다면 이 값을 100보다 크게 설정하면 된다.
(참고 - http://solr.pl/en/2011/01/10/optimization-query-result-window-size/)

그 밖에 보다 자세한 사항은 http://wiki.apache.org/solr/SolrConfigXml를 참조한다.

2013년 12월 18일 수요일

python encoding 변환시 지원되지 않는 character 무시하기

encoding을 변환하고자 하는 스트링이 해당 encoding에서 지원하지 않는 character를 포함하고 있을 때 아래와 같이 오류가 발생되는 경우가 있다.

original string은 UTF-8로 encoding되어 있으며, 이를 euc_kr로 변환하고자 한다

original_str.decode('utf-8').encode('euc_kr')
original_str = "레르 리키드 쏘시에떼 아노님 뿌르 레�드 에렉스뿔라따시옹 데 프로세데 조르즈 클로드"

UnicodeEncodeError: 'euc_kr' codec can't encode character u'\ufffd' in position 20: illegal multibyte sequence

print a.decode('utf-8').encode('euc_kr','replace')
레르 리키드 쏘시에떼 아노님 뿌르 레?드 에렉스뿔라따시옹 데 프로세데 조르즈 클로드
이때 위와 같이 encode 옵션으로 'replace' 또는 'ignore' 옵션을 사용하면 해당 character를 무시하고 encoding을 변환할 수 있다.

2013년 12월 16일 월요일

Solr Schema.xml

Schema.xml 파일에는 색인 및 검색을 위해 필요한 필드에 대한 정보를 정의한다.
개략적인 구조는 다음과 같다.


위에서 정의한 것 이외에도 <dynamicField> 등 몇가지가 더 있지만 자주 사용되지 않으며 자세한 설명은 http://wiki.apache.org/solr/SchemaXml를 참고한다.


Attributes for fields

Attributes Name
Description
Values
namefield name
typefield type name - <types> 섹션에 정의된 <fileldType> 중 하나를 갖는다.
indexed검색이 가능하게끔 index 할지의 여부를 지정한다.true or false
stored데이터를 색인파일에 저장할지의 여부를 지정한다.true or false
multiValuedmultiple value를 포함하는지의 여부를 지정한다.true or false
omitNorms
field에 대해 index 시에 length normalization과 boosting을 할지의 여부를 지정한다. true로 지정된 경우 memory를 절약할 수 있다. (주로 full-text field에 대해서 norms를 적용한다.)
true or false
termVectorsterm vector를 저장할지의 여부를 지정한다. MoreLikeThis(유사문서검색) 기능을 이용할 경우에 사용될 수 있다.true or false
termPositionstermVectors와 함께 사용되며 색인어의 위치 정보를 저장할지의 여부를 지정한다. (저장공간이 증가될 수 있다.)true or false
termOffsetstermVectors와 함께 사용되며 색인어의 offset 정보를 저장할지의 여부를 지정한다. (저장공간이 증가될 수 있다.)true or false
required해당 필드가 반드시 있어야 하는지 여부를 지정한다. true로 지정되었는데 field 값이 정의되지 않았다면 오류가 발생한다.true or false
defaultfield 값이 정의되지 않을 경우 default로 사용할 값을 지정한다.

[참고]

http://wiki.apache.org/solr/FieldOptionsByUseCase

Install & Running Solr

Solr는 별도의 설치를 요구하지 않는다.
따라서 Solr distribution page에 접속하여 apache-solr-x.x.x.zip(여기서는 4.0.0을 사용한다.)을 내려받은 후 적절한 위치에 압축을 해제함으로써 Solr 자원을 이용할 수 있다.
그 밖에도 빠르고 간편하게 테스트를 진행할 수 있도록 샘플문서(apache-solr-4.0.0/example/exampledocs)와 인덱싱 정보(apache-solr-4.0.0/example/solr)를 제공한다.
이후에는 Tomcat과 Jetty에서 Solr를 실행하는 방법을 소개한다.

Quick start with Jetty

빠른 실행을 위해 apache-solr-4.0.0/example에서 start.jar를 다음과 같이 실행한다.


에러 없이 Solr가 실행되었다면 웹브라우저에서 http://localhost:8983/solr 접속을 통해 Solr admin 페이지를 확인할 수 있다.

샘플 xml문서를 인덱싱하기 위해 apache-solr-4.0.0/example/exampledocs에서 post.jar를 이용하여 다음과 같이 인덱싱을 수행한다.

인덱싱이 완료되면 Solr admin 페이지를 통해 다음과 같이 검색과 결과조회를 할 수 있다.

Start with Tomcat

Tomcat에서 Solr를 실행시키기 위해 먼저 tomcat 서비스를 중지시킨 후 apache-solr-4.0.0/example/webapps에 있는 solr.war 파일을 apache-tomcat-6.0.36/webapps 아래에 복사한다.
인덱싱 정보가 저장될 Solr home 디렉토리를 설정하기 위해 apache-tomcat-6.0.36/conf/Catalina/localhost에 solr.xml 파일을 아래와 같이 생성한다.


  

준비가 완료되면 tomcat 서비스를 재시작한다.
Windows의 경우 시작 -> 제어판 -> 시스템 및 보안 -> 관리 도구 -> 서비스 에서  Apache Tomcat6 를 시작 및 중지할 수 있으며,
CentOS의 경우 다음과 같이 서비스를 시작 및 중지할 수 있다.
service tomcat6 start
service tomcat6 stop
웹브라우저를 통해 http://localhost:8080/solr 로 접속하면 Solr admin 페이지를 확인할 수 있다.

2013년 12월 15일 일요일

Install Apache Tomcat 6 on CentOS

Apache Tomcat 6 설치



- 압축 해제 및 소유권 할당
cd /tmp
tar -zxvf apache-tomcat-6.0.32.tar.gz -C /usr/share/
ln -s /usr/share/apache-tomcat-6.0.32 /usr/share/tomcat6
useradd -u 501 -M -d /usr/share/apache-tomcat-6.0.32 tomcat
chown -R tomcat: /usr/share/apache-tomcat-6.0.32 
chown -h tomcat: /usr/share/tomcat6
* 여기서 다운로드 받은 apache-tomcat 파일은 /tmp 디렉토리에 있으며, 버전은 6.0.32를 사용하는 것으로 하겠다.


Native Daemon용 시작 스크립트 생성(Optional)


The Java portion of Commons Daemon(jsvc) 컴파일 (64Bit)

cd /usr/share/tomcat6/bin
tar -zxvf commons-daemon-native.tar.gz
cd commons-daemon-1.0.5-native-src/unix
export CFLAGS=-m64
export LDFLAGS=-m64
./configure --with-java=/usr/java/default
make
cd ../.. (tomcat의 bin디렉토리)
cp commons-daemon-1.0.5-native-src/unix/jsvc ./
chown tomcat: /usr/share/tomcat6/bin/jsvc
rm -rf commons-daemon-1.0.5-native-src
* requirement : gcc

Tomcat 6 Service 시작 스크립트 생성


서비스 등록 및 시작


서비스 등록
chmod u+x /etc/init.d/tomcat6
chkconfig --add tomcat6
service tomcat6 start

서비스 구동 확인
pgrep -u tomcat -l
11900 jsvc


Logrotate 등록

/etc/logrotate.d/tomcat 을 아래와 같이 생성

Install Oracle JDK 6 on CentOS

CentOS 64bit 환경에서 Solr 운영에 필요한 JDK 설치하기

1. JDK 다운로드에서 Linux 64bit 버전을 다운로드

파일이름 : jdk-6u45-linux-x64-rpm.bin


2. 설치

sh jdk-6u45-linux-x64-rpm.bin


3. 환경설정

JDK 설치 패키지는 기본적으로 설치 시 다음과 같이 링크를 생성한다.
/usr/bin/java -> /usr/java/default/bin/java
/usr/bin/javac -> /usr/java/default/bin/javac
/usr/bin/javaws -> /usr/java/default/bin/javaws
따라서 특별한 경우 외엔 다음 설정을 하지 않아도 무방하다. 다음 설정은 default가 아닌 설치한 최신 버전을 기준으로 Java 프로그램이 실행되도록 하였다.
alternatives --install /usr/bin/java java /usr/java/latest/jre/bin/java 20000
alternatives --install /usr/lib64/mozilla/plugins/libjavaplugin.so libjavaplugin.so.x86_64 /usr/java/latest/jre/lib/amd64/libnpjp2.so 20000
alternatives --install /usr/bin/javac javac /usr/java/latest/bin/javac 20000
alternatives --config java (설치한 latest/bin/java를 선택한다)
There are 2 programs which provide 'java'.

  Selection    Command
-----------------------------------------------
 + 1           /usr/lib/jvm/jre-1.4.2-gcj/bin/java
*  2           /usr/java/latest/jre/bin/java

Enter to keep the current selection[+], or type selection number:


4. JDK 환경변수 등록

cat <<EOF > /etc/profile.d/java.sh
export JAVA_HOME=/usr/java/latest
export PATH=\$JAVA_HOME/bin:\$PATH
export CLASSPATH=.:\$CLASSPATH
EOF

source /etc/profile.d/java.sh