மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு

மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு

எனது பெயர் இகோர் சிடோரென்கோ, டொம்க்ளிக்கின் முழு உள்கட்டமைப்பையும் பராமரிக்கும் நிர்வாகிகள் குழுவில் நான் தொழில்நுட்பத் தலைவராக இருக்கிறேன்.

Elasticsearch இல் விநியோகிக்கப்பட்ட தரவு சேமிப்பகத்தை அமைப்பதில் எனது அனுபவத்தைப் பகிர்ந்து கொள்ள விரும்புகிறேன். துண்டுகளின் விநியோகத்திற்கு முனைகளில் என்ன அமைப்புகள் பொறுப்பு, ILM எவ்வாறு செயல்படுகிறது மற்றும் செயல்படுகிறது என்பதைப் பார்ப்போம்.

பதிவுகளுடன் பணிபுரிபவர்கள், ஒரு வழி அல்லது வேறு, பின்னர் பகுப்பாய்வுக்காக நீண்ட கால சேமிப்பகத்தின் சிக்கலை எதிர்கொள்கின்றனர். எலாஸ்டிக் தேடலில், இது குறிப்பாக உண்மை, ஏனென்றால் கியூரேட்டர் செயல்பாட்டில் எல்லாம் துரதிர்ஷ்டவசமானது. பதிப்பு 6.6 ILM செயல்பாட்டை அறிமுகப்படுத்தியது. இது 4 கட்டங்களைக் கொண்டுள்ளது:

  • ஹாட் - இன்டெக்ஸ் தீவிரமாக புதுப்பிக்கப்பட்டு வினவப்படுகிறது.
  • வார்ம் - இன்டெக்ஸ் புதுப்பிக்கப்படவில்லை, ஆனால் இன்னும் வினவப்படுகிறது.
  • குளிர் - குறியீடு இனி புதுப்பிக்கப்படாது மற்றும் அரிதாகவே வினவப்படும். தகவல் இன்னும் தேடக்கூடியதாக இருக்க வேண்டும், ஆனால் வினவல்கள் மெதுவாக இருக்கலாம்.
  • நீக்கு - குறியீடு இனி தேவைப்படாது மற்றும் பாதுகாப்பாக நீக்கப்படலாம்.

கொடுக்கப்பட்டது

  • எலாஸ்டிக் சர்ச் டேட்டா ஹாட்: 24 செயலிகள், 128 ஜிபி நினைவகம், 1,8 டிபி எஸ்எஸ்டி RAID 10 (8 முனைகள்).
  • Elasticsearch Data Warm: 24 செயலிகள், 64 GB நினைவகம், 8 TB NetApp SSD கொள்கை (4 முனைகள்).
  • மீள் தேடல் தரவு குளிர்: 8 செயலிகள், 32 ஜிபி நினைவகம், 128 TB HDD RAID 10 (4 முனைகள்).

இலக்கு

இந்த அமைப்புகள் தனிப்பட்டவை, இவை அனைத்தும் முனைகளில் உள்ள இடம், குறியீடுகளின் எண்ணிக்கை, பதிவுகள் போன்றவற்றைப் பொறுத்தது. எங்களிடம் ஒரு நாளைக்கு 2-3 TB டேட்டா உள்ளது.

  • 5 நாட்கள் - சூடான கட்டம் (8 முக்கிய / 1 பிரதி).
  • 20 நாட்கள் - சூடான கட்டம் (சுருக்க-குறியீடு 4 முக்கிய / 1 பிரதி).
  • 90 நாட்கள் - குளிர் நிலை (முடக்கம்-குறியீடு 4 முக்கிய / 1 பிரதி).
  • 120 நாட்கள் - கட்டத்தை நீக்கு.

மீள் தேடலை அமைத்தல்

முனைகளில் ஒரு துண்டை விநியோகிக்க, உங்களுக்கு ஒரே ஒரு அளவுரு தேவை:

  • சூடான- முனைகள்:
    ~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
    # Add custom attributes to the node:
    node.attr.box_type: hot
  • சூடான- முனைகள்:
    ~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
    # Add custom attributes to the node:
    node.attr.box_type: warm
  • குளிர்- முனைகள்:
    ~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
    # Add custom attributes to the node:
    node.attr.box_type: cold

