Computer/MySQL

[스크랩] 웹문서 검색엔진 기술의 핵심

알찬돌삐 2005. 5. 20. 18:25
다음의 문서는 제가 지난 1년여의 기간 동안 웹문서 검색엔진 스카우터(http://www.skouter.com)을 개발하고 운영하면서 얻은 경험을 토대로 작성된 문서의 일부입니다. 웹문서 검색엔진 스카우터는 아직은 데모 사이트의 수준이지만 현재 740만개의 웹문서를 인덱싱하고 있습니다.

----------------------------------
*웹문서 검색엔진 기술의 핵심

웹문서 검색엔진 기술에 있어서 핵심적인 부분은 다음의 몇가지로 요약될 수 있다.


1. 인덱싱한 문서의 갯수
현재 한국에서 서비스되고 있는 웹문서 검색엔진들의 경우 인덱싱하고 있는 문서가 보통 1천만에서 4천만개 정도로 추산된다. 이런 점을 고려하면 한국에서 경쟁력있는 웹문서 검색엔진을 서비스하기 위해서는 먼저 1천만개 이상의 웹문서를 인덱싱하는 것이 필수라고 생각된다. 그러나 천만 단위의 웹문서를 인덱싱하기 위해서는 다음과 같은 몇가지의 기술적, 정책적, 비용적 난점이 존재한다.

- 문서의 수집속도
1천만개 이상의 웹문서를 인덱싱하려면 우선 매우 빠른 속도로 문서를 수집하고 처리하는 크롤러(Crawler)가 필요하다. 만약 크롤러가 하루에 10만개의 문서를 수집한다고 가정하면 1천만개의 문서를 수집하기 위해서는 3개월 이상의 시간을 소모해야 한다. 그러나 전체 인덱싱 과정을 완료하기 위해서 3개월 이상의 시간을 소모한다면, 해당 검색엔진에서 검색되는 정보가 3개월 이전의 것일 수 있다는 점에서 문서의 수집속도가 충분히 빠르다고는 말할 수 없다. 현재 국내에 서비스되는 웹문서 검색엔진 중에서 전체 웹문서를 새로이 수집하고 인덱싱을 하는 풀업데이트 작업의 속도가 가장 빠른 검색엔진은 4천만개 이상의 웹문서를 1개월 이내에 풀업데이트를 한다. 그러므로 국내에서 경쟁력 있는 웹문서 검색엔진을 서비스하려면, 물론 목표로 하는 인덱스의 크기에 따라 다르지만, 보통 하루에 1백만개 이상의 웹문서를 수집할 수 있는 크롤러가 필요하다고 생각된다.

- 효율적인 인덱스 구조
현재 대부분의 검색엔진들이 여러가지 이유로 인해서 역인덱스(Inverted-Index) 구조를 사용하고 있는데, 만약 역인덱스 구조를 사용하는 검색엔진이 1천만개의 문서를 저장하고 문서당 평균적으로 100개의 단어를 인덱싱한다면, 전체 인덱스의 데이타 갯수는 약 10억개에 달한다. 이런 크기의 인덱스를 유지하고 검색하려면 데이타의 물리적인 구조 또한 매우 효율적으로 이루어져 있어야 하는데, 구체적으로 말하자면 검색의 경우에는 하드드라이브의 헤드의 움직임을 최소화하는 형태로 데이타의 물리적인 구조가 이루어져 있어야 하며, 새로운 데이타를 입력하는 경우에는 전체 인덱스를 다시 정렬하는 등의 불합리한 과정이 없어야 한다.

- 고성능의 하드웨어
웹문서 검색엔진의 경우 다루는 데이타의 크기가 보통 수십기가바이트가 넘으며 대형 검색엔진의 경우에는 테라바이트 급의 데이타를 다루는 경우도 있다. 이런 크기의 데이타를 빠른 시간내에 처리하려면 먼저 입출력 속도가 빠른 대용량의 저장장치가 있어야 하며, 충분한 크기의 메모리와 빠른 속도의 CPU 역시 필요하다. 제아무리 효율적인 인덱스 구조를 사용하더라도 충분한 하드웨어의 지원이 없다면 천만단위의 웹문서를 인덱싱하고 검색하는 것은 거의 불가능하다.

- 검색대상의 최소화
웹문서 검색엔진은 인터넷에 존재하는 모든 문서를 인덱싱하는 것을 목표로 할 수는 없다. 현재 한국의 대형 커뮤니티 한곳의 게시판에서 나오는 문서의 갯수만 해도 수백만개에 달하는데, 이런 문서들을 모두 인덱싱한다면 인덱스의 크기는 거의 무한정으로 커질 것이며, 인덱스를 검색하는 속도는 검색엔진으로서의 효용가치가 없는 수준까지 느려질 것이다. 그리고 인덱스의 크기가 커질수록 인덱스의 유지에도 많은 시간과 노력과 비용이 소모되게 마련이다. 그러므로 검색엔진의 효용성을 크게 훼손하지 않는 범위에서 인덱싱할 문서의 갯수를 최소화할 수 있는 방법이 필요하다. 여기에는 우선 사용자에게 유용한 문서에 관한 내부적인 정책을 세우고 그에 따라서 사용자에게 유용하다고 판단되는 문서만을 인덱싱하는 방법을 사용할 수 있으며 보조적으로 스팸문서, 중복문서, 유사문서, 내용이 없는 문서의 제거 또는 최소화를 하는 방법이 있겠다.


2. 정확한 랭킹시스템
현재 서비스되고 있는 대부분의 검색엔진은 기본적으로 사용자가 입력한 검색어와 일치하는 단어를 포함한 문서를 검색한다. 그리고 이런 매칭검색에 의한 검색결과를 내부적인 기준에 의해 결정된 정확도, 또는 중요도에 따라서 다시 정렬을 한 결과를 사용자에게 보여준다. 그런데 웹문서 검색엔진의 경우는 그 특성상 인덱싱하고 있는 문서가 매우 많기 때문에 보통 검색결과가 수만에서 수십만에 달하며, 대형 검색엔진이라면 수백만개의 검색결과를 출력하는 경우도 있다. 그러나 대부분의 경우에 있어서 사용자가 원하는 정보는 검색결과의 극히 일부에 지나지 않는다. 따라서 사용자에게 필요한 정보, 사용자가 원하는 정보를 검색결과의 상위에 출력할 수 있는 기능이 웹문서 검색엔진에서는 매우 중요하다. 실제적인 예를 들자면, 만약 사용자가 한국인이라면 대개의 경우 '야후'라는 단어로 검색을 하는 경우에는 kr.yahoo.com 이 최상위에 출력되는 것을 원할 것이고, '옥션'이라는 단어로 검색을 하는 경우에는 www.auction.co.kr 이 최상위에 출력되는 것을 원할 것이다. 그러나 현재 웹에 존재하는 문서 중에서 '야후', '옥션' 등의 단어를 포함한 문서는 헤아릴 수 없을 정도로 많으며 이들 검색어에 해당하는 웹문서 검색엔진의 검색결과 역시 엄청난 숫자이다. 이렇게 많은 검색결과에서 사용자가 원하는 검색결과인 kr.yahoo.com, www.auction.co.kr 을 최상위에 출력하려면 먼저 사용자에게 중요한 문서의 기준에 관한 올바른 정책과 그 정책을 구현한 랭킹시스템이 필요하다. 이때 랭킹시스템이란 사용자의 의도를 파악하는 인공지능이라는 식의 그 실체가 모호한 허황된 프로그램적 장치가 아니고 웹문서 내부에 존재하는 정보와 외부에 존재하지만 해당 문서와 관련있는 정보를 분석하고 그 정보를 토대로 내부적인 기준에 따라서 각 문서의 랭킹을 산출할 수 있는 일련의 논리적인 체계이다. 정확한 랭킹시스템을 구성하기 위해서는 다음과 같은 점을 고려할 수 있다.

- 검색어의 빈도수
검색어의 빈도수에 따라서 검색결과를 정렬하는 것은 매우 전통적인 방법이며, 대부분의 검색엔진에서 채택하고 있는 방법이다. 이 방법은 웹문서 검색엔진이 신뢰할 수 없는 영역을 검색한다는 점에서 많은 문제점을 갖고 있지만 아직까지도 무시할 수는 없는 방법이다. 예를 들자면 어떤 문서에서 '야후'라는 단어가 많이 발견된다면 이 문서가 야후와 관련이 있다고 생각하는 것이 타당하다. 그러나 현재 인터넷에는 검색어의 빈도수 조작을 시도하는 문서가 많기 때문에 검색어의 빈도수를 랭킹에 반영할 수 있는 경우와 그렇지 않은 경우에 관한 제한을 설정하는 것이 필수이다. 실제로 많은 문서들이 웹문서 검색엔진에서의 랭킹을 조작하기 위해서 문서의 내용과는 아무런 관련이 없는 인기있는 검색어를 제목이나 본문에 나열하는 경우가 있다. 따라서 특정한 단어가 일정 횟수 이상 반복이 되는 경우 랭킹에 반영을 하지 않는다던가 하는 형태의 제한이 필요하다.

- 링크의 빈도수
링크의 빈도수를 랭킹에 반영하는 것은 구글의 페이지랭크 알고리즘 이후에 몇몇 검색엔진에서 채택하고 있는 방법인데, 이 방법의 요점은 보다 많이 링크가 되어 있는 사이트가 보다 인기가 있는 사이트라는 것이다. 비록 요즘에 들어서 이런 형태의 알고리즘을 역이용하려는 스팸문서가 많아지기는 했지만 링크의 빈도수의 조작이 검색어의 빈도수 조작보다 어렵다는 점에서, 링크의 빈도수는 아직도 웹문서 검색엔진의 랭킹시스템을 구성하는 데에 있어서 신뢰도가 높은 중요한 요소가 될 수 있다. 그러나 요즘에는 많은 사이트에서 스팸문서를 통해서 링크의 빈도수를 조작하려는 시도를 하기 때문에, 링크의 빈도수를 랭킹에 반영하려면 정당한 링크와 그렇지 않은 링크에 관한 정책을 만들고 이 정책에 따른 제한을 하는 것이 필요하다.

- 링크텍스트의 반영
링크텍스트란 하나의 문서에서 다른 문서를 지칭할 때의 텍스트를 말한다. 즉 kr.yahoo.com 문서의 제목에서 발견되는 '야후' 라는 단어보다 타 사이트에서 kr.yahoo.com 문서를 야후라는 이름으로 링크를 한 경우의 링크텍스트에서 발견되는 '야후'라는 단어가 보다 객관적이라고 판단할 수 있는데, 이 링크텍스트를 저장하고 인덱싱할 수 있다면 랭킹시스템에 매우 중요한 정도로 반영할 수 있을 것이다. 물론 요즘에는 이런 점까지 감안해서 스팸문서가 제작되지만 링크텍스트는 여전히 문서의 내부에서 발견되는 단어보다 신뢰도가 더 높다. 그러나 이런 링크텍스트를 반영하기 위해서는 우선 크롤러에 링크텍스트를 파싱하고 저장할 수 있는 기능이 있어야 하겠다.

- 스팸필터링
웹문서 검색엔진의 개발과 운영을 어렵게 하는 원인은 먼저 검색대상이 너무 많다는 것이며, 그 다음으로는 웹문서 검색엔진이 신뢰할 수 없는 영역을 검색한다는 것이다. 특히 신뢰할 수 없는 영역을 검색한다는 특성은 객관적이고도 신뢰할 수 있는 랭킹시스템을 구성하려는 시도에 가장 큰 난점으로 작용한다. 현재 웹에는 웹문서 검색엔진에서의 랭킹을 조작하기 위해서 갖가지 방법을 동원한 스팸문서가 난무하고 있는데, 요즘의 스팸문서는 날이 갈수록 더 교묘한 방법을 사용하여 랭킹조작을 시도하고 있다. 이런 신뢰할 수 없는 영역을 검색하는 검색엔진이 보다 신뢰할 수 있는 랭킹시스템을 구성하기 위해서는 먼저 스팸문서에 관한 내부적인 정책을 만들고 그 정책에 따른 스팸문서의 필터링을 통해서 웹문서 검색엔진의 검색대상의 신뢰도를 조금이나마 높이는 방법이 있겠다. 그러나 스팸필터링을 지나치게 강력하게 적용하는 경우에는 스팸문서가 아닌 엉뚱한 문서가 검색대상에서 제외되는 결과가 나오므로 적당한 정도의 스팸필터링을 적용하는 것 또한 중요하다.


3. 업데이트 속도
웹문서 검색엔진의 개발과 운영을 어렵게 하는 가장 큰 원인은 데이타가 너무 많다는 것이다. 현재 한국에서 경쟁력있는 웹문서 검색엔진을 서비스하려면 먼저 1천만개 이상의 웹문서를 인덱싱해야 한다. 그러나 1천만개 이상의 웹문서를 수집하고 인덱싱 하는 것은 그리 간단한 문제가 아니며 더욱 문제를 어렵게 하는 것은 웹이 계속해서 변화를 하고 있다는 것이다. 웹에서는 매일 수많은 문서가 추가되고, 변경되고, 삭제되고 있다. 그런데 웹문서 검색엔진이 웹의 변화를 즉각적으로 반영하지 못한다면, 많은 경우에 있어서 웹문서 검색엔진의 검색결과와 실제 웹문서의 정보가 일치하지 않을 것이며, 때로는 이미 삭제된 문서가 검색결과에 포함되는 경우도 나올 것이다. 하지만 현실적으로 웹의 변화를 즉각적으로 반영할 수 있는 웹문서 검색엔진을 만드는 것은 불가능한 일이다. 천만 단위의 문서를 수집하고 인덱싱하는 작업이라면 아무리 빠른 시스템을 사용한다고 하더라도 수시간내에 완료할 수는 없는 것이다. 따라서 현실적으로 웹문서 검색엔진은 웹의 변화를 즉각적으로 반영하는 것을 목표로 하기 보다는 인덱스의 업데이트 주기를 최소화하는 것을 목표로 해야 할 것이다. 업데이트 속도라는 축면에서 충분한 경쟁력을 갖춘 웹문서 검색엔진을 개발하기 위해서는 다음과 같은 점들을 고려할 수 있다.

- 부분 업데이트의 도입
웹문서 검색엔진의 데이타를 업데이트하는 방법으로 가장 단순한 방법은 전체 데이타를 새롭게 수집하고 인덱싱을 하는 풀업데이트이다. 그러나 1천만개 이상의 웹문서를 인덱싱하는 것을 목표로 하는 웹문서 검색엔진이라면, 아무리 빠르고 효율적인 시스템을 사용한다고 하더라도 풀업데이트 방식만으로는 업데이트 속도를 빠르게 하는 것에 한계가 있다. 그리고 풀업데이트를 하는 경우에도, 풀업데이트의 주기가 수일 이내라면 새롭게 수집된 웹문서의 대부분이 기존의 웹문서와 동일한 내용이므로, 웹의 변화를 반영하기 위해서 매번 풀업데이트를 하는 것은 시스템 자원의 낭비인 것이다. 따라서 웹문서 검색엔진의 업데이트 방법으로는 풀업데이트 이외에, 웹에 새롭게 추가되거나 내용이 변경된 문서만을 기존의 인덱스에 추가하거나 변경된 내용을 반영하는 부분 업데이트를 병행하여 사용하는 것이 좋다.

- 부분 업데이트가 가능한 인덱스 구조
원래 인덱스란 보통의 텍스트 자료를 검색이 용이한 구조로 변경을 한 것이며, 대개의 경우에는 여기에 검색속도를 향상시키기 위해서 정렬까지 된 구조이다. 그런데 웹문서 검색엔진의 경우 그 특성상 인덱스의 크기가 매우 크기 마련이다. 1천만개 이상의 웹문서를 인덱싱하는 경우, 물론 각 웹문서 검색엔진의 인덱싱 정책과 인덱스 구조에 따라서 결과가 조금씩 다르겠지만, 보통 그 인덱스의 크기가 수십기가바이트에 달하며 이런 정도 크기의 인덱스를 작성하는 데에는 많은 시간과 노력이 소모된다. 그런데 앞에서 말했다시피 인덱스란 대개의 경우 검색속도를 높이기 위해서 이미 정렬이 된 구조이다. 그리고 이미 정렬이 된 인덱스에 새로운 데이타를 추가 또는 삽입하기 위해서는 엄청난 크기의 데이타를 앞으로 밀고 뒤로 당기는 작업이 필요하다. 이것은 실제에 있어서는 인덱스를 다시 쓰는 작업이 필요하다는 것이다. 그러나 빠른 시간 내에 부분 업데이트가 가능하려면 이런 식으로 인덱스를 지우고 다시 쓴다는 방법은 매우 비효율적이다. 따라서 부분적인 변경을 빠르게 반영할 수 있는 인덱스 구조가 필요한 것이다.

- 부분 업데이트 대상의 최소화
인덱스의 부분적인 업데이트가 가능하다고 하더라도 웹문서 검색엔진이 웹의 추가되거나 변경된 내용을 모두 반영하는 것을 목표로 할 수는 없다. 웹에는 매일 수많은 문서가 추가되고, 변경되고, 삭제되는데 이런 웹의 변화를 무제한적으로 부분 업데이트에 반영한다면 부분 업데이트 대상이 되는 웹문서는 수백만개에 달할 수도 있으며 이것은 부분 업데이트의 속도를 크게 저하시킨다. 따라서 부분 업데이트 대상의 제한을 통해서 부분 업데이트 대상의 최소화를 하는 것이 필요하다. 부분 업데이트 대상의 최소화는 내부적으로 부분 업데이트에 반영할 문서와 그렇지 않은 문서에 관한 정책을 만들고 그 정책에 따라서 특정한 조건에 해당하는 웹문서만을 크롤링하고 인덱싱하는 방법으로 이루어질 수 있다. 보다 실제적인 예를 들자면, 대형 포탈사이트나 뉴스사이트와 같이 대부분의 사용자들에게 인기가 있으며, 매일 많은 정도의 업데이트가 이루어지는 사이트에서 추가되거나 변경되는 문서의 경우에는 부분 업데이트에 반영하는 것이 좋다고 가정할 수 있다.

출처 : phpschool.com.