Elasticsearch:基本概念、安裝、快速開(kāi)始

摘要:Elasticsearch

《Elasticsearch搜索引擎構(gòu)建入門與實(shí)戰(zhàn)》第一章讀書筆記

Elasticsearch特色優(yōu)勢(shì)

  • 實(shí)時(shí)性好:相比于Lucene,新增的數(shù)據(jù)數(shù)秒甚至1秒(緩存)內(nèi)可以搜索到
  • 分布式架構(gòu)設(shè)計(jì):可以拓展到多臺(tái)機(jī)器進(jìn)行搜索
  • 提供REST風(fēng)格API,相比于Lucene需要Java開(kāi)發(fā),ES支持HTTP請(qǐng)求來(lái)進(jìn)行查詢
  • 提供了聚合查詢:ES可以對(duì)索引中的數(shù)據(jù)做聚合統(tǒng)計(jì)分析

Elasticsearch基本概念

  • 索引:要對(duì)進(jìn)行數(shù)據(jù)存儲(chǔ)和查詢操作需要先建立索引,ES中的索引相當(dāng)于傳統(tǒng)數(shù)據(jù)庫(kù)的庫(kù)
  • 文檔:相當(dāng)于傳統(tǒng)數(shù)據(jù)庫(kù)的一條記錄,就是ES中一個(gè)文檔,一個(gè)文檔可以包含一個(gè)或多個(gè)字段,每個(gè)字段可以有各種類型,文檔的初始版本是1,每次寫操作會(huì)自動(dòng)版本號(hào)+1,查詢時(shí)ES返回最大版本號(hào)的文檔
  • 字段:常見(jiàn)的類型包括字符串,文本,數(shù)值,還有ES提供其他類型,比如數(shù)組,地理經(jīng)緯,IP地址等,不同的數(shù)據(jù)類型ES支持不同的所有功能,比如文本可以基于分詞搜索,地理經(jīng)緯可以所有某點(diǎn)附近的文檔
  • 映射:映射就是定義的數(shù)據(jù)結(jié)構(gòu)schema,一旦設(shè)定之后不能更改,ES也提供了自動(dòng)映射的功能,如果要寫入的數(shù)據(jù)沒(méi)有給定類型ES會(huì)自動(dòng)推斷
  • 集群和節(jié)點(diǎn):多臺(tái)機(jī)器一起協(xié)作作為集群,ES集群的節(jié)點(diǎn)數(shù)不受限制,一個(gè)節(jié)點(diǎn)就對(duì)應(yīng)一臺(tái)機(jī)器
  • 分片:ES會(huì)對(duì)數(shù)據(jù)進(jìn)行切分存儲(chǔ)到多臺(tái)計(jì)算機(jī)中,均勻分?jǐn)倖闻_(tái)機(jī)器的存儲(chǔ)壓力,ES默認(rèn)一個(gè)索引5個(gè)分片,分片一定設(shè)置是不可以修改的,只能新建新索引解決一個(gè)節(jié)點(diǎn)可以被分配多個(gè)主分片。每個(gè)分片可以設(shè)置副分片,當(dāng)主分片故障離線時(shí)副分片會(huì)充當(dāng)主分片繼續(xù)提供服務(wù),保證了高可用
  • 副分片:在一個(gè)索引中主分片的副分片個(gè)數(shù)沒(méi)有限制,默認(rèn)ES不會(huì)啟用副分片。一個(gè)主分片的所有副分片都存儲(chǔ)在不同的機(jī)器上,保證一臺(tái)機(jī)器宕機(jī)的情況下,其他機(jī)器的副分片可以提供服務(wù)。因此如果只設(shè)置了一個(gè)ES節(jié)點(diǎn),且啟動(dòng)了至少一個(gè)副分片,實(shí)際上ES只會(huì)分配一個(gè)主分片,不會(huì)分配副分片

如上圖,三個(gè)主分片P0,P1,P2,各自的副分片R0,R1,R2都分別在另外的機(jī)器上,一個(gè)三個(gè)節(jié)點(diǎn)存儲(chǔ)分別分配了一個(gè)主分片,主分片的備份數(shù)量是1

  • DSL:領(lǐng)域特定語(yǔ)言,是用來(lái)定義查詢的,HTML,CSS,SQL都屬于DSL,ES中DSL使用JSON表達(dá),查詢的返回?cái)?shù)據(jù)也是JSON格式