லாக்ஸ்டாஷை அமைத்தல்

இது எப்படி வேலை செய்கிறது மற்றும் இந்த அம்சத்தை நாங்கள் எவ்வாறு செயல்படுத்தினோம்? Elasticsearch இல் பதிவுகளைப் பெறுவதன் மூலம் ஆரம்பிக்கலாம். இரண்டு வழிகள் உள்ளன:

  1. லாக்ஸ்டாஷ் காஃப்காவிலிருந்து பதிவுகளைப் பெறுகிறது. சுத்தமாக எடுக்கலாம் அல்லது உங்கள் பக்கத்தில் மாற்றலாம்.
  2. எலாஸ்டிக் தேடலுக்கு ஏதோ ஒன்று எழுதுகிறது, எடுத்துக்காட்டாக, APM சேவையகம்.

லாக்ஸ்டாஷ் மூலம் குறியீடுகளை நிர்வகிப்பதற்கான உதாரணத்தைக் கவனியுங்கள். இது ஒரு குறியீட்டை உருவாக்கி அதற்குப் பொருந்தும் குறியீட்டு முறை மற்றும் தொடர்புடைய ஆனால் ILM.

k8s-ingress.conf

input {
    kafka {
        bootstrap_servers => "node01, node02, node03"
        topics => ["ingress-k8s"]
        decorate_events => false
        codec => "json"
    }
}

