爲elasticSearch開發c++接口

1、    ElasticSearch是什麼

ElasticSearch是目前開源全文搜索引擎的首選,能夠快速存儲,搜索和分析海量數據。Stack Overflow,Github等都在使用。html

Elasticsearch 是使用 Java 編寫的,它的內部使用 Lucene 作索引與搜索,可是它使全文檢索變得簡單, 經過隱藏 Lucene 的複雜性,取而代之的提供一套簡單一致的 RESTful API。java

    ES提供的Client API:https://www.elastic.co/guide/en/elasticsearch/client/index.htmlnode

包含多種語言:python

注意:沒有C++接口,而咱們須要基於c++操做ESlinux

2、    安裝部署

1.   服務器選擇

設備IP:10.3.246.224c++

系統:linux-64git

磁盤空間:無  (df –h 發現磁盤沒容量了)github

2.   解決磁盤佔滿

du -sh /* | sort –nr  :找出系統中佔容量最大的文件夾,系統中15scpp這個文件夾佔41Gweb

 

du -sh /15scpp/* | sort -nr  :找出15scpp中佔容量最大文件夾15scpp_testbin,佔31G算法

 

確認這個文件夾已無用,rm刪除

 

PS:在Linux中,當咱們使用rm在linux上刪除了大文件,可是若是有進程打開了這個大文件,卻沒有關閉這個文件的句柄,那麼linux內核仍是不會釋放這個文件的磁盤空間。找出文件使用進程,kill掉,便可

3.   JDK8安裝

Elastic 須要 Java 8 環境

Java –version查看java是否安裝或如今版本

官網下載jdk-8u181-linux-x64.tar.gz,解壓,安裝,設置環境變量,這裏就不贅述。

1.   下載ES

下載https://www.elastic.co/downloads/elasticsearch :

elasticsearch-6.3.2.tar.gz

tar解壓

 

2.   建立新用戶

由於安全問題elasticsearch 不讓用root用戶直接運行,因此要建立新用戶:

adduser pwrd-es

passwd pwrd-es pwrd-es

3.   修改安裝文件權限

chown -R pwrd-es:pwrd-es /home/elasticSearch/elasticsearch-6.3.2

//由於安全問題,不讓root用戶執行安裝,可是其餘用戶又沒有文件操做權限,故而改之

4.  修改ES配置

Vim config/elasticSearch.yml

cluster.name: pwrd-es   //Elasticsearch會自動發如今同一網段下的Elasticsearch 節點,用這個屬性來區分不一樣的集羣,cluster.name相同則自動組建成一個集羣

node.name: node-1   //節點名,默認隨機指定一個name列表中名字,不能重複

node.master: true      //指定該節點是否有資格被選舉成爲node,默認是true,es是默認集羣中的第一臺機器爲master,若是這臺機掛了就會從新選舉master

node.data: true  //指定該節點是否存儲索引數據,默認爲true

path.data: /home/elasticSearch/log_export/data   //存儲數據

path.logs: /home/elasticSearch/log_export/logs   //存儲日誌

#index.number_of_shards: 5 // 設置默認索引分片個數,默認爲5片

#index.number_of_replicas: 1 //設置默認索引副本個數,默認爲1個副本

network.host: 10.3.246.222 #該參數用於同時設置bind_host和publish_host

network.bind_host: 0.0.0.0 #設置綁定的IP地址,能夠是IPV4或者IPV6

network.publish_host: 10.3.246.222 #設置其餘節點與該節點交互的IP地址

http.port: 9200

transport.tcp.port: 9300 #節點之間交互端口

transport.tcp.compress: true #設置是否壓縮tcp上交互傳輸的數據

http.max_content_length: 100mb #設置http內容的最大大小

http.enabled: true #是否開啓http服務對外提供服務

# --------------------------------- Discovery ----------------------------------

# Pass an initial list of hosts to perform discovery when new node is started:

# The default list of hosts is ["127.0.0.1", "[::1]"]

#設置集羣中的Master節點的初始列表,能夠經過這些節點來自動發現其餘新加入集羣的節點

discovery.zen.ping.unicast.hosts: ["10.3.246.224", "10.3.246.223"]

# Prevent the "split brain" by configuring the majority of nodes (total number of master-eligible nodes / 2 + 1): 爲了防止「腦裂」(master-slave分佈式中核心難點),設置最低主節點數

discovery.zen.minimum_master_nodes: 2  #集羣中三個節點

5.   修改系統最大虛擬內存

vim /etc/sysctl.conf

vm.max_map_count = 655360

sysctl -p

 

6.   切換用戶執行程序

切換用戶: su pwrd-es

./elasticsearch

 

 

7.   驗證安裝效果

瀏覽器中輸入10.3.246.224:9200

或者

curl 'http://localhost:9200/?pretty'   

能夠看到一個json數據,即爲安裝成功

PS:pretty是爲了json格式化,以致於返回的結果好看一些

1、    基本概念

1.   Node 與 Cluster

Elastic 本質上是一個分佈式數據庫,容許多臺服務器協同工做,每臺服務器能夠運行多個 Elastic 實例。

單個 Elastic 實例稱爲一個節點(node)。一組節點構成一個集羣(cluster)

經過cluster.name 屬性配置集羣的名字,用於惟一標識一個集羣,不一樣的集羣,其cluster.name 不一樣,集羣名字相同的全部節點自動組成一個集羣。當啓動一個結點時,該結點會在當前局域網內自動尋找相同集羣名字的主結點;若是找到主結點,該結點加入集羣中;若是未找到主結點,該結點成爲主結點

2.   Index

ES基本結構是 : index/type/id -> document (通常以json樣式存儲數據)

因此Index(索引)是Elastic 數據管理的頂層單位,它是單個數據庫的同義詞。

ES會索引全部字段,通過處理後寫入一個反向索引(Inverted Index)。查找數據的時候,直接查找該索引。

PS:每一個 Index (即數據庫)的名字必須是小寫。

 

能夠用以下命令,查看當前節點索引:

curl -X GET 'http://localhost:9200/_cat/indices?v'

3.   Document

Index裏面單條的記錄稱爲 Document(文檔)。許多條 Document 構成了一個 Index。

Document 使用 JSON 格式表示,以下:

{

    「name」:」張三」,

     「age」:18,

     「sex」:」male」

}

PS:對於json的編寫與格式是否正確,能夠藉助在線json工具:http://www.bejson.com/

4.   Type

Type能夠用來分類document,好比,china/Beijing/id-i ->doc-n

                                                  china/shanghai/id-j ->doc-m

同一個Index下不一樣的 Type 應該有類似的結構。

可是,Elastic 6.x 版只容許每一個 Index 包含一個 Type,7.x 版將會完全移除 Type。

咱們部署的是當前最新6.3.2版本

 

 

5.   Shared分片

當一個索引下的數據太多,超過單一節點所能提供的磁盤空間,ES提供分片功能,能夠將海量數據分片存儲到集羣中不一樣的節點中。當你查詢的索引分佈在多個分片上時,ES會把查詢發送給每一個相關的分片,並將結果組合在一塊兒,而應用程序並不知道分片的存在。即:這個過程對用戶來講是透明的。

 

6.   Replicas副本

爲提升查詢吞吐量或實現高可用性,可使用分片副本。

副本是一個分片的精確複製,每一個分片能夠有零個或多個副本。ES中能夠有許多相同的分片,其中之一被選擇更改索引操做,這種特殊的分片稱爲主分片。

當主分片丟失時,如:該分片所在的數據不可用時,集羣將副本提高爲新的主分片。

 

7.  ES數據架構概念與Mysql對比

 

可是目前type即將做廢。

4、    CRUD簡介

1.   建立索引

curl -XPUT "http://10.3.246.224:9200/tests/"

返回數據

{

       "acknowledged": true,

       "shards_acknowledged": true,

       "index": "testes"

}

2.   添加數據

curl -XPUT "http://10.3.246.224:9200/tests/songs/1" -d '{"name":"deck the halls","year":"2018","month":"8"}' 會報錯,以下指定header就能夠了

 

curl -H "Content-Type: application/json" -XPUT "http://10.3.246.224:9200/tests/songs/1" -d '{"name":"deck the halls","year":"2018","month":"8"}'

 

返回結果:

{

       "_index": "testes",

       "_type": "songs",

       "_id": "1",      //id 也能夠不知道,由系統自主生成

       "_version": 1,

       "result": "created",//表明添加成功

       "_shards": {

              "total": 2,

              "successful": 1,

              "failed": 0

       },

       "_seq_no": 0,

       "_primary_term": 1

}

3.   讀取數據

curl -XGET http://localhost:9200/music/songs/1?pretty

 

返回數據:

{

  "_index" : "testes",

  "_type" : "songs",

  "_id" : "1",

  "_version" : 1,

  "found" : true,  //查找成功

  "_source" : {    //目的數據

    "name" : "deck the halls",

    "year" : "2018",

    "month" : "8"

  }

}

 

 

4.   更新數據

a)   查找更新某個key:

curl -H "Content-Type: application/json" -XPOST "http://10.3.246.224:9200/testes/songs/1/_update?pretty" -d '{"doc":{"query":{"match":{"name":"qqqddd"}}}}'

返回數據:

{

  "_index" : "testes",

  "_type" : "songs",

  "_id" : "1",

  "_version" : 2,

  "result" : "updated",//更新成功

  "_shards" : {

    "total" : 2,

    "successful" : 1,

    "failed" : 0

  },

  "_seq_no" : 1,

  "_primary_term" : 1

}

b)   更新整條數據:

curl -H "Content-Type: application/json" -XPOST "http://10.3.246.224:9200/testes/songs/1/_update?pretty" -d '{"doc":{"name":"qddd","year":"2018","month":"8"}}'

返回數據同上

 

c)   還有就是用添加數據的命令:只是將數據改了

curl -H "Content-Type: application/json" -XPUT "http://10.3.246.224:9200/tests/songs/1" -d '{"name":"deck the halls","year":"2020","month":"8"}'

5.   刪除數據

curl -XDELETE "http://localhost:9200/music/songs/1"

 

返回數據:

{

       "_index": "tests",

       "_type": "songs",

       "_id": "1",

       "_version": 2,

       "result": "deleted",//刪除成功

       "_shards": {

              "total": 2,

              "successful": 1,

              "failed": 0

       },

       "_seq_no": 1,

       "_primary_term": 1

}

注意:刪除一個文檔不會當即生效,它只是被標記成已刪除。es將會在你以後添加更多索引的時候纔會在後臺進行刪除內容的清理

5、    ES的C++ API開發

1.   ES沒有C++的接口,而咱們須要基於c++操做ES

有兩個辦法

一是嵌入其餘語言的開發,利用ES已提供的接口,好比,在C++中嵌入python API,這在編譯上可能引入新的問題

二是須要本身構造如第四部分的http請求來得到數據,能夠基於libcurl庫,也能夠基於系統中已有的httpproxy

爲了避免破壞已有系統的一致性,基於httpproxy,來構造http請求,對外封裝提供C++接口

2.    基於業務需求設計思想

/*es是面向文檔,基於索引的彈性搜索引擎,故而

    *es中的數據結構:index/type/id ->對應一條數據,因此

*es中帖子的數據結構設計:

uid/tiezi/tid -> json{uid,tid,content,timestamp}

    *雖然存在uid和tid的冗餘,可是這樣設計的好處是:能夠很方便處理某我的某條數據,由於uid就是索引,這樣還利用了,索引的高處理性能

    */