Elasticsearch和傳統(tǒng)關(guān)系型數(shù)據(jù)庫(kù)對(duì)比

  • 索引方式不同:關(guān)系型數(shù)據(jù)庫(kù)大多是B-Tree索引,ES是倒排索引
  • 事務(wù)支持:ES不支持事務(wù)支持,ES使用樂(lè)觀鎖,不阻塞數(shù)據(jù)的更新操作,每次更新采用增加版本號(hào)的方式,導(dǎo)致某些更新操作可能失效,數(shù)據(jù)未更新成功。

悲觀鎖和樂(lè)觀鎖

  1. 悲觀鎖是基于一種悲觀的態(tài)度類來(lái)防止一切數(shù)據(jù)沖突,它是以一種預(yù)防的姿態(tài)在修改數(shù)據(jù)之前把數(shù)據(jù)鎖住,然后再對(duì)數(shù)據(jù)進(jìn)行讀寫,是一種串行的方式,只要開(kāi)始執(zhí)行就會(huì)鎖表,一般數(shù)據(jù)庫(kù)本身鎖的機(jī)制都是基于悲觀鎖的機(jī)制實(shí)現(xiàn)的
  2. 樂(lè)觀鎖是對(duì)于數(shù)據(jù)沖突保持一種樂(lè)觀態(tài)度,操作數(shù)據(jù)時(shí)不會(huì)對(duì)操作的數(shù)據(jù)進(jìn)行加鎖(這使得多個(gè)任務(wù)可以并行的對(duì)數(shù)據(jù)進(jìn)行操作),只有到數(shù)據(jù)提交的時(shí)候才通過(guò)一種機(jī)制來(lái)驗(yàn)證數(shù)據(jù)是否存在沖突(一般實(shí)現(xiàn)方式是通過(guò)加版本號(hào)然后進(jìn)行版本號(hào)的對(duì)比方式實(shí)現(xiàn)),樂(lè)觀鎖并不會(huì)真的加鎖,而是通過(guò)一些狀態(tài)的檢驗(yàn)達(dá)到操作互斥的效果
    例如有以下數(shù)據(jù)采用樂(lè)觀鎖的方式,用戶A,B分別查詢Name=zhangsan的這條記錄,并進(jìn)行修改再次寫入數(shù)據(jù)庫(kù)

    因?yàn)椴捎脴?lè)觀鎖,因此A,B都可以并行地拿到數(shù)據(jù),用戶A拿到之后將Name修改為lisi,在提交操作時(shí),數(shù)據(jù)庫(kù)會(huì)把之前查詢到的version與現(xiàn)在的數(shù)據(jù)的version進(jìn)行比較,版本相同則可以提交,版本不同則視為數(shù)據(jù)過(guò)期,過(guò)期則提交失敗,如以下SQL更新語(yǔ)句
    update A set Name=lisi,version=version+1 where ID=#{id} and version=#{version}
    更新成功后數(shù)據(jù)庫(kù)該記錄變?yōu)?br>

    此時(shí)用戶B將Name改為wangwu,再提交時(shí)會(huì)失敗,因?yàn)樽陨韛erson=1,而數(shù)據(jù)庫(kù)內(nèi)的version=2,數(shù)據(jù)過(guò)期
  • 查詢語(yǔ)句不同:關(guān)系型數(shù)據(jù)庫(kù)采用SQL,原因是查詢比較簡(jiǎn)單直接,ES采用DSL來(lái)完成比較復(fù)雜的查詢所有需求

  • 查詢速度:如果字段少,數(shù)據(jù)量不打,關(guān)系型數(shù)據(jù)庫(kù)查詢速度很快,但是單表有上百字段和幾十億條數(shù)據(jù)查詢速度就會(huì)變慢,隨著數(shù)據(jù)量的增長(zhǎng)速度越來(lái)越慢,ES可以支持對(duì)全字段做索引,單個(gè)索引存儲(chǔ)上百字段或幾十億條數(shù)據(jù)查詢速度都不會(huì)變慢

  • 數(shù)據(jù)的實(shí)時(shí)性:關(guān)系型數(shù)據(jù)庫(kù)是實(shí)時(shí)的,插入之后立馬可以查到,ES內(nèi)存中的數(shù)據(jù)先寫入緩存,默認(rèn)1s之后統(tǒng)一刷入磁盤,才能被ES查到,因此ES是準(zhǔn)實(shí)時(shí)的


Elasticsearch架構(gòu)原理

(1)節(jié)點(diǎn)的職責(zé)

