Elasticsearch 分享 --- 基礎篇


【理論部分】

一、什么是Elasticsearch?

        首先Elasticsearch 是一個基於Lucene的搜索服務器,而 Lucene是 一個基於java開發的全文檢索引擎的架構
       下面是官網對Elaticsearch的介紹:
               Actionable Insight at Your Fingers
                          Distributed, scalable, and highly available
                         Real-time search and analytics capabilities
                         Sophisticated RESTful API
         我們可以看到上面描述es的一些特性:具備分布式能力和相應功能,實時搜索和分析,支持現在流行的RESTful 架構風格。而分布式讓他對大數據也能很好的支持,對 RESTful  的支持讓任何語言都可以訪問。
         所以我對它的理解是:

一個采用Restful API標准的高擴展性高可用性實時數據分析的全文搜索工具。

 

二、Elasticsearch的用途

         上面也提到了,elasticsearch的主語是全文搜索工具,所以他就是干全文搜索用的。
         下面是一些使用案例:

i) Github

“Github使用Elasticsearch搜索20TB的數據,包括13億的文件和1300億行的代碼”

這個不用介紹了吧,碼農們都懂的,Github在2013年1月升級了他們的代碼搜索,由solr轉為elasticsearch,目前集群規模為26個索引存儲節點和8個客戶端節點(負責處理搜索請求),詳情請看官方博客https://github.com/blog/1381-a-whole-new-code-search

ii)  Mozilla

Mozilla公司以火狐著名,它目前使用 WarOnOrange 這個項目來進行單元或功能測試,測試的結果以 json的方式索引到elasticsearch中,開發人員可以非常方便的查找 bug。
Socorro是Mozilla 公司的程序崩潰報告系統,一有錯誤信息就插入到 Hbase和Postgres 中,然后從 Hbase中讀取數據索引到elasticsearch中,方便查找。

http://blog.itpub.net/attachment/201403/14/16907020_1394762149yiIp.png

三、Elasticsearch 名詞解釋

i) 在數據層面主要有:
  • Index:Elasticsearch用來存儲數據的邏輯區域,它類似於關系型數據庫中的db概念。一個index可以在一個或者多個shard上面,同時一個shard也可能會有多個replicas。必須小寫
  • Document:Elasticsearch里面存儲的實體數據,類似於關系數據中一個table里面的一行數據。
document由多個field組成,不同的document里面同名的field一定具有相同的類型。document里面field可以重復出現,也就是一個field會有多個值,即multivalued。區分大小寫
  • Document type:為了查詢需要,一個index可能會有多種document,也就是document type,但需要注意,不同document里面同名的field一定要是相同類型的。相當於數據庫里的一個表。 (區分大小寫,且里面的field也區分大小寫
  • Document id : 唯一,相當於數據庫主鍵。
  • Mapping:存儲field的相關映射信息,不同document type會有不同的mapping。

 

ii) 在服務層面主要有:

  • Node: 一個server實例。
  • Cluster:多個node組成cluster。
  • Shard:數據分片,一個index可能會存在於多個shards,不同shards可能在不同nodes。
  • Replica:shard的備份,有一個primary shard,其余的叫做replica shards。
 
 
 

【實踐部分】

四、Elasticsearch 的安裝部署啟動

 
         一些基本的認識我們都有了,下面就開始實踐了,由於es一般都是運行在linux里的,我們現在就在linux下部署一個elasticsearch服務(特別需要注意的,elasticsearch1.x 和 2.x 有非常大的區別,我下面講的都是2.x的)
 
1、環境
    elasticesearch依賴java環境,需要jre7以上。
 
2、下載
    在官網下載tar.gz格式壓縮包
 
3、解壓安裝
     elasticesearch只需要解壓就行,解壓到相應目錄
[boss@localhost ~]$ mkdir elasticesearch
[boss@localhost ~]$ cd elasticesearch/
[boss@localhost elasticesearch]$ tar xzf elasticsearch-2.3.5.tar.gz
 
4、啟動
啟動的時候最好添加jvm參數 ./elasticsearch -Xms512m -Xmx512m
[boss@localhost elasticesearch]$ cd bin/
[boss@localhost bin]$ ./elasticsearch
 
5、問題
 測試環境是在公司虛擬機上,jdk 1.7.0_45,啟動報錯,需要升級jdk,貌似是jvm的bug。
在官網上看到這么一句話需要java 8 update 20 for later, or java 7 update 55 or later version.否則有bug.,甚至導致數據丟失
 
至於windows下的安裝部署啟動在這就不介紹了,具體請看另外一篇《Elasticesearch在Windows的安裝運行》
 
關於elasticsearch集群:只要在相同是host下,且配置文件中的cluster.name相同的節點,就會組成一個集群
 