filter {
    ruby {
        path => "/etc/logstash/conf.d/k8s-normalize.rb"
    }
    if [log] =~ "[warn]" or [log] =~ "[error]" or [log] =~ "[notice]" or [log] =~ "[alert]" {
        grok {
            match => { "log" => "%{DATA:[nginx][error][time]} [%{DATA:[nginx][error][level]}] %{NUMBER:[nginx][error][pid]}#%{NUMBER:[nginx][error][tid]}: *%{NUMBER:[nginx][error][connection_id]} %{DATA:[nginx][error][message]}, client: %{IPORHOST:[nginx][error][remote_ip]}, server: %{DATA:[nginx][error][server]}, request: "%{WORD:[nginx][error][method]} %{DATA:[nginx][error][url]} HTTP/%{NUMBER:[nginx][error][http_version]}", (?:upstream: "%{DATA:[nginx][error][upstream][proto]}://%{DATA:[nginx][error][upstream][host]}:%{DATA:[nginx][error][upstream][port]}/%{DATA:[nginx][error][upstream][url]}", )?host: "%{DATA:[nginx][error][host]}"(?:, referrer: "%{DATA:[nginx][error][referrer]}")?" }
            remove_field => "log"
        }
    }
    else {
        grok {
            match => { "log" => "%{IPORHOST:[nginx][access][host]} - [%{IPORHOST:[nginx][access][remote_ip]}] - %{DATA:[nginx][access][remote_user]} [%{HTTPDATE:[nginx][access][time]}] "%{WORD:[nginx][access][method]} %{DATA:[nginx][access][url]} HTTP/%{NUMBER:[nginx][access][http_version]}" %{NUMBER:[nginx][access][response_code]} %{NUMBER:[nginx][access][bytes_sent]} "%{DATA:[nginx][access][referrer]}" "%{DATA:[nginx][access][agent]}" %{NUMBER:[nginx][access][request_lenght]} %{NUMBER:[nginx][access][request_time]} [%{DATA:[nginx][access][upstream][name]}] (?:-|%{IPORHOST:[nginx][access][upstream][addr]}:%{NUMBER:[nginx][access][upstream][port]}) (?:-|%{NUMBER:[nginx][access][upstream][response_lenght]}) %{DATA:[nginx][access][upstream][response_time]} %{DATA:[nginx][access][upstream][status]} %{DATA:[nginx][access][request_id]}" }
            remove_field => "log"
        }
    }
}
output {
    elasticsearch {
        id => "k8s-ingress"
        hosts => ["node01", "node02", "node03", "node04", "node05", "node06", "node07", "node08"]
        manage_template => true # включаем управление шаблонами
        template_name => "k8s-ingress" # имя применяемого шаблона
        ilm_enabled => true # включаем управление ILM
        ilm_rollover_alias => "k8s-ingress" # alias для записи в индексы, должен быть уникальным
        ilm_pattern => "{now/d}-000001" # шаблон для создания индексов, может быть как "{now/d}-000001" так и "000001"
        ilm_policy => "k8s-ingress" # политика прикрепляемая к индексу
        index => "k8s-ingress-%{+YYYY.MM.dd}" # название создаваемого индекса, может содержать %{+YYYY.MM.dd}, зависит от ilm_pattern
    }
}

கிபானா அமைப்பு

அனைத்து புதிய குறியீடுகளுக்கும் பொருந்தும் அடிப்படை முறை உள்ளது. இது சூடான குறியீடுகளின் விநியோகம், துண்டுகளின் எண்ணிக்கை, பிரதிகள் போன்றவற்றை அமைக்கிறது. டெம்ப்ளேட்டின் எடை விருப்பத்தால் தீர்மானிக்கப்படுகிறது order. அதிக எடை கொண்ட வார்ப்புருக்கள் ஏற்கனவே உள்ள டெம்ப்ளேட் அளவுருக்களை மீறும் அல்லது புதியவற்றைச் சேர்க்கும்.

மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு
மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு

GET _template/default

{
  "default" : {
    "order" : -1, # вес шаблона
    "version" : 1,
    "index_patterns" : [
      "*" # применяем ко всем индексам
    ],
    "settings" : {
      "index" : {
        "codec" : "best_compression", # уровень сжатия
        "routing" : {
          "allocation" : {
            "require" : {
              "box_type" : "hot" # распределяем только по горячим нодам
            },
            "total_shards_per_node" : "8" # максимальное количество шардов на ноду от одного индекса
          }
        },
        "refresh_interval" : "5s", # интервал обновления индекса
        "number_of_shards" : "8", # количество шардов
        "auto_expand_replicas" : "0-1", # количество реплик на ноду от одного индекса
        "number_of_replicas" : "1" # количество реплик
      }
    },
    "mappings" : {
      "_meta" : { },
      "_source" : { },
      "properties" : { }
    },
    "aliases" : { }
  }
}

பின்னர் குறியீடுகளுக்கு மேப்பிங்கைப் பயன்படுத்தவும் k8s-ingress-* அதிக எடை கொண்ட டெம்ப்ளேட்டைப் பயன்படுத்துதல்.

மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு
மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு

GET _template/k8s-ingress

{
  "k8s-ingress" : {
    "order" : 100,
    "index_patterns" : [
      "k8s-ingress-*"
    ],
    "settings" : {
      "index" : {
        "lifecycle" : {
          "name" : "k8s-ingress",
          "rollover_alias" : "k8s-ingress"
        },
        "codec" : "best_compression",
        "routing" : {
          "allocation" : {
            "require" : {
              "box_type" : "hot"
            }
          }
        },
        "number_of_shards" : "8",
        "number_of_replicas" : "1"
      }
    },
    "mappings" : {
      "numeric_detection" : false,
      "_meta" : { },
      "_source" : { },
      "dynamic_templates" : [
        {
          "all_fields" : {
            "mapping" : {
              "index" : false,
              "type" : "text"
            },
            "match" : "*"
          }
        }
      ],
      "date_detection" : false,
      "properties" : {
        "kubernetes" : {
          "type" : "object",
          "properties" : {
            "container_name" : {
              "type" : "keyword"
            },
            "container_hash" : {
              "index" : false,
              "type" : "keyword"
            },
            "host" : {
              "type" : "keyword"
            },
            "annotations" : {
              "type" : "object",
              "properties" : {
                "value" : {
                  "index" : false,
                  "type" : "text"
                },
                "key" : {
                  "index" : false,
                  "type" : "keyword"
                }
              }
            },
            "docker_id" : {
              "index" : false,
              "type" : "keyword"
            },
            "pod_id" : {
              "type" : "keyword"
            },
            "labels" : {
              "type" : "object",
              "properties" : {
                "value" : {
                  "type" : "keyword"
                },
                "key" : {
                  "type" : "keyword"
                }
              }
            },
            "namespace_name" : {
              "type" : "keyword"
            },
            "pod_name" : {
              "type" : "keyword"
            }
          }
        },
        "@timestamp" : {
          "type" : "date"
        },
        "nginx" : {
          "type" : "object",
          "properties" : {
            "access" : {
              "type" : "object",
              "properties" : {
                "agent" : {
                  "type" : "text"
                },
                "response_code" : {
                  "type" : "integer"
                },
                "upstream" : {
                  "type" : "object",
                  "properties" : {
                    "port" : {
                      "type" : "keyword"
                    },
                    "name" : {
                      "type" : "keyword"
                    },
                    "response_lenght" : {
                      "type" : "integer"
                    },
                    "response_time" : {
                      "index" : false,
                      "type" : "text"
                    },
                    "addr" : {
                      "type" : "keyword"
                    },
                    "status" : {
                      "index" : false,
                      "type" : "text"
                    }
                  }
                },
                "method" : {
                  "type" : "keyword"
                },
                "http_version" : {
                  "type" : "keyword"
                },
                "bytes_sent" : {
                  "type" : "integer"
                },
                "request_lenght" : {
                  "type" : "integer"
                },
                "url" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword"
                    }
                  }
                },
                "remote_user" : {
                  "type" : "text"
                },
                "referrer" : {
                  "type" : "text"
                },
                "remote_ip" : {
                  "type" : "ip"
                },
                "request_time" : {
                  "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis||dd/MMM/YYYY:H:m:s Z",
                  "type" : "date"
                },
                "host" : {
                  "type" : "keyword"
                },
                "time" : {
                  "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis||dd/MMM/YYYY:H:m:s Z",
                  "type" : "date"
                }
              }
            },
            "error" : {
              "type" : "object",
              "properties" : {
                "server" : {
                  "type" : "keyword"
                },
                "upstream" : {
                  "type" : "object",
                  "properties" : {
                    "port" : {
                      "type" : "keyword"
                    },
                    "proto" : {
                      "type" : "keyword"
                    },
                    "host" : {
                      "type" : "keyword"
                    },
                    "url" : {
                      "type" : "text",
                      "fields" : {
                        "keyword" : {
                          "type" : "keyword"
                        }
                      }
                    }
                  }
                },
                "method" : {
                  "type" : "keyword"
                },
                "level" : {
                  "type" : "keyword"
                },
                "http_version" : {
                  "type" : "keyword"
                },
                "pid" : {
                  "index" : false,
                  "type" : "integer"
                },
                "message" : {
                  "type" : "text"
                },
                "tid" : {
                  "index" : false,
                  "type" : "keyword"
                },
                "url" : {
                  "type" : "text",
                  "fields" : {
                    "keyword" : {
                      "type" : "keyword"
                    }
                  }
                },
                "referrer" : {
                  "type" : "text"
                },
                "remote_ip" : {
                  "type" : "ip"
                },
                "connection_id" : {
                  "index" : false,
                  "type" : "keyword"
                },
                "host" : {
                  "type" : "keyword"
                },
                "time" : {
                  "format" : "yyyy/MM/dd HH:mm:ss||yyyy/MM/dd||epoch_millis||dd/MMM/YYYY:H:m:s Z",
                  "type" : "date"
                }
              }
            }
          }
        },
        "log" : {
          "type" : "text"
        },
        "@version" : {
          "type" : "text",
          "fields" : {
            "keyword" : {
              "ignore_above" : 256,
              "type" : "keyword"
            }
          }
        },
        "eventtime" : {
          "type" : "float"
        }
      }
    },
    "aliases" : { }
  }
}

அனைத்து வார்ப்புருக்களையும் பயன்படுத்திய பிறகு, நாங்கள் ILM கொள்கையைப் பயன்படுத்துகிறோம் மற்றும் குறியீடுகளின் ஆயுளைக் கண்காணிக்கத் தொடங்குகிறோம்.

மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு

மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு

மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு

GET _ilm/policy/k8s-ingress

{
  "k8s-ingress" : {
    "version" : 14,
    "modified_date" : "2020-06-11T10:27:01.448Z",
    "policy" : {
      "phases" : {
        "warm" : { # теплая фаза
          "min_age" : "5d", # срок жизни индекса после ротации до наступления теплой фазы
          "actions" : {
            "allocate" : {
              "include" : { },
              "exclude" : { },
              "require" : {
                "box_type" : "warm" # куда перемещаем индекс
              }
            },
            "shrink" : {
              "number_of_shards" : 4 # обрезание индексов, т.к. у нас 4 ноды
            }
          }
        },
        "cold" : { # холодная фаза
          "min_age" : "25d", # срок жизни индекса после ротации до наступления холодной фазы
          "actions" : {
            "allocate" : {
              "include" : { },
              "exclude" : { },
              "require" : {
                "box_type" : "cold" # куда перемещаем индекс
              }
            },
            "freeze" : { } # замораживаем для оптимизации
          }
        },
        "hot" : { # горячая фаза
          "min_age" : "0ms",
          "actions" : {
            "rollover" : {
              "max_size" : "50gb", # максимальный размер индекса до ротации (будет х2, т.к. есть 1 реплика)
              "max_age" : "1d" # максимальный срок жизни индекса до ротации
            },
            "set_priority" : {
              "priority" : 100
            }
          }
        },
        "delete" : { # фаза удаления
          "min_age" : "120d", # максимальный срок жизни после ротации перед удалением
          "actions" : {
            "delete" : { }
          }
        }
      }
    }
  }
}

