컴퓨터 커뮤니티


[설치/설정] SphinxSearch (스핑크스) 설치 및 쿼리 테스트 + PHP 에서 사용-1

1 개요
보통 MySQL Database 를 이용하여 커뮤니티 사이트를 운영하다 보면, 사용자가 늘어거나, 컨텐츠가 늘어나는 시점에  검색이라는 계륵을 만나게 됩니다. 검색의 특성상 like 를 사용하게 되는데, 이게 빈도가 늘어나고, 범위가 늘어날수록 리소스를 많이 사용하게 됩니다. 보통 이정도 되면, 사이트 검색을 막어버리거나 사용자별 제한을 하게 됩니다. 검색을 없앨수도 없고, 그렇다고 적극 사용하게 할수도 없고, 계륵입니다.
2. 검색엔진
검색을 막을수는 없고, 꼭 넣어야 한다면, 1차적으로 해볼수 있는게 구글 내부검색입니다. 사용법도 간단하고, 성능도 좋습니다. 그러나 커스트마이징이 안됩니다. 구글검색결과 처럼 나옵니다. 
자체 검색이 가능하고, MySQL과 연동하여 사용할수 있는 검색엔진은 여러가지가 있으나, 이중 가장 편한 방법은 MySQL 의 full text search 입니다. 이것만 사용해도 검색 때문에 사이트 속도가 느려지는 문제는 해결할수 있습니다. 그러나, 검색엔진으로 사용하기에 기능이 부족합니다. 그 다음방법으로 성능이 좀더 뛰어나지만, 설치를 별도로 해야 하고, 설정을 좀 해야 하는 SphinxSearch 가 있습니다. 
3. SphinxSearch
SphinxSearch(스핑크스) 는 오픈소스로 된 풀텍스트 검색엔진입니다. 검색엔진이 기본적으로 갖춰야 하는 다양한 기능들이 있습니다. 기능에 대한 자세한 부분들은 공식 사이트나 구글링을 통해 확인을 해보시고, 이 글에서는 설치와 간단한 사용법을 포스팅합니다. 
MySQL에서 스핑크스를 쓸때 가장 큰 장점이 되는 부분은, MySQL 쿼리문 그대로 사용이 가능하다는 점입니다. connection 도 MySQL의 패킷 구조를 따라합니다. PHP 소스에서 MySQL과 동일하게 접속하고, MySQL 쿼리처럼 질의하면 됩니다. 그외 특징으로는 C++ 로 작성되어 있어서 검색속도가 빠르고, 분산처리가능, 동적 색인과 증분색인이 가능하다는 점입니다.
4. 환경구성
설치와 테스트는 CentOS 6 환경에서 이루어졌습니다. CentOS7 이나 Ubuntu 에서 설치 방식이 조금 다를수 있으나 설정파일은 동일합니다. 설치가 어렵지 않기 때문에, 설정만 유의 해서 보면 됩니다.
테스트를 위해 그누보드5를 사용했으며, 게시판 검색을 위해 게시판 데이타를 50만건가량 입력했습니다. 50만건 정도 되는 데이타를 구하기가 어려워,  https://www.kaggle.com/tmdb/tmdb-movie-metadata  cvs 데이타를 내려받아 php 코드로 여러번 반복 등록처리하였습니다. 해외 빅데이타 처리를 위한 샘플 데이타가 많은데, 그건 또 너무 커서 사용이 어려웠습니다.(GB 단위) 국내에서 샘플로 쓸 데이타는 찾질 못했네요.
5. 설치 및 설정
CentOS6의 경우 yum 레파지토리가 없어서, rpm 다운로드후 설치합니다. 
설치후 실행할려면  libmysqlclient.so.x 을 찾는 경우가 있는데,  이 경우 yum 으로 mysql client 를 설치후 vi /etc/ld.so.conf.d/mysql.conf 에 라이브리 경로를 입력하고, ldconfg 를 한번 실행주면 됩니다.
[root@vultr ~]# yum install -y sphinx-2.2.11-2.rhel6.x86_64.rpm
Running Transaction
  Installing : unixODBC-2.2.14-14.el6.x86_64                                                                   
  Installing : postgresql-libs-8.4.20-8.el6_9.x86_64                                                           
  Installing : sphinx-2.2.11-2.rhel6.x86_64     
Sphinx installed!
..........
  Verifying  : postgresql-libs-8.4.20-8.el6_9.x86_64                                                           
  Verifying  : unixODBC-2.2.14-14.el6.x86_64                                                                   
  Verifying  : sphinx-2.2.11-2.rhel6.x86_64                                                                   
Installed:
  sphinx.x86_64 0:2.2.11-2.rhel6