五、Elasticsearch 目錄、配置信息解釋

 i) 安裝的目錄布局如下:

 Type

 Description

 Default Location

 Setting

 home

 elasticsearch 安裝目錄        path.home

 bin

 二進制腳本,包括elasticsearch啟動節點  {path.home}/bin  

 conf

 配置文件路徑,包含elasticsearch.yml  {path.home}/config  path.conf

 data

 在節點上每個索引/碎片的數據文件的位置。可以有多個目錄。  {path.home}/data  path.data

 work

 零時文件目錄(工作目錄)  {path.home}/work  path.work

 logs

 日志文件目錄  {path.home}/logs  path.logs 

 

    如果有多個數據目錄,可以允許使用數據分拆技術,將數據能夠按照設置放在不同的磁盤上。這個分拆原來是很簡單的,只是保證一個文件完整的存在一個地方,具體是如果選擇存在那個磁盤上是通過 index.store.distributor來配置的:

  1. least_used(默認):總是選擇可用空間最大的目錄。
  2. random:隨機選擇的目錄。選擇一個特定的目錄的概率,是與這個目錄中可用空間量成正比。

 

    注意,在相同的數據上沒有多個副本,在這一點上,它的類似 raid 0。 雖然簡單,但是它應該提供一個好的解決方案,對於不想使用 raid的人 。
 
 ii) 配置文件
    Elasticsearch的配置文件在 conf 目錄下,有兩個.yml文件,一個是elasticsearch.yml,另一個是logging.yml。
    其中 elasticsearch.yml是對 elasticsearch的配置; logging.yml是對 elasticsearch日志的配置,也就是對log4j的配置。
    我們這里講 elasticsearch.yml,文件中都比較詳細的英文解釋,所以我就說說比較重要的幾個配置:
  1. cluster.name:          elasticsearch天然具備集群能力,所以這里就有一個集群名稱配置,默認為elasticsearch,最好修改下。
  2. node.name:           節點名稱,也就是集群中的各個節點的名稱,也需要配置,方便以后管理和java api開發
  3. network.host:         允許訪問的host,可以是ipv4也可以是ipv6形式,在es2.x下如果不配,那么就只能localhost訪問了。
  4. http.port           http端口號,用於restful、插件的訪問端口,默認9200,不能重復
  5. transport.tcp.port:      通訊端口,java api 訪問的就是這個端口,默認9300,不能重復
  6. discovery.zen.ping.unicast.hosts:    這個是集群啟動的時候,默認發現的主機列表,然后通過這里的host再去發現別的節點,需要至少配置一個,不然好像有點問題,我在集群搭建的時候就因為沒配置遇到一些意外情況。
  7. discovery.zen.minimum_master_nodes:   最小的master選舉人數,默認為2,這種形式計算(total number of nodes /2+1)
  8. discovery.zen.ping.multicast.enabled自動發現節點開關,如果為false,則新加入的節點不會被發現。
  9. discovery.zen.ping.timeout:       自動發現超時時間。
 

六、Elasticsearch插件安裝

1、head插件:         
          對於Elasticsearch這種為分布式集群而生的,沒有一個管理工具的話,會無從下手,所以我們需要安裝一些插件來輔助,經典的插件是 head插件,marvel插件。其中marvel插件是對開發者免費,另外好像要收費,而且我沒安裝成功過... 所以我們使用head插件。
         在杭州的同事可以訪問  http://10.10.100.104:9200/_plugin/head/ 來查看, 界面如下:
alpha-application為集群名稱
集群健康值:分為綠、黃、紅。綠是表示正常;黃色表示部分異常,可以搜索,但是增刪改備份什么的會有異常,數據會丟失;紅色表示連搜索也不行了。
上面一個集群有兩個節點,分別是node-alpha-0、node-alpha-1。其中node-alpha-0為master。
上面有5個index,每個index都有5個分片。
 
2、 analysis-ik插件:
    首先得介紹一個概念:在檢索數據中,有一個概念  analysis,中文為 分詞
    比如一句話 I want to a be a bird。  如果不分詞,那么每個字母都是搜索的關鍵詞。這樣就無法搜索了。es默認有分詞,但是它對英文分詞支持很好,對中文就很爛了。
    比如 “我國是發展中國家”,es 對他的分詞就是每個漢字,這當然不行,理想的分詞是 我國、是、 發展、 發展中、國家。
    因此我們需要 ik 插件,ik插件對中文分詞有很好的支持。
安裝步驟:
1、下載相應版本的ik。 https://github.com/medcl/elasticsearch-analysis-ik 
2、因為下載的是源代碼,使用maven編譯,方法是在cd 到解壓目錄下 mvn package 編譯
3、 步驟和解壓  target/releases/elasticsearch-analysis-ik-{version}.zip 到 your-es-root/plugins/ik

4、重啟elasticsearch。這點很重要,我就因為沒有重啟折騰了一上午。

 
3、analysis-ik-pinyin插件:
    說完了中文分詞插件,不可避免的需要拼音插件了,analysis-ik-pinyin這個插件是我找了很久覺得比較好的中文拼音插件。
