天天看點

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

一、開篇幾個問題

1.大規模資料如何檢索?

當系統資料量上了10億、100億條的時候,我們在做系統架構的時候通常會從以下角度去考慮:

1)用什麼資料庫好?(MySQL、sybase、Oracle、達夢、神通、MongoDB、Hbase…)

MySQL:通過分庫分表可以存海量資料,但是做資料檢索效率是達不到毫秒級别,并且資料檢索隻能支援模糊查詢,不支援全文檢索、分詞檢索

以上資料庫都可以做海量資料存儲,但都不适合做檢索的工作。

2)如何解決單點故障;(lvs、F5、A10、Zookeeper、MQ)

叢集,要考慮故障轉移的問題,就需要借助lvs、F5、A10、Zookeeper來維護配置

MQ,可以做大量資料的緩存隊列,例如滴滴,背景存儲了大量的資料,資料實時不停的産生,每天産生400T的資料,這麼大量的資料必須要有一個緩存隊列進行緩存,然後再寫入到庫裡

3)如何保證資料安全性;(熱備、冷備、異地多活)

保證資料不會丢失,做備份

4)如何解決檢索難題;(資料庫代理中間件:mysql-proxy、Cobar、MaxScale等;)

分庫分表後的檢索問題

5)如何解決統計分析問題;(離線、近實時)

以上資料庫做資料統計分析都要自己實作
思考如果自己設計可以從哪些方面考慮:
ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

2.傳統資料庫的應對解決方案?

對于關系型資料,我們通常采用以下或類似架構去解決查詢瓶頸和寫入瓶頸:

解決要點:

1)通過主從備份解決資料安全性問題;

2)通過資料庫代理中間件心跳監測,解決單點故障問題;

3)通過代理中間件将查詢語句分發到各個slave節點進行查詢,并彙總結果

4)通過分表分庫解決讀寫效率問題

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

1.資料庫并不适合做海量資料的檢索,通常項目實踐中不會讓并發請求最終落在資料庫上,資料庫中每個sql本身都代表了鎖,是以性能并不是太高,尤其面對海量資料,并發量高的情況

2.同時資料庫隻能做模糊查詢的檢索,并不能做全文分詞檢索

3.非關系型資料庫的解決方案?

對于Nosql資料庫,以redis為例,其它原理類似, 解決要點:

1)通過副本備份保證資料安全性;

2)通過節點競選機制解決單點問題;

3)先從配置庫檢索分片資訊,然後将請求分發到各個節點,最後由路由節點合并彙總結果

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

Redis做全文檢索是不可能的,本身就是key-value資料結構

并且伺服器記憶體是有限制的,不能無限制存儲資料

4.完全把資料放入記憶體怎麼樣?

完全把資料放在記憶體中是不可靠的,實際上也不太現實,當我們的資料達到PB級别時,按照每個節點96G記憶體計算,在記憶體完全裝滿的資料情況下,我們需要的機器是:

1PB=1024T=1048576G

節點數=1048576/96=10922個

實際上,考慮到資料備份,節點數往往在2.5萬台左右。成本巨大決定了其不現實!

從前面我們了解到,把資料放在記憶體也好,不放在記憶體也好,都不能完完全全解決問題。

全部放在記憶體速度問題是解決了,但成本問題上來了。

為解決以上問題,從源頭着手分析,通常會從以下方式來尋找方法:

1、磁盤存儲順序存儲;

2、将資料和索引分離;

3、壓縮資料;

4、熱點資料放記憶體

5、多線程

以上5個特點就是ElasticSearch的特點(ElasticSearch對堆記憶體的要求比較高,一個節點最高占用30G)

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

二、全文檢索技術

1.什麼是全文檢索?

什麼叫做全文檢索呢?這要從我們生活中的資料說起。

我們生活中的資料總體分為兩種:結構化資料和非結構化資料。

  • 結構化資料:指具有固定格式或有限長度的資料,如資料庫,中繼資料等。
  • 非結構化資料:指不定長或無固定格式的資料,如 網際網路資料、郵件,word文檔等。

對非結構化資料順序掃描很慢,對結構化資料的搜尋卻相對較快,那麼把我們的非結構化資料想辦法弄得有一定結構不就行了嗎?這就是全文檢索的基本思路,也就是将非結構化資料中的一部分資訊提取出來,重新組織,使其變得有一定結構,然後對此有一定結構的資料進行搜尋,進而達到搜尋相對較快的目的。這部分從非結構化資料中提取出的然後重新組織的資訊,我們稱之索引 。