Complete!
[root@vultr ~]#
[root@vultr lib64]# indexer
indexer: error while loading shared libraries: libmysqlclient.so.16: cannot open shared object file: No such file or directory
#오류나네요.
[root@vultr lib64]# find / -name libmy*
/usr/lib64/mysql/libmysqlclient_r.so.16
/usr/lib64/mysql/libmysqlclient_r.so.16.0.0
/usr/lib64/mysql/libmysqlclient.so.16
/usr/lib64/mysql/libmysqlclient.so.16.0.0
[root@vultr lib64]# vi /etc/ld.so.conf.d/mysql.conf
/usr/lib64/mysql 를 추가해줍니다.
[root@vultr lib64]# ldconfig  #한번 실행줍니다.
설치가 완료되었습니다. sphinx는 중요한 파일이 3가지가 있습니다. 
indexer 
색인을 수행하는 명령어입니다.
searchd
검색과 검색결과를 전송해주는 데몬입니다.
sphinx.conf
스핑크스 설정파일입니다. /etc/sphinx/sphinx.conf 에 위치합니다.
위의 설치 상태에서 실행해도 오류가 발생합니다. 이제 sphinx.conf 를 설정해야합니다.
설정할수 있는 부분들이 많은데, 실제 동작하는 설정파일을 보는게 좋습니다. 동작하도록 만들어둔뒤에 추가적인 설정을 하나씩 고쳐서 실행해보면서 기능을 익히도록 합니다. 아래 설정은 그누보드5에서 test 라는 게시판을 색인합니다. 실제 서비스에서는 여러테이블을 색인해야 하고, 병합색인과 관련된 설정과, 게시판 수정/삭제시 기존 색인문서를 삭제하는 기능도 추가되어야 합니다.
source g5_write_test
{
        type                    = mysql
        sql_host                = 127.0.0.1
        sql_user                = root
        sql_pass                = root
        sql_db                  = board
        sql_port                = 3306  # optional, default is 3306
        #sql_sock                = /tmp/mysql.sock
        sql_query = SELECT wr_id id, 'test' bo_table, wr_id, wr_parent, ca_name, wr_subject, wr_content, mb_id, wr_name, wr_ip, wr_is_comment, UNIX_TIMESTAMP(wr_datetime) AS wr_datetime FROM g5_write_test where wr_is_comment=0
        sql_attr_string        = ca_name
        sql_field_string        = wr_subject
        sql_field_string        = wr_content
        sql_field_string        = bo_table
        sql_attr_uint          = wr_id
        sql_attr_uint          = wr_parent
        sql_attr_uint          = wr_is_comment
        sql_attr_timestamp      = wr_datetime
}

index board
{
        source                  = g5_write_test
        path                    = /var/lib/sphinx/board
        docinfo                = extern
        #morphology            = stem_en
        charset_table = 0..9, A..Z->a..z, _, a..z, U+410..U+42F->U+430..U+44F, U+430..U+44F
        ngram_len = 1
        min_word_len = 1
        #enable_star  = 0
        #min_prefix_len = 3
        min_infix_len = 1
        min_prefix_len = 0
        ngram_chars =  U+4E00..U+9FBB, U+3400..U+4DB5, U+20000..U+2A6D6, U+FA0E, U+FA0F, U+FA11, U+FA13, U+FA14, U+FA1F, U+FA21, U+FA23, U+FA24, U+FA27, U+FA28, U+FA29, U+3105..U+312C, U+31A0..U+31B7, U+3041, U+3043, U+3045, U+3047, U+3049, U+304B, U+304D, U+304F, U+3051, U+3053, U+3055, U+3057, U+3059, U+305B, U+305D, U+305F, U+3061, U+3063, U+3066, U+3068, U+306A..U+306F, U+3072, U+3075, U+3078, U+307B, U+307E..U+3083, U+3085, U+3087, U+3089..U+308E, U+3090..U+3093, U+30A1, U+30A3, U+30A5, U+30A7, U+30A9, U+30AD, U+30AF, U+30B3, U+30B5, U+30BB, U+30BD, U+30BF, U+30C1, U+30C3, U+30C4, U+30C6, U+30CA, U+30CB, U+30CD, U+30CE, U+30DE, U+30DF, U+30E1, U+30E2, U+30E3, U+30E5, U+30E7, U+30EE, U+30F0..U+30F3, U+30F5, U+30F6, U+31F0, U+31F1, U+31F2, U+31F3, U+31F4, U+31F5, U+31F6, U+31F7, U+31F8, U+31F9, U+31FA, U+31FB, U+31FC, U+31FD, U+31FE, U+31FF, U+AC00..U+D7A3, U+1100..U+1159, U+1161..U+11A2, U+11A8..U+11F9, U+A000..U+A48C, U+A492..U+A4C6
}
index testrt
{
        type                    = rt
        rt_mem_limit            = 128M
        path                    = /var/lib/sphinx/testrt
        rt_field                = title
        rt_field                = content
        rt_attr_uint            = gid
}

indexer
{
        mem_limit              = 128M
}