3.    C++ API

1)   添加

/*功能:向es中添加protobuf數據,可是在es中是以json樣式存在

    *uid:用戶id

    *tid:帖子id

    *msg:帖子結構,即(uid,tid,content,timestamp)

    */

bool addDocument(const std::string &uid, const std::string &tid,const google::protobuf::Message *msg);

封裝後造成的http請求:

curl -H "Content-Type: application/json" -XPUT "http://10.3.246.224:9200/ uid /tiezi/tid " -d ' msg .json_str()'

 

2)   刪除

    /*功能:向es中刪除某我的uid的全部數據

    *uid:用戶id

    */

bool deleteAllByUid(const std::string &uid);

封裝後造成的http請求:

curl -XDELETE http://localhost:9200/uid  -d ‘{「query」:{「match_all」:{}}}’

 

    /*功能:向es中刪除某我的具體的某個數據

    *uid:用戶id

    *tid:帖子id

    */

bool deleteDocumentByUidTid(const std::string &uid, const std::string &tid);

封裝後造成的http請求:

curl -XDELETE "http://localhost:9200/ uid / tiezi / tid "

 

    /*功能:向es中刪除某個用戶某個時間點之前的全部帖子,也就是 小於 某個時間的全部帖子

    *uid:用戶id

    *beforeTimes:時刻之前的數據將所有會刪除

    */

bool deleteDocumentByUidBeforeTimes(const std::string &uid, const std::string &beforeTimes);

封裝後造成的http請求:

curl -XPOST "http://localhost:9200/ uid /tiezi/_delete_by_query

-d‘{"query":{"range":{"timestamp.keyword":{"gte":"2016-07-09 11:18:21","lte":"2018-08-17 11:18:21","format":"yyyy-MM-dd HH:mm:ss"}}}}’

 

PS: timestamp是數據中一個字段,在時間段匹配中,要注意空格

3)   查詢

    /*功能:以或的邏輯關係操做查詢帖子中是否存在包含詞,並過濾返回結果,只返回並獲得UID,tid

    *注:好比查詢詞是詞組:"running swimming",查詢以後的結果是,只要帖子content中至少包含一個詞彙就能夠,即帖子content中包含"running","swimming","running ... swimming ..."都返回

    *containsWords:查詢詞 或詞組 ,好比 "sport","running swimming"

    *uid_tid:查詢成功返回的N條uid和tid數據

    */

int searchAllByContainWords_OR(const std::string &containsWords,vector<struct Uid_Tid> &uid_tid);

封裝後造成的http請求:

curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/_search

-d ‘{"query":{"match": {"content":{"query":"swimming running"","operator":"or"}}},"_source":["uid","tid"]}’

 

PS: operator 是or,表示是或邏輯操做,query中填寫多個字段,匹配數據字段content中存在swimming或running,_source 中有數據字段uid和tid,用來控制返回結果的,當數據量很大的時候對結果裁剪,減小無用的數據傳輸

 

 

    /*功能:以與的邏輯關係操做查詢帖子中是否存在包含詞,並過濾返回結果,只返回並獲得UID,tid

    *注:好比查詢詞是詞組:"running swimming",查詢以後的結果是,帖子content中包含每一個詞彙,即帖子content中包含running和 swimming才返回

    *containsWords:查詢詞 或詞組 ,好比 "sport","running swimming"

    *uid_tid:查詢成功返回的N條uid和tid數據

    */

    Int searchAllByContainWords_AND(const std::string &containsWords,vector<struct Uid_Tid> &uid_tid);

封裝後造成的http請求:

curl -H "Content-Type: application/json" -XPOST "http://localhost:9200/_search

-d ‘{"query":{"match": {"content":{"query":"swimming running"","operator":"and"}}},"_source":["uid","tid"]}’

 

PS:同上,區別是operator是and,表示是與邏輯操做

 

 

 相似c++ API接口參考:https://github.com/QHedgeTech/cpp-elasticsearch

6、    部署後運維

1.    單節點集羣中節點掛掉,數據會有損失嗎?

在Elasticsearch和磁盤之間是文件系統緩存。 在內存索引緩衝區中的文檔會被寫入到一個新的段中,可是這裏新段會被先寫入到文件系統緩存(這一步代價會比較低),稍後再被刷新(refresh)到磁盤(這一步代價比較高fsync)。不過只要文件已經在緩存中,就能夠像其它文件同樣被打開和讀取了。在 Elasticsearch 中,寫入和打開一個新段的過程叫作 refresh 。 默認狀況下每一個分片會每秒自動刷新一次。

在fsync以後的數據是不會有損失的,若是你設置的refresh_interval刷新間隔過大,設備忽然斷電,這種狀況避免不了數據丟失

 

 

2.    假設是在集羣單一節點掛掉中,數據會有損失嗎?集羣中多少個節點down機,會影響集羣的健壯性,會致使數據丟失?

當集羣設置了分片(shard)和副本(replicats)時,(少部分節點掛掉)數據不會有損失。(PS:集羣有3個節點,一個一個掛掉,只要有一個節點在,數據不會損失,集羣可用)

同時掛了多臺,致使剩餘節點中副本和分片拼不齊一個完整的數據時,集羣將失效。(PS:集羣有3個節點,同時掛掉2個,集羣不可用,當只要再恢復一個,使可以拼齊一條完整的數據,集羣恢復可用)。猜想,若是此時加入的是全新節點,可能不起做用。

 

這部分還須要考慮主副數據一致性,參見6.15

 

3.    集羣節點掛掉是什麼場景?掛掉的節點又及時加入集羣是什麼場景,有什麼行爲?掛掉的節點不可再用了(好比硬件問題),加入新的節點會有什麼行爲?

答案同2

 

4.    節點崩潰重啓:

1)節點崩潰後

只要集羣數據完整性沒受到破壞,集羣中Master 當即注意到了這個節點的離線,它決定在集羣內提拔其餘擁有該崩潰節點上面的主分片對應的副本分片爲主分片,將找到該崩潰節點的副本

在副本被提拔爲主分片之後,master 節點開始執行恢復操做來重建缺失的副本。集羣中的節點之間互相拷貝分片數據,網卡壓力劇增

因爲目前集羣處於非平衡狀態,這個過程還有可能會觸發小規模的分片移動。其餘不相關的分片將在節點間遷移來達到一個最佳的平衡狀態,集羣狀態變綠

 

2)重啓後

該節點自動加入集羣,這個節點被告知當前的數據已經沒有用了, 數據已經在其餘節點上從新分配了。因此 該節點 把本地的數據進行刪除,而後從新開始恢復集羣的其餘分片,觸發小規模的分片移動。其餘不相關的分片將在節點間遷移來達到一個最佳的平衡狀態,集羣狀態變綠

 

3)若是明確知道該節點是瞬時中斷,能夠設置推遲分片的分配:

curl -X PUT 10.3.246.224/_all/_settings -d '{"settings": {"index.unassigned.node_left.delayed_timeout": "5m" }}'

 

4)若是節點在超時以後再回來,且集羣尚未完成分片的移動,會發生什麼事情呢?

Elasticsearch 會檢查該機器磁盤上的分片數據和當前集羣中的活躍主分片的數據是否是同樣 — 若是二者匹配, 說明沒有進來新的文檔,包括刪除和修改 — 那麼 master 將會取消正在進行的再平衡並恢復該機器磁盤上的數據。

之因此這樣作是由於本地磁盤的恢復永遠要比網絡間傳輸要快,而且咱們保證了他們的分片數據是同樣的,這個過程能夠說是共贏。

若是分片已經產生了分歧(好比:節點離線以後又索引了新的文檔),那麼恢復進程會繼續按照正常流程進行。從新加入的節點會刪除本地的、過期的數據,而後從新獲取一份新的。

 

5.    崩潰後起不來:

只要集羣數據完整性沒受到破壞,集羣可用,數據沒有損失

 

PS:什麼叫數據完整性?即集羣中對數據進行分片和副本,將分片副本按照必定算法分配到不一樣的節點上,任何一個節點down機或一個一個down機,都不會影響其餘節點的分片或副本,能夠將數據拼齊,恢復完整

 

6.    集羣節點擴展,加入新節點是什麼場景,有什麼行爲?

在集羣正常使用下,加入新節點,將會使數據從新分佈,以使任何一個(或部分)節點掛掉,仍能拼齊一條完整的數據。

 

7.    集羣監測哪些指標?

集羣健康:curl -X get http://10.3.246.224:9200/_cluster/health?pretty

集羣統計:

curl -XGET 'http://10.3.246.224:9200/_cluster/stats?human&pretty'

查看每一個節點狀態:

curl -XGET  http://10.3.246.224:9200/_cat/nodes?v

8.    分片(shard)和副本(replicats)怎麼調整?

主分片的數目在索引建立時就已經肯定了下來。實際上,這個數目定義了這個索引可以 存儲 的最大數據量。(實際大小取決於你的數據、硬件和使用場景。) 可是,讀操做——搜索和返回數據——能夠同時被主分片  副本分片所處理,因此當你擁有越多的副本分片時,也將擁有越高的吞吐量。

在運行中的集羣上是能夠動態調整副本分片數目的,咱們能夠按需伸縮集羣。讓咱們把副本數從默認的 1增長到 2 :

對整個index調整副本數:

curl -H "Content-Type: application/json" -X PUT http://10.3.246.222:9200/_settings  -d '{"number_of_replicas" : 2}'

對某個index按需調整副本數2:

curl -H "Content-Type: application/json" -X PUT http://10.3.246.222:9200/index/_settings  -d '{"number_of_replicas" : 2}'

 

9.    路由一個文檔到一個分片當中

shard = hash(routing) % number_of_primary_shards

routing:是一個可變值,默認是文檔的id,也能夠設置成一個自定義的值

number_of_primary_shards :主分片的數量,如6,建立索引的時候就肯定好主分片的數量而且永遠不會改變這個數量:由於若是數量變化了,那麼全部以前路由的值都會無效,文檔也再也找不到了

10. 多少個節點能組成一個正常的集羣、業務功能、選舉功能能正常使用

這個沒有要求。只有一個節點的,叫單節點集羣。集羣可用,是在可用節點中數據都具有完整性,即爲可用。不然集羣不可用。

 

11. JVM SWAP

 

12. 更新文檔

在 Elasticsearch 中文檔是 不可改變 的,不能修改它們(倒排索引被寫入磁盤後是 不可改變 的:它永遠不會修改)。 相反,若是想要更新現有的文檔,須要 重建索引或者進行替換。

更新操做:1,從舊文檔構建 JSON2,更改該 JSON 3,刪除舊文檔  4,索引一個新文檔

 

如下是部分更新一個文檔的步驟:

1)   客戶端向 Node 1 發送更新請求。

2)   它將請求轉發到主分片所在的 Node 3 。

3)   Node 3 從主分片檢索文檔,修改 _source 字段中的 JSON ,而且嘗試從新索引主分片的文檔。 若是文檔已經被另外一個進程修改,它會重試步驟 3 ,超過 retry_on_conflict 次後放棄。

4)   若是 Node 3 成功地更新文檔,它將新版本的文檔並行轉發到 Node 1 和 Node 2 上的副本分片,從新創建索引。 一旦全部副本分片都返回成功, Node 3 向協調節點也返回成功,協調節點向客戶端返回成功。