節(jié)點(diǎn)按照職責(zé)可以分為master節(jié)點(diǎn)數(shù)據(jù)節(jié)點(diǎn),協(xié)調(diào)節(jié)點(diǎn),每個(gè)節(jié)點(diǎn)的角色可以單獨(dú)配置,默認(rèn)每臺(tái)機(jī)器都可以擔(dān)任這三種角色。

  • master節(jié)點(diǎn):維護(hù)ES集群工作,如創(chuàng)建刪除索引,節(jié)點(diǎn)上線下線,健康狀態(tài)監(jiān)測(cè)等,master通過(guò)選舉算法產(chǎn)生,在候選的機(jī)器中只能有一個(gè)master節(jié)點(diǎn),可以配置node.master為true將當(dāng)前節(jié)點(diǎn)作為master節(jié)點(diǎn)的候選
  • 數(shù)據(jù)節(jié)點(diǎn):負(fù)責(zé)數(shù)據(jù)保存,修改,刪除,查詢,數(shù)據(jù)節(jié)點(diǎn)的工作是調(diào)用Lucene庫(kù)進(jìn)行索引操作,對(duì)內(nèi)存和I/O消耗比較大
  • 協(xié)調(diào)節(jié)點(diǎn):負(fù)責(zé)對(duì)接客戶端請(qǐng)求,默認(rèn)情況下協(xié)調(diào)節(jié)點(diǎn)可以是集群中的任一節(jié)點(diǎn),當(dāng)一個(gè)請(qǐng)求開(kāi)始時(shí)該節(jié)點(diǎn)作為協(xié)調(diào)節(jié)點(diǎn)存在,請(qǐng)求結(jié)束該協(xié)調(diào)節(jié)點(diǎn)生命結(jié)束。協(xié)調(diào)節(jié)點(diǎn)將請(qǐng)求轉(zhuǎn)發(fā)給其他節(jié)點(diǎn),最終匯總結(jié)果輸出。為了降低集群負(fù)荷,可以設(shè)置某些節(jié)點(diǎn)作為單獨(dú)的協(xié)調(diào)節(jié)點(diǎn),將這些節(jié)點(diǎn)的node.masternode.data全部設(shè)置為false即可,所有的數(shù)據(jù)請(qǐng)求都會(huì)發(fā)到這些單獨(dú)設(shè)置的協(xié)調(diào)節(jié)點(diǎn),例如圖中的Client Node就是協(xié)調(diào)節(jié)點(diǎn)
(2)主分片和副分片

ES中索引由一個(gè)或多個(gè)分片組成,一個(gè)分片可以擁有0個(gè)或多個(gè)副分片,保證了高可用。

例如當(dāng)node1發(fā)生宕機(jī),P0消失,集群感知到P0消失之后會(huì)找到node3的R0充當(dāng)為新的P0,此時(shí)只有node2和node3對(duì)外提供服務(wù)。



當(dāng)node1恢復(fù)時(shí),node1上面的主分片和副分片會(huì)分別從node2,node3同步數(shù)據(jù),node1本來(lái)的P0變?yōu)镽0


(3)文檔讀寫流程

寫流程
ES協(xié)調(diào)節(jié)點(diǎn)接受客戶端請(qǐng)求,默認(rèn)根據(jù)文檔的_id值通過(guò)路由計(jì)算獲得目標(biāo)主分片,和主分片所在的節(jié)點(diǎn),將客戶端請(qǐng)求轉(zhuǎn)發(fā),寫入該節(jié)點(diǎn)的主分片,然后對(duì)于該主分片的副分片,分別找到所在的節(jié)點(diǎn)再寫入,等主副全部寫好了,ES協(xié)調(diào)節(jié)點(diǎn)告訴客戶端寫入完成

路由計(jì)算
路由計(jì)算的目的是對(duì)于客戶端發(fā)來(lái)的文檔,找到文檔要讀取或者寫入的主分片和主分片所在的節(jié)點(diǎn),實(shí)際上是計(jì)算的分片ID,公式如下
shard=hash(routing)%number_of_primary_shards
routing:客戶端提交的參數(shù),默認(rèn)是文檔的_id
number_of_primary_shards:索引中的主分片個(gè)數(shù)
相當(dāng)于就是對(duì)文檔hash取模計(jì)算出到底去哪個(gè)分片,計(jì)算出主分片ID之后,ES的協(xié)調(diào)節(jié)點(diǎn)上存儲(chǔ)了一份節(jié)點(diǎn)-分片的對(duì)照表,根據(jù)這個(gè)表找到主分片和副分片所在的機(jī)器節(jié)點(diǎn),找到節(jié)點(diǎn)進(jìn)行寫入操作