非結構化資料又一種叫法叫全文資料。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

按照資料的分類,搜尋也分為兩種:

  • 對結構化資料的搜尋: 如對資料庫的搜尋,用SQL語句。再如對中繼資料的搜尋,如利用windows搜尋對檔案名,類型,修改時間進行搜尋等。
  • 對非結構化資料的搜尋: 如用Google和百度可以搜尋大量内容資料。

對非結構化資料也即全文資料的搜尋主要有兩種方法:順序掃描法和反向索引法。

  • 順序掃描法:所謂順序掃描法,就是順序掃描每個文檔内容,看看是否有要搜尋的關鍵字,實作查找文檔的功能,也就是根據文檔找詞。
  • 反向索引法:所謂反向索引,就是提前将搜尋的關鍵字建成索引,然後再根據索引查找文檔,也就是根據詞找文檔。
ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

這種先建立

索引

,再對索引進行

搜尋

文檔的過程就叫

全文檢索(Full-text Search)

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析
資料庫隻能做精确比對,不能分詞搜尋,并且效率低。

2.全文檢索場景

  • 搜尋引擎(對算法、資料結構要求較高)
  • 站内搜尋(直接使用ElasticSearch基本可以滿足)
  • 系統檔案搜尋

3.全文檢索相關技術

  1. Lucene:如果使用該技術實作,需要對Lucene的API和底層原理非常了解,而且需要編寫大量的Java代碼。
  2. Solr:使用java實作的一個web應用,可以使用rest方式的http請求,進行遠端API的調用。
  3. ElasticSearch(ES):可以使用rest方式的http請求,進行遠端API的調用。
Solr和ElasticSearch底層都是基于Lucene

4.Solr和ES的比較

ElasticSearch vs Solr 檢索速度

  • 當單純的對已有資料(靜态資料,不會發生變化的資料)進行搜尋時,Solr更快。
    ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析
  • 當實時建立索引時, Solr會産生io阻塞,查詢性能較差, Elasticsearch具有明顯的優勢。
    ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析
  • 随着資料量的增加,Solr的搜尋效率會變得更低,而Elasticsearch卻沒有明顯的變化。
    ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析
  • 大型網際網路公司,實際生産環境測試,将搜尋引擎從Solr轉到Elasticsearch以後的平均查詢速度有了50倍的提升。
    ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

總結:

  • 二者安裝都很簡單;
  • Solr 利用 Zookeeper 進行分布式管理,而 Elasticsearch 自身帶有分布式協調管理功能;
  • Solr 支援更多格式的資料,而 Elasticsearch 僅支援json檔案格式;
  • Solr 官方提供的功能更多,而 Elasticsearch 本身更注重于核心功能,進階功能都由第三方插件提供;
  • Solr 在傳統的搜尋應用中表現好于 Elasticsearch,但在處理實時搜尋應用時效率明顯低于Elasticsearch。

最終的結論:

Solr 是傳統搜尋應用的有力解決方案,但 Elasticsearch 更适用于新興的實時搜尋應用。

三、全文檢索的流程分析

1.什麼是索引

  有人可能會說,對非結構化資料順序掃描很慢,對結構化資料的搜尋卻相對較快(由于結構化資料有一定的結構可以采取一定的搜尋算法加快速度),那麼把我們的非結構化資料想辦法弄得有一定結構不就行了嗎?

  這種想法很天然,卻構成了全文檢索的基本思路,也即将非結構化資料中的一部分資訊提取出來,重新組織,使其變得有一定結構,然後對此有一定結構的資料進行搜尋,進而達到搜尋相對較快的目的。

  這部分從非結構化資料中提取出的然後重新組織的資訊,我們稱之索引

  這種說法比較抽象,舉幾個例子就很容易明白,比如字典,字典的拼音表和部首檢字表就相當于字典的索引,對每一個字的解釋都是非結構化的,如果字典沒有拼音表和部首檢字表,在茫茫辭海中找一個字隻能順序掃描。然而字的某些資訊可以提取出來進行結構化處理,比如讀音,就比較結構化,分聲母和韻母,分别隻有幾種可以 一一列舉,于是将讀音拿出來按一定的順序排列,每一項讀音都指向此字的詳細解釋的頁數。我們搜尋時按結構化的拼音搜到讀音,然後按其指向的頁數,便可找到 我們的非結構化資料——也即對字的解釋