安裝插件需要將 elasticsearch-analysis-lc-pinyin的源碼自己maven  build出來,這樣可以避免版本沖突
 
現在網上沒有找到有關2.X的插件安裝和配置介紹,我摸索了很久才完成,這里記錄下:
 

編譯安裝:

首先是build源碼,使用將目錄切到相應目錄,我的是:
cd F:\software\elasticsearch-analysis-lc-pinyin-dev_2.2.2\elasticsearch-analysis-lc-pinyin
然后執行maven build命令(當然,前提是你安裝了maven,並配置好環境變量)
mvn package
然后就等待他的編譯,完成時會在..\elasticsearch-analysis-lc-pinyin\target\releases目錄下生產一個zip,我們只需將這個zip解壓到elasticsearch的plugin目錄下即可。

配置使用:

lc 2.x是不需要在 elasticsearch.yml里配置的,我們只需要重啟 elasticsearch實例即可。
關鍵就是在於使用上mapping和DSL的配置。
由於elasticsearch 1.x和2.x改動很大,所以我這里直接貼2.x的mapping配置了:
curl -XPUT http://localhost:9200/addr
curl -XPOST http://localhost:9200/addr/std/_mapping -d'
 {
  "std": {
    "properties": {
      "detail_name": {
        "type": "string",
        "analyzer": "lc_index",
        "search_analyzer": "lc_search",
        "fields": {
          "cn": {
            "type": "string",
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word"
          }
        }
      },
      "door_name": {
        "type": "string",
        "analyzer": "lc_index",
        "search_analyzer": "lc_search",
        "fields": {
          "cn": {
            "type": "string",
            "analyzer": "ik_max_word",
            "search_analyzer": "ik_max_word"
          }
        }
      }
    }
  }
}
'
主要問題是在於,1.x是 index_analyzer 為 lc_index ,但是2.x 沒有了 index_analyzer  這個參數。
接下來就和1.x差不多了。
 
4、sql插件:
          這個插件可以讓不熟悉curl命令的人使用sql語句查詢。
          具體方法就不介紹了,github里都有: https://github.com/NLPchina/elasticsearch-sql/  
 
5、elasticsearch-jdbc插件:
    這是一個數據庫(mysql/oracle...)和 elasticsearch 同步的插件,並且支持實時同步(但是不同步物理刪除的數據)。
    下載安裝相應版本即可。
    不過它的同步是通過腳本實現的,linux為.sh,windows下為.bat。
    需要說明的是,該插件提供了mysql的樣例,oracle的沒有提供,下面是我寫的oracle的腳本,由於不是很熟悉linux命令,有些參數沒有使用到。
    
#!/bin/sh
# This example is a template to connect to Oracle
# The JDBC URL and SQL must be replaced by working ones.
DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
bin=${DIR}/../bin
lib=${DIR}/../lib
JAVA_HOME="/opt/java/jdk1.8.0_101"
echo '
{
    "type" : "jdbc",
    "jdbc" : {
        "url" : "jdbc:oracle:thin:@//***.***.***.***:1521/***",
        "connection_properties" : {
            "oracle.jdbc.TcpNoDelay" : false,
            "useFetchSizeWithLongColumn" : false,
            "oracle.net.CONNECT_TIMEOUT" : 10000,
            "oracle.jdbc.ReadTimeout" : 50000
        },
        "user" : "pboss",
        "password" : "******",
        "sql" : "select std_addr_id as \"_id\",std_addr_id as \"std_addr_id\", name as \"door_name\", detail_name as \"detail_name\" from addr_std_addr",
        "index" : "addr",
        "type" : "std",
        "elasticsearch" : {
            "cluster" : "alpha-application",
            "host" : "10.10.100.104",
            "port" : 9300
        },
        "max_bulk_actions" : 20000,
        "max_concurrent_bulk_requests" : 10,
        "index_settings" : {
            "index" : {
                "number_of_shards" : 1,
                "number_of_replica" : 0
            }
        }
    }
}
' | ${JAVA_HOME}/bin/java \
    -cp "${lib}/*" \
    -Dlog4j.configurationFile=${bin}/log4j2.xml \
    org.xbib.tools.Runner \
    org.xbib.tools.JDBCImporter

 

 
上面的url即 jdbc驅動的url,user 和password 是相應數據庫的登錄名密碼。
上面的腳本是一次性同步,實時同步需要加如一些參數。
        "interval":            "1800", 這里是同步數據的頻率 1800s,半小時,可以按需要設成 1s或其它
        "schedule" :           "0 0/60 0-23 ? * *",   同步數據任務  60分鍾一次
        "flush_interval" :     "5s",    刷新間隔為5S    

 

 
具體關於這個插件的使用,請看《elasticsearch-jdbc 插件說明》
 
 
 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM