Stòradh dàta fad-ùine ann an Elasticsearch

Stòradh dàta fad-ùine ann an Elasticsearch

Is e m ’ainm Igor Sidorenko, tha mi nam stiùiriche teignigeach anns an sgioba de luchd-rianachd a tha a’ cumail suas bun-structar iomlan Domclick.

Tha mi airson m ’eòlas a cho-roinn ann a bhith a’ stèidheachadh stòradh dàta sgaoilte ann an Elasticsearch. Seallaidh sinn air dè na roghainnean air na nodan a tha cunntachail airson cuairteachadh shards, mar a tha ILM ag obair agus ag obair.

Bidh an fheadhainn a tha ag obair le logaichean, aon dòigh no dòigh eile, an aghaidh duilgheadas stòraidh fad-ùine airson mion-sgrùdadh nas fhaide air adhart. Ann an Elasticsearch, tha seo gu sònraichte fìor, leis gu robh a h-uile dad mì-fhortanach le gnìomhachd an neach-gleidhidh. Thug dreach 6.6 a-steach comas ILM. Tha e air a dhèanamh suas de 4 ìrean:

  • Hot - Tha an clàr-amais ga ùrachadh gu gnìomhach agus ga cheasnachadh.
  • Blàth - Chan eil an clàr-amais air ùrachadh tuilleadh, ach tha e fhathast ga cheasnachadh.
  • Fuar - Chan eil an clàr-amais air ùrachadh tuilleadh agus is ann ainneamh a thèid a cheasnachadh. Feumaidh am fiosrachadh a bhith air a sgrùdadh fhathast, ach dh’ fhaodadh ceistean a bhith nas slaodaiche.
  • Sguab às - Chan eil feum air a 'chlàr-amais tuilleadh agus faodar a sguabadh às gu sàbhailte.

Air a thoirt seachad

  • Dàta Elasticsearch Hot: 24 pròiseasairean, cuimhne 128 GB, 1,8 TB SSD RAID 10 (nòtaichean 8).
  • Blàth Dàta Elasticsearch: 24 pròiseasairean, cuimhne 64 GB, Poileasaidh 8 TB NetApp SSD (nòtaichean 4).
  • Fuar Dàta Elasticsearch: 8 pròiseasairean, cuimhne 32 GB, 128 TB HDD RAID 10 (4 nod).

Amas

Tha na roghainnean sin fa leth, tha e uile an urra ris an àite air na nodan, an àireamh de chlàran-amais, logaichean, msaa. Tha 2-3 TB de dhàta againn gach latha.

  • 5 latha - Ìre teth (8 prìomh / 1 mac-samhail).
  • 20 latha - ìre blàth (crìonadh-clàr-amais 4 prìomh / 1 mac-samhail).
  • 90 latha - ìre fhuar (reothadh-clàr-amais 4 prìomh / 1 mac-samhail).
  • 120 latha - Sguab às ìre.

A’ stèidheachadh Elasticsearch

Gus slatan a sgaoileadh thairis air nodan, chan fheum thu ach aon paramadair:

  • Hot-nòtaichean:
    ~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
    # Add custom attributes to the node:
    node.attr.box_type: hot
  • Blàth-nòtaichean:
    ~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
    # Add custom attributes to the node:
    node.attr.box_type: warm
  • Fuar-nòtaichean:
    ~]# cat /etc/elasticsearch/elasticsearch.yml | grep attr
    # Add custom attributes to the node:
    node.attr.box_type: cold

Logstash a stèidheachadh

Ciamar a tha e uile ag obair agus ciamar a chuir sinn am feart seo an gnìomh? Feuch an tòisich sinn le bhith a’ faighinn logaichean a-steach gu Elasticsearch. Tha dà dhòigh ann:

  1. Bidh Logstash a’ faighinn logaichean bho Kafka. Faodaidh tu togail glan no tionndadh air do thaobh.
  2. Bidh rudeigin fhèin a’ sgrìobhadh gu Elasticsearch, mar eisimpleir, frithealaiche APM.

Beachdaich air eisimpleir de stiùireadh clàran-amais tro Logstash. Bidh e a 'cruthachadh clàr-amais agus a' buntainn ris pàtran clàr-amais agus co-fhreagarrach SEOLADH.

k8s-inntrigeadh.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
    }
}

Suidheachadh Kibana

Tha pàtran bunaiteach ann a tha a 'buntainn ris a h-uile clàr-amais ùr. Bidh e a’ suidheachadh cuairteachadh clàran-amais teth, an àireamh de shards, mac-samhail, msaa. Tha cuideam an teamplaid air a dhearbhadh leis an roghainn order. Bidh teamplaidean le cuideam nas àirde a’ dol thairis air na crìochan teamplaid a th’ ann mar-thà no a’ cur feadhainn ùra ris.