13. 系統升級

 

14. 協調節點

咱們能夠發送請求到集羣中的任一節點。 每一個節點都有能力處理任意請求。 每一個節點都知道集羣中任一文檔位置,因此能夠直接將請求轉發到須要的節點上。每一個節點都是這樣的協調節點(coordinating node)

 

 

 

如下是在主副分片和任何副本分片上面 成功新建,索引和刪除文檔所須要的步驟順序:

1)   客戶端向 Node 1 發送新建、索引或者刪除請求。

2)   節點使用文檔的 _id 肯定文檔屬於分片 0 。請求會被轉發到 Node 3`,由於分片 0 的主分片目前被分配在 `Node 3 上。

3)   Node 3 在主分片上面執行請求。若是成功了,它將請求並行轉發到 Node 1 和 Node 2 的副本分片上。一旦全部的副本分片都報告成功, Node 3 將向協調節點報告成功,協調節點向客戶端報告成功。

在客戶端收到成功響應時,文檔變動已經在主分片和全部副本分片執行完成,變動是安全的

 

 

如下是從主分片或者副本分片檢索文檔的步驟順序:

1)   客戶端向 Node 1 發送獲取請求。

2)   節點使用文檔的 _id 來肯定文檔屬於分片 0 。分片 0 的副本分片存在於全部的三個節點上。 在這種狀況下,它將請求轉發到 Node 2 。

