天天看點

Elasticsearch叢集記憶體占用高?用這招!

作者:MCNU雲原生

一、freeze index當機索引介紹

Elasticsearch為了能夠實作高效快速搜尋,在記憶體中維護了一些資料結構,當索引的數量越來越多,那麼這些資料結構所占用的記憶體也會越來越大,這是一個不可忽視的損耗。

在實際的業務開展過程中,我們會發現,有些索引的資料是“熱”資料,經常被查詢,這些索引對應的資料結構維護在記憶體中以提供快速查詢是非常正确的,而有些“溫”資料(例如随時時間推移的曆史資料),可能很久才需要被查詢到,這時候一直維持在記憶體中就有些得不償失了。

為了解決這種情況,Elasticsearch提出了freeze index當機索引的功能。一個被當機的索引的每個shard在被搜尋時,Elasticsearch會建立一個臨時的資料結構,一旦搜尋完成将會立刻丢掉這個資料結構,由于不長期維持這些臨時資料結構在記憶體,當機索引比正常索引消耗更少的堆記憶體,在叢集的性能表現上更好。

Elasticsearch叢集記憶體占用高?用這招!

總結來說索引的當機是Elasticsearch提供的一個用于減少記憶體開銷的操作,這個功能在7.14版本中被标記為Deprecated,在Version 8以後,已經對堆記憶體的使用進行了改進,當機和解凍的功能不再适用,但在Version 8以前的版本中不失為一個可行的優化方案。

Elasticsearch叢集記憶體占用高?用這招!

二、索引當機

索引當機以後除了儲存一些必要的中繼資料資訊意外,将不再占用系統負載,索引将會變成隻讀,不再提供寫入的能力,類似force merge等操作也将無法執行。

注意,目前正在寫的索引不能被當機,并且執行了當機操作以後,會将索引先進行close,然後再open,在這段時間内,可能導緻主分片沒有被配置設定,叢集可能短暫出現red狀态,open結束後恢複。

我們來全程示範一下(基于7.14版本),首先建立一個索引:

curl -X PUT -H 'Content-Type:application/json' --data '{
    "settings":{
        "number_of_shards":1,
        "number_of_replicas":1
    },
    "mappings":{
        "properties":{
            "name":{
                "type":"text"
            },
            "phone":{
                "type":"keyword"
            },
            "orderId":{
                "type":"keyword"
            },
            "amount":{
                "type":"text"
            },
            "time":{
            "type":"keyword"
            },
            "merchantsType":{
            "type":"keyword"
            },
            "gender":{
            "type":"keyword"
            },
            "age":{
            "type":"keyword"
            },
            "channel":{
            "type":"keyword"    
            }
        }
    }
}' "http://localhost:9200/order?pretty"           

結果如下

{
  "acknowledged" : true,
  "shards_acknowledged" : true,
  "index" : "order"
}           

此時适用cat API檢視索引的狀态,可以看到索引的狀态是open。

curl http://localhost:9200/_cat/indices/order?v

health status index uuid                   pri rep docs.count docs.deleted store.size pri.store.size
yellow open   order JWeddPjZQF2-W5PD2EZn0w   1   1          0            0       208b           208b           

當機的API格式如下:

POST /<index>/_freeze           

我們使用API當機order索引:

curl -X POST http://localhost:9200/order/_freeze

{"acknowledged":true,"shards_acknowledged":true}           

往order索引中寫入文檔,發現響應如下,提示order索引處于block狀态,禁止寫入(注意,如果使用cat API能看到的狀态仍然是open的)。

{
    "error": {
        "root_cause": [
            {
                "type": "cluster_block_exception",
                "reason": "index [order] blocked by: [FORBIDDEN/8/index write (api)];"
            }
        ],
        "type": "cluster_block_exception",
        "reason": "index [order] blocked by: [FORBIDDEN/8/index write (api)];"
    },
    "status": 403
}           

三、索引解凍

需求解凍的過程中,同樣會将索引先進行close,然後再open,在這段時間内,索引不可查詢,叢集可能短暫出現red狀态,open結束後恢複。

API格式如下:

POST /<index>/_unfreeze           

以下為索引解凍操作的代碼案例:

curl -X POST "localhost:9200/order/_unfreeze?pretty"
{
  "acknowledged" : true,
  "shards_acknowledged" : true
}           

再次寫入文檔:

curl -X POST 'http://192.168.56.11:9200/order/_doc/' --header 'Content-Type: application/json' --data '{
    "name":"Lucas",
    "phone":"13535567890",
    "orderId":"388830293548545433",
    "amount":"999.99"
}'           

能夠正常寫入成功:

{
    "_index": "order",
    "_type": "_doc",
    "_id": "NfM9c4YBYouGktFdy0Fv",
    "_version": 1,
    "result": "created",
    "_shards": {
        "total": 2,
        "successful": 1,
        "failed": 0
    },
    "_seq_no": 0,
    "_primary_term": 6
}           

特别注意,在再次當機索引之前,一定要運作“force_merge”,以確定最佳性能。

#頭條創作挑戰賽#

繼續閱讀