當前位置:首頁 » 編程軟體 » ES開腳本

ES開腳本

發布時間: 2025-03-06 15:12:15

① 配置Elasticsearch

Elasticsearch船隻具有良好的默認值,並且只需要很少的配置。可以在運行的集群上使用集群更新設置API更改大多數設置。
配置文件應該包含特定於節點的設置(例如node.name和路徑),或者節點為了能夠加入集群而需要的設置,例如 cluster.name 和 network.host 。

Elasticsearch有三個配置文件:

這些文件位於config目錄中,其默認位置取決於安裝是來自存檔分發版(tar.gz或zip)還是包分發版(Debian或RPM包)。
對於存檔發行版,config目錄位置默認為 $ES_HOME/config 。配置目錄的位置可以通過 ES_PATH_CONF 環境變數改變,如下所示:

或者,您可以通過命令行或shell配置文件導出ES_PATH_CONF環境變數。

對於包分發,配置目錄位置默認為 /etc/elasticsearch 。配置目錄的位置也可以通過 ES_PATH_CONF 環境變數更改,但是請注意,僅在shell中設置是不夠的。相反,這個變數來源於 /etc/default/elasticsearch (用於Debian包)和 /etc/sysconfig/elasticsearch (用於RPM包)。您需要相應地在其中一個文件中編輯 ES_PATH_CONF=/etc/elasticsearch 條目,以更改配置目錄的位置。

配置格式為YAML。下面是更改數據和日誌目錄路徑的示例:

設置也可以扁平化如下:

在YAML中,你可以將非標量值格式化為序列:

雖然不太常見,但你也可以將非標量值格式化為數組:

使用${…}符號將被替換為環境變數的值。例如:

環境變數的值必須是簡單字元串。使用逗號分隔的字元串來提供Elasticsearch將解析為列表的值。例如,Elasticsearch將以下字元串分割為 ${HOSTNAME} 環境變數的值列表

集群和節點設置可以根據配置方式進行分類:

您可以使用 集群更新設置API 在運行的集群上配置和更新動態設置。您還可以使用 elasticsearch.yml 在未啟動或關閉的節點上本地配置動態設置。

使用集群更新設置API進行的更新可以是持久的(跨集群重啟應用),也可以是短暫的(在集群重啟後重置)。您還可以通過使用API為臨時或持久設置賦值為空來重置它們。

如果您使用多個方法配置相同的設置,Elasticsearch將按照以下優先順序應用這些設置:

例如,您可以應用瞬變設置來覆蓋持久設置或 elasticsearch.yml 設置。然而,對 elasticsearch.yml 的更改,不會覆蓋已定義的瞬態或持久設置。

最好使用集群更新設置API設置動態的集群范圍設置,並使用 elasticsearch.yml 僅用於本地配置。使用集群更新設置API可以確保所有節點上的設置是相同的。如果您不小心在 elasticsearch.yml 中配置了不同的設置。在不同的節點上,很難注意到差異。

靜態設置只能在未啟動或關閉的節點上使用 elasticsearch.yml 進行配置。

必須在集群中的每個相關節點上設置靜態設置

Elasticsearch開始時只需要很少的配置,但是在生產環境中使用集群之前,有很多方面需要考慮:

Elasticsearch將創建索引的數據寫入索引,將數據流寫入數據目錄。Elasticsearch將自己的應用程序日誌(其中包含關於集群運行狀況和操作的信息)寫入日誌目錄

對於macOS .tar.gz、Linux .tar.gz和Windows .zip安裝,數據和日誌默認是 $ES_HOME 的子目錄。但是,在升級過程中, $ES_HOME 中的文件有被刪除的風險

In proction, we strongly recommend you set the path.data and path.logs in elasticsearch.yml to locations outside of $ES_HOME . Docker , Debian , RPM , macOS Homebrew , and Windows .msi installations write data and log to locations outside of $ES_HOME by default.