3)   Node 2 將文檔返回給 Node 1 ,而後將文檔返回給客戶端。

在處理讀取請求時,協調結點在每次請求的時候都會經過輪詢全部的副本分片來達到負載均衡

15. 數據一致性

consistency參數的值能夠設爲

 one:要主分片狀態 ok 就容許執行_寫_操做

all:必需要主分片和全部副本分片的狀態沒問題才容許執行_寫_操做

quorum:默認爲quorum,即大多數的分片副本狀態沒問題就容許執行_寫_操做。

                                                                 ’quorum =( (primary + number_of_replicas) / 2 ) + 1

若是你的索引設置中指定了當前索引擁有三個副本分片(number_of_replicas=3),那quorum=3 (primary=1)

若是此時你只啓動兩個節點,那麼處於活躍狀態的分片副本數量就達不到規定數量,也所以您將沒法索引和刪除任何文檔。

 

16. 數據從內存到磁盤是個什麼刷新機制 與 近實時

在Elasticsearch和磁盤之間是文件系統緩存。 在內存索引緩衝區中的文檔會被寫入到一個新的段中,可是這裏新段會被先寫入到文件系統緩存(這一步代價會比較低),稍後再被刷新到磁盤(這一步代價比較高fsync)。不過只要文件已經在緩存中,就能夠像其它文件同樣被打開和讀取了。