讀流程
當(dāng)客戶端收到請(qǐng)求文檔的讀取要求時(shí),同樣根據(jù)路由算法找到對(duì)應(yīng)的主分片,協(xié)調(diào)節(jié)點(diǎn)根據(jù)對(duì)照表找到所有該主分片以及對(duì)應(yīng)的副分片的節(jié)點(diǎn),然后使用輪詢算法從主/副中選取一個(gè),數(shù)據(jù)傳遞給協(xié)調(diào)節(jié)點(diǎn),再返回給客戶端

輪詢算法
輪詢算法是最簡(jiǎn)單的一種負(fù)載均衡算法。它的原理是把來(lái)自用戶的請(qǐng)求輪流分配給內(nèi)部的節(jié)點(diǎn),從節(jié)點(diǎn)1開(kāi)始,直到節(jié)點(diǎn)N,然后重新開(kāi)始循環(huán)。


Elasticsearch安裝

(1)單機(jī)安裝

進(jìn)入該網(wǎng)站下載對(duì)應(yīng)的壓縮包 https://www.elastic.co/cn/downloads/elasticsearch

開(kāi)始解壓

tar -zxvf elasticsearch-8.0.0-linux-x86_64.tar.gz
cd elasticsearch-8.0.0
ll
total 884
drwxr-xr-x  9 root root   4096 2月   4 00:55 ./
drwxr-xr-x 11 root root   4096 2月  26 19:37 ../
drwxr-xr-x  2 root root   4096 2月   4 00:55 bin/
drwxr-xr-x  3 root root   4096 2月  26 19:37 config/
drwxr-xr-x  9 root root   4096 2月   4 00:55 jdk/
drwxr-xr-x  3 root root   4096 2月   4 00:55 lib/
-rw-r--r--  1 root root   3860 2月   4 00:47 LICENSE.txt
drwxr-xr-x  2 root root   4096 2月   4 00:52 logs/
drwxr-xr-x 65 root root   4096 2月   4 00:55 modules/
-rw-r--r--  1 root root 858789 2月   4 00:52 NOTICE.txt
drwxr-xr-x  2 root root   4096 2月   4 00:52 plugins/
-rw-r--r--  1 root root   2710 2月   4 00:47 README.asciidoc

ES不允許root用戶啟動(dòng),需要?jiǎng)?chuàng)建一個(gè)用戶,并且將整個(gè)目錄修改擁有者為該用戶

root@ubuntu:/opt/elasticsearch-8.0.0# useradd  -s /bin/bash /us^C
root@ubuntu:/opt/elasticsearch-8.0.0# useradd -s /bin/bash -m es
root@ubuntu:/opt/elasticsearch-8.0.0# passwd es
Enter new UNIX password: 
Retype new UNIX password: 
passwd: password updated successfully
root@ubuntu:/opt/elasticsearch-8.0.0# su es

修改擁有者

root@ubuntu:/opt/elasticsearch-8.0.0# chown -R es /opt/elasticsearch-8.0.0

es默認(rèn)配置進(jìn)程占用內(nèi)存1GB,如果機(jī)器內(nèi)存不足可以修改配置

# 打開(kāi) confog/jvm.options
-Xms512m
-Xmx512m

關(guān)閉ssl認(rèn)證和用戶名密碼認(rèn)證

# config/elasticsearch.yml
xpack.security.http.ssl:
  enabled: false

xpack.security.enabled: false

下面啟動(dòng)es

root@ubuntu:/opt/elasticsearch-8.0.0/bin# su - es
es@ubuntu:~$ cd /opt/elasticsearch-8.0.0/bin/
es@ubuntu:/opt/elasticsearch-8.0.0/bin$ ./elasticsearch

http訪問(wèn)9200端口

root@ubuntu:~# curl http://127.0.0.1:9200
{
  "name" : "ubuntu",
  "cluster_name" : "elasticsearch",
  "cluster_uuid" : "9T7jMwqUR_qSchEC6Hpn0w",
  "version" : {
    "number" : "8.0.0",
    "build_flavor" : "default",
    "build_type" : "tar",
    "build_hash" : "1b6a7ece17463df5ff54a3e1302d825889aa1161",
    "build_date" : "2022-02-03T16:47:57.507843096Z",
    "build_snapshot" : false,
    "lucene_version" : "9.0.0",
    "minimum_wire_compatibility_version" : "7.17.0",
    "minimum_index_compatibility_version" : "7.0.0"
  },
  "tagline" : "You Know, for Search"
}

