현재 사용하고 있는 버전이 Mysql 5.5버전에 innoDB를 사용하는 테이블에서 like 쿼리를 날리니,
full text 검색이 지원이 되지 않아, 쿼리가 몇초씩 걸리더군요.
5.6부터는 지원을 한다고는 하는데, 불안정할 것 같아서 이번 기회에 Sphinx라는 검색엔진을 붙여보기로 했습니다.
1. 설치
http://sphinxsearch.com/downloads/release/ 로 이동해서, 본인 OS 버전에 맞는 것을 받아줍니다.
(저는 Cent OS 5.X버전을 기준으로 설명하겠습니다.)
다운받기가 귀찮으신 분은 wget을 이용해서 바로 받아주시면 되겠습니다.
wget http://sphinxsearch.com/files/sphinx-2.0.5-1.rhel5.x86_64.rpm (2.0.5버전 rpm)
이렇게 하면, 위 명령어를 친 경로에 파일이 받아집니다.
rpm을 설치해줍니다.
[rpm옵션]
설치 옵션: -i 또는 -U (install, upgrade)
제거 옵션: -e (erase)
질의 옵션: -q (query)
기타: -v (정보 표시)
-h (진행상태 표시)
--force (강제설치)
--nodeps (의존성 무시)
$ rpm -Uvh sphinx-2.0.5-1.rhel5.x86_64.rpm
이렇게 하면 설치완료!
2. Sphinx.conf 설정
설치된 폴더로 이동해보시면 Sphinx.conf 라는 설정파일이 있습니다. (저는 /etc/sphinx/ 라는 경로에 설치되더군요.)
설정하기 전에 주의하실 점은, 사용하고 계신 mysql의 charset을 아래 설정과 동일하게 해주어야 한다는 점입니다.
전 UTF-8을 기준으로 설명하도록 하겠습니다.
열어보면 아래와 같은 구조로 되어 있습니다.
자세한 내용은 주석 참조
#
# Minimal Sphinx configuration sample (clean, simple, functional)
#
source src1
{
type = mysql
sql_host = {DB호스트}
sql_user = {ID}
sql_pass = {PASSWORD}
sql_db = {DB}
sql_port = {PORT} # optional, default is 3306
sql_query_pre = SET NAMES UTF8 # 쿼리 실행 전에 처리되는 구문
sql_query_pre = SET CHARACTER SET UTF8 # 쿼리 실행 전에 처리되는 구문
# 결과 값을 가져올 쿼리 (항상 아래 sql_attr_xxxx 들과 매칭을 시켜주어야 정상적으로 인덱싱 됩니다.)
sql_query = SELECT test_id, test_value, UNIX_TIMESTAMP(test_dt) AS test_dt FROM test_table
sql_attr_timestamp = test_dt # 결과 값 중 timestamp 형태를 가진 컬럼에 대해 명시
sql_attr_uint = test_id # 결과 값 중 uint 형을 가진 컬럼에 대해 명시
# string만 sql_field_string을 사용하는 이유는 sphinx는 기본적으로 string형태를 가진 컬럼을 기준으로 인덱싱 하기 때문에
# 굳이 추가하지 않아도 되지만, java코드에서 log 등을 확인하기 위해 추가합니다.)
sql_field_string = test_value # 결과 값 중 string 형을 가진 컬럼에 대해 명시
# $id는 sphinx내에서 인덱싱한 값들에 대한 고유값으로, 테이블 내에서 sequence id로 사용하는 컬럼을 매칭시켜 줍니다.)
sql_query_info = SELECT * \
FROM test_table \
WHERE test_id=$id
}
index test_idx
{
source = src1
path = /var/data/rt # 인덱싱 될 데이터들을 저장할 경로
docinfo = extern
# 한글 처리를 위해 utf-8로 해주고, charset_table 추가 (공식홈 참조)
charset_type = utf-8
charset_table = 0..9, A..Z->a..z, _, a..z, U+AC00..U+D7A3,\
U+1100..U+1159, U+1161..U+11A2, U+11A8..U+11F9
min_word_len = 1 # 검색 시 단어로 취급할 문자의 수 (1은 한 글자도 단어로 취급한다는 의미)
min_prefix_len = 0
min_infix_len = 1
}
indexer
{
mem_limit = 256M # indexer가 사용할 메모리 최대치(기본값)
}
searchd
{
compat_sphinxql_magics = 0 # 추가하지 않으면 에러가 발생하는 경우가 있으므로, 그냥 추가
# 이건 거의 정보가 없어서, 삽질할 가능성이 높으므로, 그냥 추가합니다.
listen = 9312
listen = 9306:mysql41
log = /var/log/sphinx/searchd.log # 인덱싱 된 결과 로그가 추가될 경로
query_log = /var/log/sphinx/query.log # 인덱싱 처리 시 위에 명시된 쿼리에 대한 로그가 추가될 경로
read_timeout = 5
max_children = 30
pid_file = /var/run/sphinx/searchd.pid
max_matches = 1000
}
여기까지 세팅 완료!
3. 실행 (설정 파일이 바뀌거나 데이터가 바뀔 경우 매번 해줘야 하는 작업)
1) INDEXING (설정파일에 명시된 모든 index를 indexing한다. 옵션을 다르게 주면, 개별 indexing도 가능하지만, 귀찮으므로 all로 ㄱ)
: indexer --all {설정파일 : sphinx.conf}
2) SEARCHD(데몬 띄우기)
: searchd --config {설정파일}
3) INDEX를 이용한 쿼리 실행 확인
(여기서 한글로 테스트하는 건 별로 의미가 없으니, 대충 영어로 테스트하고 넘어갑시다. like검색처럼 못찾는다면,
설정이 잘못된거니까 설정 파일 수정 후 데몬을 죽이고, 다시 indexing한 후 테스트 합니다.)
: search {keyword}
※ pid를 이용하지 않고 sphinx 데몬을 죽이는 법 : searchd --stop
(여러개가 뜨면 느려질 수 있으므로, 다시 indexing할 때는 왠만하면 실행해줍니다.)
4. JAVA 코드를 이용한 연동
http://sphinxsearch.com/downloads/release/ 로 다시 이동해서, windows OS용을 하나 받아서, 압축을 풀어봅니다.
압축을 푼 내용 중에 보면 api폴더가 있는데, 그 안에 java를 이용해서 연동할 수 있는 example코드가 있습니다.
test.java를 열어보면, 테스트를 할 수 있도록 연동코드가 들어가 있는데,
like검색처럼 하기 위해서는 MATCH MODE를 바꿔주어야 합니다.
기본적으로 SPH_MATCH_ALL 이라고 되어 있는데, SPH_MATCH_ANY 로 바꿔주어야 like검색이 됩니다.
나머지 부분은, 다른 코드들을 참조하셔서 filtering이라던지 sorting이라던지 mysql과 동일하게 이용하실 수 있습니다.
filtering이라던지, sorting같은 경우 java코드에서 처리하는 것이 indexing 설정파일에서 하는 것보다 성능이 좋더군요.
연동코드까지 마친 후에는, 위에 3번의 indexing작업을 crontab 등을 이용해서 주기적으로 업데이트 해주는게 중요합니다.