በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ

በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ

ስሜ Igor Sidorenko እባላለሁ, እኔ የዶምክሊክን አጠቃላይ መሠረተ ልማት በሚጠብቁ የአስተዳዳሪዎች ቡድን ውስጥ የቴክኒክ መሪ ነኝ.

በ Elasticsearch ውስጥ የተከፋፈለ የውሂብ ማከማቻ በማዘጋጀት ረገድ ያለኝን ልምድ ማካፈል እፈልጋለሁ። በመስቀለኛ መንገዱ ላይ ለሻርዶች ስርጭት ምን አይነት ቅንጅቶች ተጠያቂ እንደሆኑ፣ ILM እንዴት እንደሚሰራ እና እንደሚሰራ እንመለከታለን።

በምዝግብ ማስታወሻዎች የሚሰሩ, አንድ መንገድ ወይም ሌላ, በኋላ ላይ ለመተንተን የረጅም ጊዜ ማከማቻ ችግር ያጋጥማቸዋል. በElasticsearch ውስጥ፣ ይህ በተለይ እውነት ነው፣ ምክንያቱም ሁሉም ነገር በተቆጣጣሪው ተግባር አሳዛኝ ነበር። ስሪት 6.6 የ ILM ተግባርን አስተዋውቋል። እሱ 4 ደረጃዎችን ያቀፈ ነው-

  • ትኩስ - መረጃ ጠቋሚው በንቃት እየተዘመነ እና እየተጠየቀ ነው።
  • ሞቅ ያለ - መረጃ ጠቋሚው ከአሁን በኋላ አልዘመነም፣ ነገር ግን አሁንም እየተጠየቀ ነው።
  • ቀዝቃዛ - መረጃ ጠቋሚው ከአሁን በኋላ አልተዘመነም እና ብዙም አይጠየቅም. መረጃው አሁንም መፈለግ አለበት፣ ነገር ግን መጠይቆች ቀርፋፋ ሊሆኑ ይችላሉ።
  • ሰርዝ - መረጃ ጠቋሚው ከአሁን በኋላ አያስፈልግም እና ደህንነቱ በተጠበቀ ሁኔታ ሊሰረዝ ይችላል.

የተሰጠው

  • Elasticsearch Data Hot፡ 24 ፕሮሰሰር፣ 128 ጂቢ ማህደረ ትውስታ፣ 1,8 ቴባ SSD RAID 10 (8 ኖዶች)።
  • Elasticsearch Data Warm፡ 24 ፕሮሰሰር፣ 64 ጊባ ማህደረ ትውስታ፣ 8 ቴባ NetApp SSD ፖሊሲ (4 ኖዶች)።
  • Elasticsearch Data Cold፡ 8 ፕሮሰሰር፣ 32 ጂቢ ማህደረ ትውስታ፣ 128 ቴባ HDD RAID 10 (4 nodes)።

ግብ

እነዚህ ቅንብሮች ግለሰባዊ ናቸው, ሁሉም በአንጓዎች ላይ ባለው ቦታ, በመረጃ ጠቋሚዎች, በምዝግብ ማስታወሻዎች, ወዘተ ላይ ይወሰናል. በቀን 2-3 ቴባ መረጃ አለን።

  • 5 ቀናት - ሙቅ ደረጃ (8 ዋና / 1 ቅጂ)።
  • 20 ቀናት - ሞቃታማ ደረጃ (መቀነስ-ኢንዴክስ 4 ዋና / 1 ቅጂ).
  • 90 ቀናት - ቀዝቃዛ ደረጃ (ፍሪዝ-ኢንዴክስ 4 ዋና / 1 ቅጂ).
  • 120 ቀናት - ደረጃ ሰርዝ.

Elasticsearchን በማዘጋጀት ላይ

በአንጓዎች ላይ ሸርጣን ለማሰራጨት አንድ ግቤት ብቻ ያስፈልግዎታል፡-

  • ቅናሽ- አንጓዎች;
    ~]# 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

Logstash በማዘጋጀት ላይ

እንዴት ነው ሁሉም የሚሰራው እና ይህን ባህሪ እንዴት ተግባራዊ አድርገነዋል? ወደ Elasticsearch ምዝግብ ማስታወሻዎችን በማግኘት እንጀምር። ሁለት መንገዶች አሉ፡-

  1. Logstash ከካፍካ የምዝግብ ማስታወሻዎችን ያወጣል። ንፁህ ማንሳት ወይም ከጎንዎ መለወጥ ይችላል።
  2. የሆነ ነገር ራሱ ወደ Elasticsearch ይጽፋል፣ ለምሳሌ፣ APM አገልጋይ።

በ Logstash በኩል ኢንዴክሶችን የማስተዳደር ምሳሌን ተመልከት። ኢንዴክስ ይፈጥራል እና በእሱ ላይ ይተገበራል የመረጃ ጠቋሚ ንድፍ እና ተዛማጅ አይ.ኤም.ኤም..

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. ከፍተኛ ክብደት ያላቸው አብነቶች ያሉትን የአብነት መለኪያዎች ይሽራሉ ወይም አዳዲሶችን ይጨምራሉ።

በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ
በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ

GET _አብነት/ነባሪ

{
  "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-* ከፍተኛ ክብደት ያለው አብነት በመጠቀም.

በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ
በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ

GET _template/k8s-መግቢያ

{
  "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 ፖሊሲን እንተገብራለን እና የመረጃ ጠቋሚዎችን ህይወት መከታተል እንጀምራለን.

በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ

በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ

በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ

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 በአንድ መስቀለኛ መንገድ ላይ ለመገጣጠም ከዋናው የሻርዶች ብዛት ጋር እኩል መሆን ወይም የበለጠ መሆን አለበት. ያለበለዚያ ፣ ማሳወቂያዎች ይኖራሉ እና ቁርጥራጮች ወደ ትክክለኛው አንጓዎች አይንቀሳቀሱም።

በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ
በ Elasticsearch ውስጥ የረጅም ጊዜ የውሂብ ማከማቻ

GET / shrink-k8s-ingress-2020.06.06-000025/_ቅንብሮች

{
  "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ን ከሁሉም የሕይወት ደረጃዎች ጋር ለመጠቆም ተምረናል።

ጠቃሚ አገናኞች

ምንጭ: hab.com