To avoid errors, only Elasticsearch should open files in the path.data directory. Exclude the path.data directory from other services that may open and lock its files, such as antivirus or backup programs.

Supported path.data and path.logs values vary by platform

只有當一個節點與集群中的所有其他節點共享 cluster.name 時,該節點才能加入集群。默認名稱是 elasticsearch ,但是您應該將其更改為描述集群用途的適當名稱。

不要在不同的環境中重用相同的集群名稱。否則,節點可能會加入錯誤的集群

Elasticsearch使用 node.name 作為Elasticsearch特定實例的人類可讀標識符。這個名稱包含在許多api的響應中。當Elasticsearch啟動時,節點名默認為機器的主機名,但是可以在 elasticsearch.yml 中顯式配置

預設情況下,Elasticsearch只綁定到 127.0.0.1 和 [::1] 等環回地址。這對於在單個伺服器上運行一個或多個節點的集群進行開發和測試已經足夠了,但是 彈性生產集群 必須包含其他伺服器上的節點。有許多 網路設置 ,但通常你只需要配置 network.host :

當你為 network.host 提供值時。Elasticsearch假定您正在從開發模式轉向生產模式,並將一些系統啟動檢查從警告升級到異常。看看 開發和生產模式 之間的區別。

在投入生產之前,配置兩個重要的發現和集群形成設置,以便集群中的節點能夠相互發現並選擇一個主節點。

Elasticsearch可以開箱即用,無需任何網路配置,它將綁定到可用的環回地址,並掃描本地埠 9300 到 9305 ,以便與運行在同一伺服器上的其他節點連接。這種行為提供了一種無需進行任何配置的自動集群體驗。

當您希望與其他主機上的節點形成集群時,使用 靜態 discovery.seed_hosts 設置. This setting provides a list of other nodes in the cluster that are master-eligible and likely to be live and contactable to seed the discovery process .
此設置接受集群中所有符合主節點的地址的YAML序列或數組。每個地址可以是一個IP地址,也可以是通過DNS解析為一個或多個IP地址的主機名。

當您第一次啟動Elasticsearch集群時, 集群引導 步驟將確定在第一次選舉中計票的符合主資格的節點集。在 開發模式 下,如果沒有配置發現設置,這個步驟將由節點自己自動執行。

因為自動引導 本身就不安全 ,,所以在生產模式下啟動新集群時,必須顯式列出符合主資格的節點,這些節點的投票應該在第一次選舉中計算。您可以使用集群設置此列表。 initial_master_nodes 設置。

在集群第一次成功形成之後,刪除每個節點配置中的 Initial_master_nodes 設置。在重新啟動集群或向現有集群添加新節點時,不要使用此設置。

通過節點的 node.name 標識初始主節點, 該節點默認為主節點的主機名。請確保 cluster.initial_master_nodes 值 與 node.name 完全匹配如果您使用完全限定的域名(FQDN),例如master-node-a.example.com作為您的節點名,那麼您必須在此列表中使用FQDN。相反,如果node.name是沒有任何尾隨限定符的裸主機名,您也必須省cluster.initial_master_nodes中的尾隨限定符如果您使用完全限定的域名(FQDN),例如 master-node-a.example.com 作為您的節點名, 那麼您必須在此列表中使用FQDN。相反,如果f node.name 是沒有任何尾隨限定符的裸主機名,您也必須省略 cluster.initial_master_nodes 中的尾隨限定符。

請參見 bootstrapping a cluster 以及 發現和集群形成設置 .

默認情況下,Elasticsearch會根據節點的 角色 和總內存自動設置JVM堆大小。對於大多數生產環境,我們建議使用默認大小。

自動堆大小需要 bundled JDK ,如果使用自定義JRE位置,則需要Java 14或更高版本的JRE。

如果需要,您可以通過手動 設置JVM堆大小 來覆蓋默認大小