பிரச்சினைகள்

அமைவு மற்றும் பிழைத்திருத்த கட்டத்தில் சிக்கல்கள் இருந்தன.

சூடான கட்டம்

குறியீடுகளின் சரியான சுழற்சிக்கு, முடிவில் இருப்பது மிகவும் முக்கியமானது index_name-date-000026 வடிவ எண்கள் 000001. குறியீட்டில் கோடுகள் உள்ளன, அவை இறுதியில் எண்களின் இருப்புக்கான வழக்கமான வெளிப்பாட்டைப் பயன்படுத்தி குறியீடுகளை சரிபார்க்கின்றன. இல்லையெனில், ஒரு பிழை இருக்கும், குறியீட்டிற்கு எந்த கொள்கையும் பயன்படுத்தப்படாது, அது எப்போதும் சூடான கட்டத்தில் இருக்கும்.

சூடான கட்டம்

சுருக்கு (கட்ஆஃப்) — துண்டுகளின் எண்ணிக்கையைக் குறைத்தல், ஏனெனில் சூடான மற்றும் குளிர்ந்த நிலைகளில் 4 முனைகள் உள்ளன. ஆவணத்தில் பின்வரும் வரிகள் உள்ளன:

  • அட்டவணை படிக்க மட்டுமே இருக்க வேண்டும்.
  • குறியீட்டில் உள்ள ஒவ்வொரு துண்டின் நகலும் அதே முனையில் இருக்க வேண்டும்.
  • கிளஸ்டர் சுகாதார நிலை பசுமையாக இருக்க வேண்டும்.

ஒரு குறியீட்டை கத்தரிக்க, Elasticsearch அனைத்து முதன்மைத் துண்டுகளையும் ஒரு முனைக்கு நகர்த்துகிறது, துண்டிக்கப்பட்ட குறியீட்டை தேவையான அளவுருக்களுடன் நகலெடுக்கிறது, பின்னர் பழையதை நீக்குகிறது. அளவுரு total_shards_per_node ஒரு முனையில் பொருத்துவதற்கு முக்கிய துண்டுகளின் எண்ணிக்கைக்கு சமமாகவோ அல்லது அதிகமாகவோ இருக்க வேண்டும். இல்லையெனில், அறிவிப்புகள் இருக்கும் மற்றும் துண்டுகள் சரியான முனைகளுக்கு நகராது.

மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு
மீள் தேடலில் நீண்ட கால தரவு சேமிப்பு

GET /shrink-k8s-ingress-2020.06.06-000025/_settings

{
  "shrink-k8s-ingress-2020.06.06-000025" : {
    "settings" : {
      "index" : {
        "refresh_interval" : "5s",
        "auto_expand_replicas" : "0-1",
        "blocks" : {
          "write" : "true"
        },
        "provided_name" : "shrink-k8s-ingress-2020.06.06-000025",
        "creation_date" : "1592225525569",
        "priority" : "100",
        "number_of_replicas" : "1",
        "uuid" : "psF4MiFGQRmi8EstYUQS4w",
        "version" : {
          "created" : "7060299",
          "upgraded" : "7060299"
        },
        "lifecycle" : {
          "name" : "k8s-ingress",
          "rollover_alias" : "k8s-ingress",
          "indexing_complete" : "true"
        },
        "codec" : "best_compression",
        "routing" : {
          "allocation" : {
            "initial_recovery" : {
              "_id" : "_Le0Ww96RZ-o76bEPAWWag"
            },
            "require" : {
              "_id" : null,
              "box_type" : "cold"
            },
            "total_shards_per_node" : "8"
          }
        },
        "number_of_shards" : "4",
        "routing_partition_size" : "1",
        "resize" : {
          "source" : {
            "name" : "k8s-ingress-2020.06.06-000025",
            "uuid" : "gNhYixO6Skqi54lBjg5bpQ"
          }
        }
      }
    }
  }
}

குளிர் கட்டம்

உறைய (முடக்கம்) - வரலாற்றுத் தரவுகளில் வினவல்களை மேம்படுத்த, குறியீட்டை முடக்குகிறோம்.

உறைந்த குறியீடுகளில் செய்யப்படும் தேடல்கள், ஒவ்வொரு முனையிலும் உறைந்த துகள்களைத் தாக்கும் ஒரே நேரத்தில் தேடல்களின் எண்ணிக்கையைக் கட்டுப்படுத்த சிறிய, அர்ப்பணிக்கப்பட்ட, தேடல்_த்ரோட்டில்ட் த்ரெட்பூலைப் பயன்படுத்துகின்றன. உறைந்த துகள்களுடன் தொடர்புடைய நிலையற்ற தரவு கட்டமைப்புகளுக்குத் தேவைப்படும் கூடுதல் நினைவகத்தின் அளவை இது கட்டுப்படுத்துகிறது, இதன் விளைவாக அதிகப்படியான நினைவக நுகர்வுக்கு எதிராக முனைகளைப் பாதுகாக்கிறது.
உறைந்த குறியீடுகள் படிக்க மட்டுமே: நீங்கள் அவற்றை அட்டவணைப்படுத்த முடியாது.
உறைந்த குறியீடுகள் மீதான தேடல்கள் மெதுவாகச் செயல்படும் என்று எதிர்பார்க்கப்படுகிறது. உறைந்த குறியீடுகள் அதிக தேடல் சுமைக்காக அல்ல. உறைந்த குறியீட்டின் தேடல் முடிவடைய வினாடிகள் அல்லது நிமிடங்கள் ஆகலாம், குறியீடுகள் உறையாமல் இருக்கும் போது அதே தேடல்கள் மில்லி விநாடிகளில் முடிந்தாலும் கூட.

முடிவுகளை

ILM உடன் பணிபுரிவதற்கான முனைகளை எவ்வாறு தயாரிப்பது, சூடான முனைகளுக்கு இடையே துண்டுகளை விநியோகிக்க ஒரு டெம்ப்ளேட்டை அமைப்பது மற்றும் வாழ்க்கையின் அனைத்து கட்டங்களுடனும் ஒரு குறியீட்டிற்காக ILM ஐ அமைப்பது எப்படி என்பதை நாங்கள் கற்றுக்கொண்டோம்.

பயனுள்ள இணைப்புகள்

ஆதாரம்: www.habr.com