2.流程總覽

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析
ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析
ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析
索引庫建立過程
ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析
索引庫搜尋過程
ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

全文檢索的流程分為兩大流程:索引建立、搜尋索引

  • 索引建立:将現實世界中所有的結構化和非結構化資料提取資訊,建立索引的過程。
  • 搜尋索引:就是得到使用者的查詢請求,搜尋建立的索引,然後傳回結果的過程。
ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

要想搞清楚全文檢索,必須要搞清楚下面三個問題:

  • 1.索引庫裡面究竟存些什麼?(Index)
  • 2.如何建立索引?(Indexing)
  • 3.如何對索引進行搜尋?(Search)

3.建立索引流程

3.1原始内容

原始内容是指要索引和搜尋的内容。

原始内容包括網際網路上的網頁、資料庫中的資料、磁盤上的檔案等。

3.2獲得文檔

也就是采集資料,從網際網路上、資料庫、檔案系統中等擷取需要搜尋的原始資訊,這個過程就是資訊采集。

采集資料的目的是為了将原始内容存儲到Document對象中。

如何采集資料?

  1. 對于網際網路上網頁,可以使用工具将網頁抓取到本地生成html檔案。
  2. 資料庫中的資料,可以直接連接配接資料庫讀取表中的資料。
  3. 檔案系統中的某個檔案,可以通過I/O操作讀取檔案的内容。

在Internet上采集資訊的軟體通常稱為爬蟲或蜘蛛,也稱為網絡機器人,爬蟲通路網際網路上的每一個網頁,将擷取到的網頁内容存儲起來。

3.3建立文檔對象

建立文檔的目的是統一資料格式(Document),友善文檔分析。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

說明:

1.一個Document文檔中包括多個域(Field),域(Field)中存儲内容。

2.這裡我們可以将資料庫中一條記錄當成一個Document,一列當成一個Field

3.4分析文檔(重點)

分析文檔主要是對Field域進行分析,分析文檔的目的是為了索引。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

說明:分析文檔主要通過分詞元件(Tokenizer)和語言處理元件(Linguistic Processor)完成

3.4.1分詞元件

分詞元件工作流程(此過程稱之為Tokenize)

  1. 将Field域中的内容進行分詞(不同語言有不同的分詞規則)
  2. 去除标點符号。
  3. 去除停用詞(stop word)。

經過分詞(Tokenize)之後得到的結果成為

詞元(Token)

所謂停用詞(Stop word)就是一種語言中最普通的一些單詞,由于沒有特别的意義,因而大多數情況下不能成為搜尋的關鍵詞,因而建立索引時,這種詞會被去掉而減少索引的大小。

英語中停詞(Stop word)如:“the”,“a”,“this”等。

對于每一種語言的分詞元件(Tokenizer),都有一個停詞(stop word)集合。

示例(Document1的Field域和Document2的Field域是同名的):

  • Document1的Field域:
    Students should be allowed to go out with their friends, but not allowed to drink beer.
  • Document2的Field域:
    My friend Jerry went to school to see his students but found them drunk which is not allowed.
  • 在我們的例子中,便得到以下詞元(Token):
    “Students”,“allowed”,“go”,“their”,“friends”,“allowed”,“drink”,“beer”,“My”,“friend”,“Jerry”,“went”,“school”,“see”,“his”,“students”,“found”,“them”,“drunk”,“allowed”。

将得到的詞元(Token)傳給語言處理元件(Linguistic Processor)

3.4.2語言處理元件

語言處理元件(linguistic processor)主要是對得到的詞元(Token)做一些同語言相關的處理。

對于英語,語言處理元件(Linguistic Processor)一般做以下幾點:

  • 1.變為小寫(Lowercase)。
  • 2.将單詞縮減為詞根形式,如“cars”到“car”等。這種操作稱為:stemming。
  • 3.将單詞轉變為詞根形式,如“drove”到“drive”等。這種操作稱為:lemmatization。

語言處理元件(linguistic processor)的結果稱為詞(Term)。