默認情況下,Elasticsearch將JVM配置為將堆內存溢出異常轉儲到默認數據目錄。在RPM和Debian軟體包中,數據目錄是/var/lib/elasticsearch。在Linux、MacOS和Windows發行版上,數據目錄位於Elasticsearch安裝的根目錄下。

如果此路徑不適合接收堆轉儲,請修改 -XX:HeapDumpPath=… jvm.options

默認情況下,Elasticsearch啟用垃圾收集(GC)日誌。這些是在jvm中配置的 jvm.options 並輸出到與Elasticsearch日誌相同的默認位置。默認配置每64mb輪換一次日誌,最多可以消耗2gb的磁碟空間。

您可以使用 JEP 158: Unified JVM Logging 中描述的命令行選項重新配置JVM日誌。除非您更改了默認jvm。選項文件,Elasticsearch默認配置將應用於您自己的設置之外。要禁用默認配置,首先通過提供 -Xlog:disable 選項禁用日誌記錄,然後提供您自己的命令行選項。這將禁用所有JVM日誌記錄,因此一定要檢查可用選項並啟用所需的所有內容。

要查看原始JEP中未包含的其他選項,請參見使用 JVM統一日誌框架啟用日誌記錄 .

Change the default GC log output location to /opt/my-app/gc.log by creating $ES_HOME/config/jvm.options.d/gc.options with some sample options:

Configure an Elasticsearch Docker container to send GC debug logs to standard error ( stderr ). This lets the container orchestrator handle the output. If using the ES_JAVA_OPTS environment variable, specify:

默認情況下,Elasticsearch使用啟動腳本直接在系統臨時目錄下創建的私有臨時目錄。

在某些Linux發行版上,如果最近沒有訪問過/tmp中的文件和目錄,系統實用程序將清除它們。如果需要臨時目錄的特性長時間不使用,那麼在Elasticsearch運行時,這種行為會導致私有臨時目錄被刪除。如果隨後使用需要此目錄的特性,則刪除私有臨時目錄會導致問題。

如果您使用.deb或.rpm包安裝Elasticsearch,並在systemd下運行它,那麼Elasticsearch使用的私有臨時目錄將被排除在定期清理之外。

如果您打算在Linux或MacOS上長時間運行.tar.gz發行版,請考慮為Elasticsearch創建一個專用的臨時目錄,該目錄不在將舊文件和目錄清除的路徑下。這個目錄應該設置許可權,以便只有作為Elasticsearch運行的用戶才能訪問它。然後,在啟動Elasticsearch之前,設置$ES_TMPDIR環境變數指向這個目錄。

默認情況下,Elasticsearch將JVM配置為將致命錯誤日誌寫入默認日誌目錄。對於 RPM 和 Debian 軟體包, 這個目錄是 /var/log/elasticsearch . On Linux and MacOS and Windows 發行版, logs 目錄位於Elasticsearch安裝根目錄下。

這些日誌是JVM遇到致命錯誤(例如分段錯誤)時產生的。如果此路徑不適合接收日誌,請修改 -XX:ErrorFile=... 在 jvm.options 條目。

在災難中,快照可以防止數據永久丟失。快照生命周期管理是對集群進行定期備份的最簡單方法。有關更多信息,請參見備份集群。

在災難中, 快照 可以防止數據永久丟失. 快照生命周期管理 是對集群進行定期備份的最簡單方法. 有關更多信息, 請參見 備份集群 。

備份集群的唯一可靠和受支持的方法是使用快照。您不能通過復制Elasticsearch集群節點的數據目錄來備份該集群。不支持從文件系統級備份恢復任何數據的方法。如果試圖從這樣的備份恢復集群,可能會出現損壞、丟失文件或其他數據不一致的報告,或者看起來已經成功地悄無聲息地丟失了一些數據。

有些設置是敏感的,僅依靠文件系統許可權來保護它們的值是不夠的。對於這個用例,Elasticsearch提供了一個密鑰存儲庫和 elasticsearch -keystore 工具 來管理密鑰存儲庫中的設置。