searchd
{
        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
        seamless_rotate        = 1
        preopen_indexes        = 1
        unlink_old              = 1
        workers                = threads # for RT to work
        binlog_path            = /var/lib/sphinx/
}
위 설정에서 mysql 접속정보를 제대로 넣어야 합니다. 127.0.0.1 로 접속할수 있는 계정이 설정되어야 하고, localhost 로 접속할때는 sql_sock  주석을 해제하고, mysql.sock 파일 경로를 넣으셔야 합니다. 제대로 설정하고, indexer를 실행해봅니다. 
indexer 가 제대로 동작하면, searchd 를 실행합니다. searchd 까지 정상 실행되면, 이제부터 검색을 할수가 있게 됩니다.
[root@vultr sphinx]# indexer board
Sphinx 2.2.11-id64-release (95ae9a6)
Copyright (c) 2001-2016, Andrew Aksyonoff
Copyright (c) 2008-2016, Sphinx Technologies Inc (http://sphinxsearch.com)
using config file '/etc/sphinx/sphinx.conf'...
indexing index 'board'...
collected 279599 docs, 85.0 MB
sorted 15.2 Mhits, 100.0% done
total 279599 docs, 85013520 bytes
total 12.091 sec, 7030885 bytes/sec, 23123.71 docs/sec
total 279916 reads, 0.278 sec, 0.6 kb/call avg, 0.0 msec/call avg
total 767 writes, 0.632 sec, 421.9 kb/call avg, 0.8 msec/call avg
[root@vultr sphinx]#
#검색 데몬을 실행합니다.
[root@vultr sphinx]# searchd
Sphinx 2.2.11-id64-release (95ae9a6)
Copyright (c) 2001-2016, Andrew Aksyonoff
Copyright (c) 2008-2016, Sphinx Technologies Inc (http://sphinxsearch.com)
using config file '/etc/sphinx/sphinx.conf'...
listening on all interfaces, port=9312
listening on all interfaces, port=9306
precaching index 'board'
precaching index 'testrt'
precached 2 indexes in 0.177 sec
[root@vultr sphinx]# ps -ef | grep searchd
root    32235    1  0 20:03 ?        00:00:00 searchd
root    32236 32235  0 20:03 ?        00:00:00 searchd
root    32274 30426  0 20:03 pts/0    00:00:00 grep --color searchd
[root@vultr sphinx]#
indexer 실행시 옵션이 있는데, -all 로 하면 전체 색인, --merge는 병합색인(이 경우 sphinx.conf 에 병합색인 관련 설정이 들어가야 합니다.) --rotate 는 searchd 데몬에 영향을 주지 않고, 색인을 하라는 옵션입니다.(searchd 가 실행중일때 indexer 를 그냥 실행하면 오류가 발생합니다.)
indexer board --rotate 는 board는 index 설정을 실행하라는 뜻입니다. (sphinx.conf 에 보시면 index board 는 설정 섹션이 있습니다.)
정상적으로 searchd가 실행되었으면,  mysql 로 접속하여, 테스트 해봅니다. 위에서 설명한대로 sphinx는 mysql 클라인트를 그대로 사용할수 있습니다. 기본 실행포트인 9306 포트로 접속하시면 됩니다. 아이디와 비번은 입력할필요 없습니다. mysql 마찬가지로 limit 로 출력 결과수를 조정할수 있습니다. 기본값은 20.
[root@vultr sphinx]# mysql -h127.0.0.1 -P9306
MySQL [(none)]> select * from board;
......
MySQL [(none)]> select wr_id, wr_subject from board where match('@wr_subject "hero"');
+-------+-----------------+
| wr_id | wr_subject      |
+-------+-----------------+
|  770 | Superhero Movie |
|  3388 | Superhero Movie |
|  6006 | Superhero Movie |
|  8624 | Superhero Movie |
| 12833 | Superhero Movie |
| 20043 | Superhero Movie |
| 21279 | Superhero Movie |
| 21958 | Superhero Movie |
| 22558 | Superhero Movie |
| 23050 | Superhero Movie |
| 23109 | Superhero Movie |
| 23362 | Superhero Movie |
| 23615 | Superhero Movie |
| 23769 | Superhero Movie |
| 23927 | Superhero Movie |
| 24261 | Superhero Movie |
| 24395 | Superhero Movie |
| 24574 | Superhero Movie |
| 24937 | Superhero Movie |
| 24985 | Superhero Movie |
+-------+-----------------+
20 rows in set (0.01 sec)

Comments


<
Category
State
  • 현재 접속자 169 명
  • 오늘 방문자 775 명
  • 어제 방문자 1,427 명
  • 최대 방문자 7,216 명
  • 전체 방문자 1,793,036 명
  • 전체 게시물 33,624 개
  • 전체 댓글수 47 개
  • 전체 회원수 534 명
Facebook Twitter GooglePlus KakaoStory NaverBand