目錄下新增的data目錄就是存儲(chǔ)索引數(shù)據(jù)的文件

(2)安裝Kibana

Kibana提供ES的查詢可視化功能,同時(shí)提供DEV Tools,可以與ES進(jìn)行交互請(qǐng)求。Kibana版本最好es版本一致

wget https://artifacts.elastic.co/downloads/kibana/kibana-8.0.0-linux-x86_64.tar.gz

解壓,求改擁有者

tar -zxvf kibana-8.0.0-linux-x86_64.tar.gz
mv kibana-8.0.0 /opt/
chown -R es /opt/kibana-8.0.0

在kibana的配置文件中,默認(rèn)elasticsearch.hosts為對(duì)應(yīng)的ES HTTP服務(wù)地址

#elasticsearch.hosts: ["http://localhost:9200"]

如果允許其他計(jì)算機(jī)訪問(wèn)kibana,修改server.host為0.0.0.0

#server.host: "localhost"

然后先啟動(dòng)es,再啟動(dòng)kibana

es@ubuntu:/opt/kibana-8.0.0$ cd bin/
es@ubuntu:/opt/kibana-8.0.0/bin$./kibana

http端口號(hào)5601打開(kāi)kibana界面


Elasticsearch快速開(kāi)始

以下操作全部基于kibana的console

(1)創(chuàng)建索引

通過(guò)PUT請(qǐng)求,JSON中定義mappings,三個(gè)字段分別是text(文本),keyword(關(guān)鍵詞),double(小數(shù))類型

PUT /my_index
{
  "mappings": {
   "properties": {
      "title":{
         "type": "text"
     },
     "city":{
         "type": "keyword"
     },
     "price": {
         "type": "double"
     }
   }
  }
}
(2)寫入文檔

使用POST請(qǐng)求,加入請(qǐng)求體JSON數(shù)據(jù),指定文檔的_id為001

POST /my_index/_doc/001
{
  "title":"好再來(lái)酒店",
  "city": "青島",
  "price": 578.23
}
(3)根據(jù)_id搜索文檔

使用GET請(qǐng)求,在請(qǐng)求路由中指定_id

GET /my_index/_doc/001

查看返回結(jié)果,顯示了該文檔的_id,_version(版本號(hào)1),_source(返回的字段)

{
  "_index" : "my_index",
  "_id" : "001",
  "_version" : 1,
  "_seq_no" : 0,
  "_primary_term" : 1,
  "found" : true,
  "_source" : {
    "title" : "好再來(lái)酒店",
    "city" : "青島",
    "price" : 578.23
  }
}
(4)根據(jù)一般字段搜索文檔

進(jìn)行復(fù)雜搜索時(shí)需要用到GET請(qǐng)求的_search路由和query請(qǐng)求體,本例查找price是578.23 的文檔,使用term搜索

GET /my_index/_search
{
  "query": {
    "term": {
       "price": {
         "value": 578.23  
        }
     }
  }
}

看一下返回

{
  "took" : 1,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 1.0,
    "hits" : [
      {
        "_index" : "my_index",
        "_id" : "001",
        "_score" : 1.0,
        "_source" : {
          "title" : "好再來(lái)酒店",
          "city" : "青島",
          "price" : 578.23
        }
      }
    ]
  }
}

返回結(jié)果除了文檔詳情之外還顯示了_shards分片信息,一共一個(gè)分片,hits信息一共一條符合要求的文檔

(5)文本字段搜索

文本模糊搜索需要使用query中的match關(guān)鍵字

GET /my_index/_search
{
  "query": {
    "match": {
       "title":  "好再" 
     }
  }
}

查看返回結(jié)果

{
  "took" : 5,
  "timed_out" : false,
  "_shards" : {
    "total" : 1,
    "successful" : 1,
    "skipped" : 0,
    "failed" : 0
  },
  "hits" : {
    "total" : {
      "value" : 1,
      "relation" : "eq"
    },
    "max_score" : 0.5753642,
    "hits" : [
      {
        "_index" : "my_index",
        "_id" : "001",
        "_score" : 0.5753642,
        "_source" : {
          "title" : "好再來(lái)酒店",
          "city" : "青島",
          "price" : 578.23
        }
      }
    ]
  }
}

返回來(lái)對(duì)應(yīng)的文檔,耗費(fèi)了5ms(took關(guān)鍵字)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容