소개
Database 기반의 사이트를 설계하다보면, 키워드 검색 기능이 필요할 때가 있습니다. 사실 대부분 사이트가 이런 검색기능이 있습니다. 일반적으로 SQL 에서 검색이라고 하면 LIKE 를 많이 떠올립니다. 데이터의 양이 많치 않을 경우에는 LIKE 로 충분합니다만, 수백만건 이상 되는 데이터에 대해서 검색하려면, LIKE 에는 많은 무리가 있습니다. 기본적으로 FullTable Scan 을 하게 될테니까요.
이런 검색을 위해서 Database 마다 Full Text Search 를 고유한 방식으로 지원하고 있습니다. MySQL 에서도 FullText Search 를 지원하지요. 하지만 아무래도 서버의 로드가 올라가거나 하는 문제들이 발생합니다. 이를 해결하기 위해서 대부분 Sphinx 라는 이 녀석을 사용하길 추천하더군요. :)
오늘은 이 Sphinx 검색 엔진에 대해서 알아보도록 하겠습니다.
미리 알아야 할 점
이 스핑크스(Sphinx)라는 엔진은 MySQL 처럼 Index 를 위한 일종의 DB 입니다. 무슨 말인가면 Index 를 구성하는 방식이 크게 두가지로 나뉩니다. 첫번째는 자체적으로 MySQL 처럼 Database 가 되는 것이고, 또 한가지는 다른 Database 에서 값을 가져와서 Index 를 구성하는 방식입니다. 전자를 Real Time Index (RT index)라고 하고, 후자는 뭐라고 불러야 하는지 잘 모르겠네요. 후자도 두가지로 나뉩니다. full 로 가져오는 것과 변경된 내용만 따로 가져와서 merge 하는 방식입니다.
말씀드리고 싶은 점은, 대게 데이터베이스가 따로 있는 상태에서(예. MySQL) 검색이 필요한 부분만 Sphinx 에서 처리하는 경우가 많을거라 생각됩니다. 이때는 당연히 Real Time Index 를 사용하지 않을것 같습니다. 꼭 쓰겠다면 MySQL 같은 original 서버에 데이터를 CUD(Create, Update, Delete) 할때, Sphinx 에서도 같이 CUD 해 주면 되겠습니다. 아무튼 이렇게 할것이 아니라면, 주기적으로 Sphinx 에 데이터를 업데이트 해 주어야 합니다. -_-;;
후에 설명하겠지만, indexer 라는 녀석을 통해서 Sphinx 에 update 해주어야 합니다. 이게 아시겠지만 많은 부하가 걸리므로, main indexer 를 초기에 빌드하고, 이후 변경된 내용만 merge 할 수 있습니다. 이 부분은 직접 찾아보시기 바랍니다. 인터넷에 자료가 많이 있습니다.(사실 간단합니다.)
모쪼록 주기적으로 update(싱크를 맞추기 위해)하려면, indexer 를 호출해 주어야 합니다. 주기적으로요... Sphinx 에서 자동으로 싱크를 맞추지는 않습니다. 수동입니다. 그러므로 Crontab 같은 것을 이용하여, 일정시간마다 실행시켜 주어야 합니다. 이후 자세히 설명하도록 하겠습니다.
설치
CentOS 6.6 버전에서의 설치 방법에 대한 이야깁니다.
먼저 아래 Sphinx 사이트에서 다운로드 받습니다.
http://sphinxsearch.com/downloads/release/
제 시스템은 CentOS 6.6 x86_64 이므로 해당 버전을 받도록 하겠습니다. :)
참고로 tmp 에 받았습니다.
[und3r@crystalcube.com tmp]$ wget http://sphinxsearch.com/files/sphinx-2.2.8-1.rhel6.x86_64.rpm
파일이 rpm 으로 제공되네요.
rmp 을 이용해서 설치해도 되지만, dependency 가 걸려있으면, 귀찮기 때문에 yum 으로 인스톨 합니다. :)
[und3r@crystalcube.com tmp]$ sudo yum --nogpgcheck localinstall sphinx-2.2.8-1.rhel6.x86_64.rpm
역시나 아래처럼 뭔가 필요한게 더 있네요 :)
Dependencies Resolved
==============================================================================================
Package Arch Version Repository Size
==============================================================================================
Installing:
sphinx x86_64 2.2.8-1.rhel6 /sphinx-2.2.8-1.rhel6.x86_64 33 M
Installing for dependencies:
mysql-libs x86_64 5.1.73-3.el6_5 base 1.2 M
unixODBC x86_64 2.2.14-14.el6 base 378 k
Transaction Summary
==============================================================================================
Install 3 Package(s)
Total size: 34 M
Total download size: 1.6 M
Installed size: 38 M
Is this ok [y/N]:
과감히 설치합니다. 설치가 완료되면 어디에 설치되었나 확인을 해 봅니다.
[und3r@crystalcube.com tmp]$ whereis sphinx
sphinx: /etc/sphinx /usr/share/sphinx
설정하기
이제 Sphinx 를 사용하기 위해, sphinx.conf 를 설정해 주어야 합니다. 경로는 /etc/sphinx/sphinx.conf 입니다.
source my_users
{
type = mysql
sql_host = localhost
sql_user = und3r
sql_pass = password
sql_db = crystalcube
sql_port = 3306 # optional, default is 3306
#sql_sock = /home/und3r/mysql/tmp/mysql.sock
sql_query = SELECT id, name FROM users
#sql_attr_uint = id
sql_field_string = name
#sql_attr_timestamp = date_added
}
index my_users
{
source = my_users
path = /var/lib/sphinx/my_users
}
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/
}
하나씩 살펴보도록 하겠습니다.
첫번째로 나오는 source 부분은 Sphinx 에서 index 를 생성할때 사용할 source 입니다. 즉 원본 데이터를 어디서, 무엇을 어떻게 가져올지에 대한 정보가 있는 곳이죠.
눈치 채셨겠지만, source 뒤에 나온 my_user 는 사용자가 지정해주는 별칭입니다. 이후에 index 설정할때 이 값을 사용합니다. 대게 table 명을 써 주는게 좋습니다.
안에 나오는 sql_host, sql_user 등은 database 의 정보입니다. 이곳 정보를 통해서 index 구성할때, 원본 database 에 연결합니다.
sql_query 라는 부분은 해당 database 에 접속한 후에, 어떤 데이터들을 가져와서 index 로 구성할건지에 대한 정보입니다. 위 예에서는 users 라는 테이블에서 id 와 name 을 가져오겠다는 것이죠. 주의할점은 첫번째 컬럼은 반드시 unique 한 primary key 값이어야 합니다.
혹시나 mysql 을 기본위치에 설치하지 않은 경우(sock 의 경로가 /tmp/mysql.sock 이 아닌 경우), sql_sock 을 통해서 직접 설정해 주시면 됩니다.
다음에 이어서 나오는 sql_field_string 은 앞서 query 에서 가져온 데이터에 대한 schema 정도로 생각하시면 됩니다. 위 예에서 name 의 데이터 타입은 string 이므로 sql_field_string 입니다. 만약 int 값이었다면 sql_field_uint 를 써야 겠지요. 모든 데이터 타입에 대한 정보는 http://sphinxsearch.com/docs/current.html#conf-sql-field-string 를 보시면 됩니다.
중요한것은 sql_field_ 와 sql_attr_ 이 있는데 주의하셔야 합니다. field 는 검색 대상 필드이고, attr 은 검색을 제외한 order 같은 곳에서 쓰일때 선언하는 것입니다.
다음으로 index 부분을 보겠습니다.
역시나 index 뒤에 이름이 붙습니다. 이 이름은 나중에 indexer 를 통해서 database 의 값을 가져올때, 파라미터로 쓰입니다. source 랑 동일하게 이름을 지으셔도 무관합니다. path 는 저장될 위치인데, 기본값으로 하시면 됩니다.
뒤에 searchd 는 sphinx 서비스를 실행하는 정보에 대한 것입니다. pid_file 등 입맛에 맞게 수정하시면 됩니다.(수정 안해도 됩니다 ㅎ)
참, 만약 sphinx 에서 사용할 index 가 여러개라면, 위 conf 에서 source 와 index 를 쌍으로 하나씩 추가해 주시면 됩니다.
맺음말
스핑크스(Sphinx) 를 사용하는 경우가 크게 두가지 정도 되는것 같습니다. 전화번호부라든지, 우편번호처럼 한번 값을 넣고나면 수정의 거의 없는 경우. 그리고 사용자가 계속 데이터를 추가하고 수정하는 경우가 있는것 같습니다.
전자의 경우라면 스핑크스가 더없이 좋고 편리할것 같습니다. 하지만 후자라면 delta 를 써야하고, 비교적 복잡합니다. 주기적으로 업데이트도 해 주어야 하니까요.
상황에 맞게 잘 쓰시면 될것 같습니다 :)
Sphinx 서비스를 돌리고, 검색하고 확인하는 방법에 대해서는 다음 포스팅에서 다루도록 하겠습니다.
'DB > Sphinx' 카테고리의 다른 글
[Sphinx] Sphinx 검색엔진 3부 - 검색 및 설정 (0) | 2023.02.06 |
---|---|
[Sphinx] Sphinx 검색엔진 2부 - 설정 및 사용 (0) | 2023.02.06 |
[Sphinx] Sphinx 검색엔진 라이브러리 (0) | 2023.02.06 |