一、 ElasticSearch是什么
ElasticSearch是目前開源全文搜索引擎的首選,可以快速存儲,搜索和分析海量數據。Stack Overflow,Github等都在使用。
Elasticsearch 是使用 Java 編寫的,它的內部使用 Lucene 做索引與搜索,但是它使全文檢索變得簡單, 通過隱藏 Lucene 的復雜性,取而代之的提供一套簡單一致的 RESTful API。
ES提供的Client API:https://www.elastic.co/guide/en/elasticsearch/client/index.html
包含多種語言:
注意:沒有C++接口,而我們需要基於c++操作ES
二、 安裝部署
1. 服務器選擇
設備IP:10.3.246.224
系統:linux-64
磁盤空間:無 (df –h 發現磁盤沒容量了)
2. 解決磁盤占滿
du -sh /* | sort –nr :找出系統中占容量最大的文件夾,系統中15scpp這個文件夾占41G
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. 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即將作廢。
四、 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將會在你之后添加更多索引的時候才會在后台進行刪除內容的清理
五、 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
六、 部署后運維
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" )來避免數據丟失
七、 資料
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. 中文社區
4. 英文社區
https://discuss.elastic.co/c/elasticsearch/
八、 插件
1. Head插件
在chrome中直接安裝的插件,要比在linux下命令安裝簡單
2. Ik分詞插件
九、 其他
ES也提供對數據的分析,功能非常強大,還有很多像ik這樣分詞插件,我們在瀏覽器中訪問es服務,在web界面中也可以很方便的操作數據。了解的非常淺顯,暫記於此,以待有機會深入了解。對於json格式以及json中數據空格也需要非常注意。