只有重新啟動Elasticsearch後,對keystore的所有修改才會生效。

這些設置就像elasticsearch中的常規設置一樣。Yml配置文件,需要在集群中的每個節點上指定。目前,所有安全設置都是特定於節點的設置,在每個節點上必須具有相同的值。

Just like the settings values in elasticsearch.yml , 對密鑰存儲庫內容的更改不會自動應用到運行的Elasticsearch節點。重新讀取設置需要重新啟動節點。但是,某些安全設置被標記為 可重新載入 。. Such settings can be re-read and applied on a running node .

所有安全設置的值(無論是否可重新載入)必須在所有集群節點上相同。在進行所需的安全設置更改後,使用 bin/elasticsearch-keystore add 命令, call:

keystore-password : 用於加密Elasticsearch密鑰庫的密碼

此API在每個集群節點上解密並重新讀取整個密鑰存儲庫,但只應用可重新載入的安全設置。對其他設置的更改直到下次重啟才會生效。一旦調用返回,重新載入就完成了,這意味著依賴於這些設置的所有內部數據結構都已更改。所有的設置都應該從一開始就具有新值。

當更改多個可重新載入的安全設置時,在每個集群節點上修改所有安全設置,然後發出 reload_secure_settings 調用,而不是在每次修改後重新載入。

有可重新載入的安全設置:

② 如何使用Elasticsearch groovy script腳本更新數據

用groovy腳本自定義ElasticSearch查詢,來實現以上功能。

例,數據中包含欄位birdtyday,記錄遊客生日:
"birthday": "1992-02-05 00:00:00",
新建文件getAgeByBirthday.groovy,編輯其內容為:

def b = doc[birthday_field].value
def birthday = new Date(b)
def now = new Date()
long age = (now -birthday)/365
age

並把此文件放在es的config/scripts目錄下(如果沒有此目錄就新建一個)。

然後在config/elasticsearch.yml文件中加一行:

script.groovy.sandbox.enabled: true

最後重啟es即可。
接下來,我們就可以用以下DSL進行年齡統計了

GET /lovingtrip-report/hotelcustomer/_search?search_type=count
{
"aggs": {
"counts_by_age": {
"terms": {
"script_file": "getAgeByBirthday",
"params": {
"birthday_field": "birthday"
},
"size": 100
}
}
}
}

或者:

GET /lovingtrip-report/hotelcustomer/_search?search_type=count
{
"aggs": {
"histogram_by_age": {
"histogram": {
"script_file": "getAgeByBirdthday",
"params": {
"birdthday_field": "birdthday"
},
"interval": 5
}
}
}
}

不過腳本查詢性能不佳,且不能利用es的緩存,所以在大數據量或高性能要求的場景下不適用。。

-------------------------------------
補充一個自定義的年齡range過濾:
range_AgeByBirthday.groovy:

def b = doc[birdthday_field].value
def birdthday = new Date(b)
def now = new Date()
long age = (now -birdthday)/365
gte<=age && age<=lte

DSL:

GET /lovingtrip-report/hotelcustomer/_search?search_type=count
{
"query": {
"filtered": {
"filter": {
"script": {
"script_file": "range_AgeByBirdthday",
"params": {
"birdthday_field": "birdthday",
"gte": 50,
"lte": 60
}
}
}
}
},
"aggs": {
"histogram_by_age": {
"histogram": {
"script_file": "getAgeByBirdthday",
"params": {
"birdthday_field": "birdthday"
},
"interval": 5
}
}
}
}

③ 如何使用Elasticsearch groovy script腳本更新數據

今天細說一下elasticsearch的update更新功能,以及如何利用script腳本更新數據。

想要使用script腳本功能,需要在配置文件elasticsearch.yml里設置

python

script.disable_dynamic: false

關於elasticsearch script的文章,總是會沒完沒了的修改