Term是索引庫的最小機關。

  • 在我們的例子中,經過語言處理,得到的詞(Term)如下:
    “student”,“allow”,“go”,“their”,“friend”,“allow”,“drink”,“beer”,“my”,“friend”,“jerry”,“go”,“school”,“see”,“his”,“student”,“find”,“them”,“drink”,“allow”。
    也正是因為有語言處理的步驟,才能使搜尋drove,而drive也能被搜尋出來。

3.5索引建立

索引的目的是為了搜尋。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

說明:将得到的詞(Term)傳給索引元件(Indexer),索引元件(Indexer)主要做以下幾件事情:

3.5.1建立Term字典

在我們的例子中字典如下:

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

3.5.2排序Term字典

對字典按字母順序進行排序

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

3.5.3合并Term字典

合并相同的詞(Term)成為文檔倒排(Posting List)連結清單

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

在此表中,有幾個定義:

  • Document Frequency 即文檔頻次,表示總共有多少檔案包含此詞(Term)。
  • Frequency 即詞頻率,表示此檔案中包含了幾個此詞(Term)。

到此為止,索引已經建立好了。

最終的索引結構是一種反向索引結構也叫反向索引結構,包括索引和文檔兩部分,索引即詞彙表,它的規模較小,而文檔集合較大。

反向索引結構是根據内容(詞彙)找文檔,如下圖:

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

3.6建立索引流程總結

分詞及檢索的詳細的流程:

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

上圖詳細示範了一下: 建立索引的過程 (此過程為

英文環境

下的索引庫建構過程,中文有一定差異)

4.搜尋索引流程

4.1查詢語句

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

4.2執行搜尋

4.2.1第一步:對查詢語句進行詞法分析、文法分析及語言處理。

1、詞法分析

如上述例子中,經過詞法分析,得到單詞有lucene,learned,hadoop, 關鍵字有AND, NOT。

注意:關鍵字必須大寫,否則就作為普通單詞處理。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

2、文法分析

如果發現查詢語句不滿足文法規則,則會報錯。如lucene NOT AND learned,則會出錯。

如上述例子,lucene AND learned NOT hadoop形成的文法樹如下:

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

3、語言處理

如learned變成learn等。

經過第二步,我們得到一棵經過語言處理的文法樹。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

4.2.2第二步:搜尋索引,得到符号文法樹的文檔。

1、 首先,在反向索引表中,分别找出包含lucene,learn,hadoop的文檔連結清單。

2、 其次,對包含lucene,learn的連結清單進行合并操作,得到既包含lucene又包含learn的文檔連結清單。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

3、 然後,将此連結清單與hadoop的文檔連結清單進行差操作,去除包含hadoop的文檔,進而得到既包含lucene又包含learn而且不包含hadoop的文檔連結清單。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

4、 此文檔連結清單就是我們要找的文檔。

ElasticSearch 基本原理之全文檢索一、開篇幾個問題二、全文檢索技術三、全文檢索的流程分析

4.2.3第三步:根據得到的文檔和查詢語句的相關性,對結果進行排序。

相關度自然打分(權重越高分越高):

  • tf越高、權重越高(tf代表該詞在文檔中出現的頻率)
  • df越高、權重越低(df代表包含該詞的文檔的數量)

人為影響分數:

  • 設定Boost值(權重值)

5.Lucene相關度排序

5.1什麼是相關度排序

相關度排序是查詢結果按照與查詢關鍵字的相關性進行排序,越相關的越靠前。比如搜尋“Lucene”關鍵字,與該關鍵字最相關的文章應該排在前邊。

5.2相關度打分

Lucene對查詢關鍵字和索引文檔的相關度進行打分,得分高的就排在前邊。

如何打分呢?Lucene是在使用者進行檢索時實時根據搜尋的關鍵字計算出來的,分兩步:

  1. 計算出詞(Term)的權重
  2. 根據詞的權重值,計算文檔相關度得分。

什麼是詞的權重?

通過索引部分的學習,明确索引的最小機關是一個Term(索引詞典中的一個詞)。搜尋也是從索引域中查詢Term,再根據Term找到文檔。Term對文檔的重要性稱為權重,影響Term權重有兩個因素:

  • Term Frequency (tf):

    指此Term在此文檔中出現了多少次。tf 越大說明越重要。

    詞(Term)在文檔中出現的次數越多,說明此詞(Term)對該文檔越重要,如“Lucene”這個詞,在文檔中出現的次數很多,說明該文檔主要就是講Lucene技術的。

  • Document Frequency (df):

    指有多少文檔包含此Term。df 越大說明越不重要。

    比如,在一篇英國文檔中,this出現的次數更多,就說明越重要嗎?不是的,有越多的文檔包含此詞(Term), 說明此詞(Term)太普通,不足以區分這些文檔,因而重要性越低。