Stòradh dàta fad-ùine ann an Elasticsearch
Stòradh dàta fad-ùine ann an Elasticsearch

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" : { }
  }
}

An uairsin cuir a-steach am mapa gu na clàran-amais k8s-ingress-* cleachdadh teamplaid le cuideam nas àirde.

Stòradh dàta fad-ùine ann an Elasticsearch
Stòradh dàta fad-ùine ann an Elasticsearch

GET _template/k8s-inntrigeadh

{
  "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" : { }
  }
}

Às deidh dhuinn na teamplaidean gu lèir a chuir an sàs, bidh sinn a’ cleachdadh poileasaidh ILM agus a’ tòiseachadh a’ cumail sùil air beatha nan clàran-amais.

Stòradh dàta fad-ùine ann an Elasticsearch

Stòradh dàta fad-ùine ann an Elasticsearch

Stòradh dàta fad-ùine ann an Elasticsearch

GET _ilm/policy/k8s-ing

{
  "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" : { }
          }
        }
      }
    }
  }
}

Duilgheadasan

Bha duilgheadasan ann aig an ìre rèiteachaidh agus deasbaid.

Ìre teth

Airson an cuairteachadh ceart de chlàran-amais, tha làthaireachd aig an deireadh deatamach index_name-date-000026 àireamhan cruth 000001. Tha loidhnichean anns a’ chòd a nì sgrùdadh air clàran-amais a’ cleachdadh abairt àbhaisteach airson làthaireachd àireamhan aig an deireadh. Rud eile, bidh mearachd ann, cha tèid poileasaidhean sam bith a chuir an sàs sa chlàr-amais, agus bidh e an-còmhnaidh aig ìre teth.

Ìre blàth

Crìonadh (gearradh dheth) - lughdaich an àireamh de shards, leis gu bheil 4 nodan againn anns na h-ìrean blàth is fuar Tha na loidhnichean a leanas anns na sgrìobhainnean:

  • Feumaidh an clàr-amais a bhith ri leughadh a-mhàin.
  • Feumaidh leth-bhreac de gach shard sa chlàr-amais fuireach air an aon nód.
  • Feumaidh inbhe slàinte na buidhne a bhith uaine.

Gus clàr-amais a ghearradh, bidh Elasticsearch a’ gluasad a h-uile prìomh shard gu aon nód, a’ dùblachadh a’ chlàr-amais truncated leis na paramadairean riatanach, agus an uairsin a’ cuir às don t-seann fhear. Paramadair total_shards_per_node feumaidh iad a bhith co-ionann no nas motha na an àireamh de phrìomh shards airson a bhith a’ freagairt air aon nód. Rud eile, bidh fiosan ann agus cha ghluais shards gu na nodan ceart.

Stòradh dàta fad-ùine ann an Elasticsearch
Stòradh dàta fad-ùine ann an Elasticsearch

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"
          }
        }
      }
    }
  }
}

Ìre fuar

Freeze (reothadh) - Bidh sinn a’ reothadh a’ chlàr-amais gus ceistean mu dhàta eachdraidheil a bharrachadh.

Bidh rannsachaidhean a chaidh a dhèanamh air clàran-amais reòta a’ cleachdadh an t-snàthainn beag, coisrigte, search_throttled gus smachd a chumail air an àireamh de rannsachaidhean co-aontach a bhuaileas slatan reòta air gach nód. Tha seo a’ cuingealachadh na tha de chuimhne a bharrachd a dhìth airson na structaran dàta neo-ghluasadach a tha co-chosmhail ri mìrean reòta, a tha mar sin a’ dìon nodan an aghaidh cus caitheamh cuimhne.
Tha clàran-amais reòta ri leughadh a-mhàin: chan urrainn dhut clàr-amais a dhèanamh annta.
Thathas an dùil gun tèid rannsachaidhean air clàran-amais reòta a dhèanamh gu slaodach. Chan eil clàran-amais reòta airson luchd sgrùdaidh àrd. Dh’fhaodadh gun toir rannsachadh air clàr-amais reòta diogan no mionaidean airson a chrìochnachadh, eadhon ged a bhiodh na h-aon rannsachaidhean air an crìochnachadh ann am milleanan-tomhais nuair nach robh na clàran-amais reòta.

Builean

Dh’ionnsaich sinn mar a dheasaicheas sinn nodan airson a bhith ag obair le ILM, stèidhich sinn teamplaid airson a bhith a’ sgaoileadh shards am measg nodan teth, agus stèidhich sinn ILM airson clàr-amais le gach ìre de bheatha.

Ceanglaichean feumail

Source: www.habr.com