在 Elasticsearch 中,寫入和打開一個新段的輕量的過程叫作 refresh 。 默認狀況下每一個分片會每秒自動刷新一次。

想優化索引速度而不是近實時搜索,能夠經過建立索引時設置 refresh_interval

curl -H "Content-Type: application/json" -X PUT http://10.3.246.223:9200/test_refresh -d '{"settings": {"refresh_interval": "30s" }}'

 

中止刷新

curl  -H "Content-Type: application/json"  -X PUT http://10.3.246.223:9200/test_refresh/_settings  -d '{"refresh_interval":-1}'

 

refresh_interval 能夠在既存索引上進行動態更新

 

curl  -H "Content-Type: application/json"  -X PUT http://10.3.246.223:9200/test_refresh/_settings  -d '{"refresh_interval":"30m"}'//-1 不設置,1一毫秒,1s一秒,30m 30分鐘

 

17. 持久化

一個文檔被索引以後,就會被添加到內存緩衝區,而且追加到了 translog。

translog 提供全部尚未被刷到磁盤的操做的一個持久化紀錄。當 Elasticsearch 啓動的時候,它會從磁盤中使用最後一個提交點去恢復已知的段,而且會重放 translog 中全部在最後一次提交後發生的變動操做。

18. Translog 有多安全 ?