ES支持更新,但是更新的方式是通過一個提供的腳本進行的。ES的做法是,通過
index找到相應的存放記錄的節點,然後執行腳本,執行完之後,返回新的索引。實際上執行的是一個get和reindex的過程,在這個過程中,通過
versioning來控制沒有其它的更新操作(這個功能是0.19後可用的)。具體實現的原理應該和elasticsearch
Versioning相關。

get,reindex的含義是,ES先取出這條記錄,然後根據新數據生成新記錄,然後在把新記錄放回到ES中(並不會覆蓋老的記錄)。

現在沒有數據,首先我們需要創建一條記錄

Python

$ curl -XPUT localhost:9200/xiaorui.cc/blog/1 -d '{
"counter" : 1,
"tags" : ["red"]
}'

$ curl -XPUT localhost:9200/xiaorui.cc/blog/1 -d '{
"counter" : 1,
"tags" : ["red"]
}'

直接修改數據,一定要注意,直接update的化,會覆蓋以前的數據,另外update的時候,需要/index/type/id ,一定要帶著id。 elasticsearch 應該不支持搜索query方式update修改數據。

Python

curl -XPUT 'localhost:9200/xiaorui.cc/blog/1?pretty' -d '
{
"name": "xiaorui.cc"
}'

curl -XPUT 'localhost:9200/xiaorui.cc/blog/1?pretty' -d '
{
"name": "xiaorui.cc"
}'

elasticsearch提供了doc這個局部更新參數,他可以局部修改,而不會直接覆蓋以前的數據,這會針對特定的k v,欄位修改。

Python

curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update?pretty' -d '
{
"doc": { "name": "ruifengyun" }
}'

curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update?pretty' -d '
{
"doc": { "name": "ruifengyun" }
}'

當Elasticsearch API不能滿足要求時,Elasticsearch允許你使用腳本實現自己的邏輯。腳本支持非常多的API,例如搜索、排序、聚合和文檔更新。腳本可以通過請求的一部分、檢索特殊的.scripts索引或者從磁碟載入方式執行。

下面是es script的用法,這些腳本是groovy開發的。 下面的語句的意思是說,將counter的值加4

Python

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
}
}'

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
}
}'

通過上面的例子,我們知道tags是個列表,如果用doc局部更新的語法,他是無法做到append的,還是會覆蓋tags這個欄位。 那麼怎麼實現列表擴展? 請使用elasticsearch script實現。

Python

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.tags += tag",
"params" : {
"tag" : "white"
}
}'

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.tags += tag",
"params" : {
"tag" : "white"
}
}'

_update也支持upsert功能,沒有這個欄位或者key,也會添加這個記錄。下面是一個例子,如果沒有counter欄位,則插入該欄位:

Python

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
},
"upsert" : {
"counter" : 1
}
}'

$ curl -XPOST 'localhost:9200/xiaorui.cc/blog/1/_update' -d '{
"script" : "ctx._source.counter += count",
"params" : {
"count" : 4
},
"upsert" : {
"counter" : 1
}
}'

下面我們來復雜點的groovy script腳本用法. 當你的source沒有china這個key,那麼我會增加一個kv

Python

curl -XPOST "http://localhost:9200/xiaorui.cc/blog/80/_update" -d'
{
"script": "if (!ctx._source.containsKey(\"china\")) { ctx._source.attending = newField }",
"params" : {"newField" : "blue" },
"myfield": "data"
}'

curl -XPOST "http://localhost:9200/xiaorui.cc/blog/80/_update" -d'
{
"script": "if (!ctx._source.containsKey(\"china\")) { ctx._source.attending = newField }",
"params" : {"newField" : "blue" },
"myfield": "data"
}'

下面的script語法相對復雜的,會遍歷一組字典,然後進行判斷賦值。

{
「55555″: 22,
「name」: 「lisi」,
「distr_pan」: [
{
「k」: 15,
「v」: 15
},
{
「k」: 20,
「v」: 20
}
]
}

Python

