Elasticsearch 分享 --- 基礎篇

【理論部分】

1、什麼是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標準的高擴展性高可用性實時數據分析的全文搜索工具。

 

2、Elasticsearch的用途

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

i) Githubjava

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

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

ii)  Mozilla

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

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

3、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) 在服務層面主要有:linux

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

【實踐部分】

4、Elasticsearch 的安裝部署啓動

 
         一些基本的認識咱們都有了,下面就開始實踐了,因爲es通常都是運行在linux裏的,咱們如今就在linux下部署一個elasticsearch服務(特別須要注意的,elasticsearch1.x 和 2.x 有很是大的區別,我下面講的都是2.x的)
 
一、環境
    elasticesearch依賴java環境,須要jre7以上。
 
二、下載
    在官網下載tar.gz格式壓縮包
 
三、解壓安裝
     elasticesearch只須要解壓就行,解壓到相應目錄
[boss@localhost ~]$ mkdir elasticesearch
[boss@localhost ~]$ cd elasticesearch/
[boss@localhost elasticesearch]$ tar xzf elasticsearch-2.3.5.tar.gz
 
四、啓動
啓動的時候最好添加jvm參數 ./elasticsearch -Xms512m -Xmx512m
[boss@localhost elasticesearch]$ cd bin/
[boss@localhost bin]$ ./elasticsearch
 
五、問題
 測試環境是在公司虛擬機上,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相同的節點,就會組成一個集羣
 

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

 i) 安裝的目錄佈局以下: git

 Type github

 Description sql

 Default Location 數據庫

 Setting json

 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:       自動發現超時時間。
 

6、Elasticsearch插件安裝

一、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個分片。
 
二、 analysis-ik插件:
    首先得介紹一個概念:在檢索數據中,有一個概念  analysis,中文爲 分詞
    好比一句話 I want to a be a bird。  若是不分詞,那麼每一個字母都是搜索的關鍵詞。這樣就沒法搜索了。es默認有分詞,可是它對英文分詞支持很好,對中文就很爛了。
    好比 「我國是發展中國家」,es 對他的分詞就是每一個漢字,這固然不行,理想的分詞是 我國、是、 發展、 發展中、國家。
    所以咱們須要 ik 插件,ik插件對中文分詞有很好的支持。
安裝步驟:
一、下載相應版本的ik。 https://github.com/medcl/elasticsearch-analysis-ik 
二、由於下載的是源代碼,使用maven編譯,方法是在cd 到解壓目錄下 mvn package 編譯
三、 步驟和解壓  target/releases/elasticsearch-analysis-ik-{version}.zip 到 your-es-root/plugins/ik

四、重啓elasticsearch。這點很重要,我就由於沒有重啓折騰了一上午。

 
三、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差很少了。
 
四、sql插件:
          這個插件可讓不熟悉curl命令的人使用sql語句查詢。
          具體方法就不介紹了,github裏都有: https://github.com/NLPchina/elasticsearch-sql/  
 
五、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 插件說明》
相關文章
相關標籤/搜索