5.3.設定boost值影響相關度排序

boost是一個權重值(預設權重值為1.0f),它可以影響權重的計算。在索引時對某個文檔中的field設定權重值,設定越高,在搜尋時比對到這個文檔就可能排在前邊。

6.Lucene的Field域

6.1Field屬性

Field是文檔中的域,包括Field名和Field值兩部分,一個文檔可以包括多個Field,Document隻是Field的一個承載體,Field值即為要索引的内容,也是要搜尋的内容。

屬性 可選值
是否分詞(tokenized)

* 是:作分詞處理,即将Field值進行分詞,分詞的目的是為了索引。

比如:商品名稱、商品描述等,這些内容使用者要輸入關鍵字搜尋,由于搜尋的内容格式大、内容多需要分詞後将語彙單元建立索引

* 否:不作分詞處理

比如:商品id、訂單号、身份證号等

是否索引(indexed)

* 是:進行索引。将Field分詞後的詞或整個Field值進行索引,存儲到索引域,索引的目的是為了搜尋。

比如:商品名稱、商品描述分析後進行索引,訂單号、身份證号不用分詞但也要索引,這些将來都要作為查詢條件。

* 否:不索引。

比如:圖檔路徑、檔案路徑等,不用作為查詢條件的不用索引

是否存儲(stored)

* 是:将Field值存儲在文檔域中,存儲在文檔域中的Field才可以從Document中擷取。

比如:商品名稱、訂單号,凡是将來要從Document中擷取的Field都要存儲。

* 否:不存儲Field值

比如:商品描述,内容較大不用存儲。如果要向使用者展示商品描述可以從系統的關系資料庫中擷取。

6.2Field常用類型

下邊列出了開發中常用 的Filed類型,注意Field的屬性,根據需求選擇:

Field類 資料類型 Analyzed 是否分詞 Indexed 是否索引 Stored 是否存儲 說明
StringField(FieldName, FieldValue,Store.YES)) 字元串 N Y Y或N 這個Field用來建構一個字元串Field,但是不會進行分詞,會将整個串存儲在索引中,比如(訂單号,身份證号等) 是否存儲在文檔中用Store.YES或Store.NO決定
LongField(FieldName, FieldValue,Store.YES) Long型 Y Y Y或N 這個Field用來建構一個Long數字型Field,進行分詞和索引,比如(價格) 是否存儲在文檔中用Store.YES或Store.NO決定
StoredField(FieldName, FieldValue) 重載方法,支援多種類型 N N Y 這個Field用來建構不同類型Field 不分析,不索引,但要Field存儲在文檔中
TextField(FieldName, FieldValue, Store.NO) 或 TextField(FieldName, reader) 字元串 或 流 Y Y Y或N 如果是一個Reader, lucene猜測内容比較多,會采用Unstored的政策.

6.3Field設計

Field域如何設計,取決于需求,比如搜尋條件有哪些?顯示結果有哪些?

字段 設計
商品id

是否分詞:不用分詞,因為不會根據商品id來搜尋商品

是否索引:不索引,因為不需要根據商品ID進行搜尋

是否存儲:要存儲,因為查詢結果頁面需要使用id這個值。

商品名稱

是否分詞:要分詞,因為要根據商品名稱的關鍵詞搜尋。

是否索引:要索引。

是否存儲:要存儲。

商品價格

是否分詞:要分詞,lucene對數字型的值隻要有搜尋需求的都要分詞和索引,因為lucene對數字型的内容要特殊分詞處理,需要分詞和索引。

是否索引:要索引

是否存儲:要存儲

商品圖檔位址

是否分詞:不分詞

是否索引:不索引

是否存儲:要存儲

商品描述

是否分詞:要分詞

是否索引:要索引

是否存儲:因為商品描述内容量大,不在查詢結果頁面直接顯示,不存儲。

常見問題:

不存儲是指不在lucene的索引域中記錄,目的是為了節省lucene的索引檔案空間。

如果要在詳情頁面顯示描述,解決方案:

從lucene中取出商品的id,根據商品的id查詢關系資料庫(MySQL)中item表得到描述資訊。

繼續閱讀