$ curl -XPUT 'localhost:9200/xiaorui.cc/blog/9123/_update' -d '
{
"script" : "def x = false;ctx._source.distr_pan.each({if(it.get('k')==target){x=true}});if(x){ctx._source.distr_pan +=v}",
"params":{
"v":{"k":nlp, "v":35},
"target":15
}
}

$ curl -XPUT 'localhost:9200/xiaorui.cc/blog/9123/_update' -d '
{
"script" : "def x = false;ctx._source.distr_pan.each({if(it.get('k')==target){x=true}});if(x){ctx._source.distr_pan +=v}",
"params":{
"v":{"k":nlp, "v":35},
"target":15
}
}

elasticsearch script就講解到這里了,很多例子已經簡單明了…
script貌似不是很安全,最少遠程代碼執行的漏洞暴露過幾次了. 下次把python版的script走一遍試試.
貌似對於我們你者來說,不管是groovy python,沒什麼太大卻別,語法看起來都一個模子。

④ 07 ES部分更新,包括_update和script腳本兩種方式

主要講解的內容: 部分更新,包括_update和script腳本兩種方式

每次就傳遞少數幾個發生修改的field即可,不需要將全量的document數據發送過去

更新示例:

ES內部對partial update的實際執行,跟傳統的全量替換方式,是幾乎一樣的
1、內部先獲取document
2、將傳過來的field更新到document的json中
3、將老的document標記為deleted
4、將修改後的新的document創建出來

partial update相較於全量替換的優點
1、所有的查詢、修改和寫回操作,都發生在es中的一個shard內部,避免了網路數據傳輸的開銷(減少2次網路請求) , 大大提升了性能。
2.減少了查詢和修改中的時間間隔,可以大大減少並發沖突的情況。

通過腳本更新制定欄位,其中ctx是腳本語言中的一個執行對象,先獲取_source,再修改price欄位

在 ES安裝目錄/config/scripts目錄下創建groovy文件 ( 該方法 已過時 了)

使用 _script在ES中創建腳本 ecommerce_add_tags

_scripts腳本的簡單管理

使用id引用外部腳本更新document

與修改欄位類似

刪除欄位

刪除文檔

如果指定的document不存在,就執行upsert中的初始化操作;

如果指定的document存在,就執行doc或者script指定的partial update操作

相對於之前的使用upsert中的內容添加到不存在的文檔,使用doc_as_upsert可以在文檔不存在的時候,把doc中的內容插入到文檔中。

注意

參考文章:

ES 27 - Elasticsearch的腳本使用實踐 - 瘦風 - 博客園 https://www.cnblogs.com/shoufeng/p/11360177.html

Elasticsearch增刪改查 之 —— Update更新 - xingoo - 博客園 https://www.cnblogs.com/xing901022/p/5330778.html

How to use scripts | Elasticsearch Reference [7.x] | Elastic https://www.elastic.co/guide/en/elasticsearch/reference/7.x/moles-scripting-using.html

Painless API Reference | Painless Scripting Language [7.x] | Elastic https://www.elastic.co/guide/en/elasticsearch/painless/7.x/painless-api-reference.html#painless-api-reference

熱點內容
as橫版游戲源碼 發布:2025-03-06 19:17:25 瀏覽:394
學編程哪所學校好 發布:2025-03-06 18:55:04 瀏覽:727
php斷點續傳 發布:2025-03-06 18:35:10 瀏覽:525
伺服器ilo忘記ip 發布:2025-03-06 18:34:27 瀏覽:737
wiicfg加密手柄 發布:2025-03-06 18:33:33 瀏覽:656
手機上qq怎麼看密碼 發布:2025-03-06 18:18:20 瀏覽:756
ma演算法 發布:2025-03-06 18:18:17 瀏覽:924
iframe中的元素訪問 發布:2025-03-06 18:07:16 瀏覽:504
隨機訪問空間 發布:2025-03-06 18:06:39 瀏覽:324
安卓電視下什麼軟體 發布:2025-03-06 18:05:45 瀏覽:522