在文件被fsync到磁盤前,被寫入的文件在重啓以後就會丟失。默認translog 是每5秒被fsync刷新到硬盤,或者在每次寫請求完成以後執行。這個過程在主分片和複製分片都會發生。最終,基本上,這意味着在整個請求被fsync到主分片和複製分片的translog以前,你的客戶端不會獲得一個200 OK響應。

能夠設置異步fsync

curl -H "Content-Type: application/json" -X PUT http://10.3.246.223:9200/tttt/_settings  -d '{"index.translog.durability": "async","index.translog.sync_interval": "5s"}'

這個選項能夠針對索引單獨設置,而且能夠動態進行修改。若是你決定使用異步 translog 的話,你須要 保證 在發生crash時,丟失掉 sync_interval 時間段的數據也無所謂

若是你不肯定這個行爲的後果,最好是使用默認的參數( "index.translog.durability": "request" )來避免數據丟失

7、    資料

1.   ES參考手冊

https://www.elastic.co/guide/en/elasticsearch/reference/current/index.html

2.   《ElasticSearch權威指南》

https://www.elastic.co/guide/cn/elasticsearch/guide/current/intro.html

 

3.   中文社區

https://elasticsearch.cn/

4.   英文社區

https://discuss.elastic.co/c/elasticsearch/

 

8、    插件

1.   Head插件

在chrome中直接安裝的插件,要比在linux下命令安裝簡單

 

2.   Ik分詞插件

 

9、    其餘

ES也提供對數據的分析,功能很是強大,還有不少像ik這樣分詞插件,咱們在瀏覽器中訪問es服務,在web界面中也能夠很方便的操做數據。瞭解的很是淺顯,暫記於此,以待有機會深刻了解。對於json格式以及json中數據空格也須要很是注意。

相關文章
相關標籤/搜索