Elasticsearch:对时间序列数据流进行降采样(downsampling)

降采样提供了一种通过以降低的粒度存储时间序列数据来减少时间序列数据占用的方法。

指标(metrics)解决方案收集大量随时间增长的时间序列数据。 随着数据老化,它与系统当前状态的相关性越来越小。 降采样过程将固定时间间隔内的文档汇总为单个摘要文档。 每个摘要文档都包含原始数据的统计表示:每个指标的最小值(min)最大值 (max)总和 (sum)值计数 (value_count) 和平均值 (average)。 数据流时间序列维度存储不变。

实际上,降采样可以让你用数据分辨率和精度来换取存储大小。 你可以将其包含在索引生命周期管理 (ILM) 策略中,以自动管理指标数据的数量和相关成本。

它是如何工作的?

时间序列是特定实体随时间推移的一系列观察结果。 观察到的样本可以表示为连续函数,其中时间序列维度保持不变,时间序列指标随时间变化。

在 Elasticsearch 索引中,会为每个时间戳创建一个文档,其中包含不可变的时间序列维度以及指标名称和变化的指标值。 对于单个时间戳,可以存储多个时间序列维度和指标。

对于最新的相关数据,指标系列通常具有较低的采样时间间隔,因此它针对需要高数据分辨率的查询进行了优化。

图 2. 原始指标系列

降采样通过用更高采样间隔的数据流和该数据的统计表示替换原始时间序列来处理较旧的、访问频率较低的数据。 在原始指标样本可能已采集的情况下,例如每十秒采集一次,随着数据老化,你可以选择将样本粒度减少到每小时或每天。 你可以选择将冷归档数据的粒度减少到每月或更小。

图 3. 降采样指标系列

对时间序列数据运行降采样

要对时间序列索引进行降采样,请使用 Downsample API 并将 fixed_interval 设置为你想要的粒度级别:

POST /my-time-series-index/_downsample/my-downsampled-time-series-index
{
    "fixed_interval": "1d"
}

要将时间序列数据降采样作为 ILM 的一部分,请在 ILM 策略中包含降采样操作,并将 fixed_interval 设置为你想要的粒度级别:

PUT _ilm/policy/my_policy
{
  "policy": {
    "phases": {
      "warm": {
        "actions": {
          "downsample" : {
            "fixed_interval": "1h"
          }
        }
      }
    }
  }
}

查询降采样索引

你可以使用 _search 和 _async_search 端点来查询降采样索引。 可以在单个请求中查询多个原始数据和降采样索引,并且单个请求可以包括不同粒度(不同桶时间跨度)的降采样索引。 也就是说,你可以查询包含具有多个降采样间隔(例如15m、1h、1d)的降采样索引的数据流。

基于时间的直方图聚合的结果采用统一的桶大小,并且每个降采样索引返回忽略降采样时间间隔的数据。 例如,如果你对已按每小时分辨率 ( "fixed_interval": "1h") 降采样的降采样索引运行带有 "fixed_interval": "1m" 的 date_histogram 聚合,则查询将返回一个存储桶,其中包含位于 第 0 分钟,然后是 59 个空桶,然后是下一小时内再次有数据的桶。

关于降采样查询的注意事项

查询降采样索引有几点需要注意:

  • 当你在 Kibana 中并通过 Elastic 解决方案运行查询时,会返回正常响应,而不会通知某些查询索引已被降采样。
  • 对于日期直方图聚合,仅支持 fixed_intervals(而不支持日历感知间隔)。
  • 仅支持协调世界时 (UTC) 日期时间。

限制和局限

以下限制和局限适用于降采样:

  • 仅支持时间序列数据流中的索引。
  • 仅根据时间维度对数据进行降采样。 所有其他维度都将复制到新索引而不进行任何修改。
  • 在数据流内,降采样索引替换原始索引,并且原始索引被删除。 给定时间段内只能存在一个索引。
  • 源索引必须处于只读模式才能成功进行降采样过程。 有关详细信息,请查看如下的手动运行降采样示例。
  • 支持对同一时段的数据进行多次降采样(降采样索引的降采样)。 降采样间隔必须是降采样索引间隔的倍数。
  • 降采样作为 ILM 操作提供。 请参阅降采样。
  • 新的降采样索引是在原始索引的数据层上创建的,并继承其设置(例如,分片和副本的数量)。
  • 支持 gauge 和 counter 指标类型。
  • 降采样配置是从时间序列数据流索引映射中提取的。 唯一需要的额外设置是降采样固定间隔。

手动运行降采样

对时间序列数据流 (TSDS) 进行降采样的推荐方法是通过索引生命周期管理 (ILM)。我们将在下面进行详述。 但是,如果你不使用 ILM,则可以手动对 TSDS 进行降采样。 本指南向你展示如何使用典型的 Kubernetes 集群监控数据。

前提条件

  • 请参阅 TSDS 先决条件。
    • 集群权限:manage_ilm 和 manage_index_templates。
    • 索引权限:你创建或转换的任何 TSDS 的 create_doc 和 create_index。 要滚动 TSDS,你必须具有 manage 权限。
  • 不可能直接对数据流进行降采样,也不可能一次对多个索引进行降采样。 只能对一个时间序列索引(TSDS 后备索引)进行降采样。
  • 为了对索引进行降采样,它需要是只读的。 对于 TSDS 写入索引,这意味着需要先滚动并使其变为只读。
  • 降采样使用 UTC 时间戳。
  • 降采样需要时间序列索引中至少存在一个指标字段。

创建时间序列数据流

首先,你将创建 TSDS。 为了简单起见,在时间序列映射中,所有 time_series_metric 参数都设置为 gauge 类型,但也可以使用其他值,例如 counter 和 histogram。 time_series_metric 值确定降采样期间使用的统计表示的类型。

索引模板包含一组静态时间序列维度:主机 (host)、命名空间 (namespace)、节点 (node) 和 Pod。 时间序列维度不会因降采样过程而改变。

PUT _index_template/my-data-stream-template
{
  "index_patterns": [
    "my-data-stream*"
  ],
  "data_stream": {},
  "template": {
    "settings": {
      "index": {
        "mode": "time_series",
        "routing_path": [
          "kubernetes.namespace",
          "kubernetes.host",
          "kubernetes.node",
          "kubernetes.pod"
        ],
        "number_of_replicas": 0,
        "number_of_shards": 2
      }
    },
    "mappings": {
      "properties": {
        "@timestamp": {
          "type": "date"
        },
        "kubernetes": {
          "properties": {
            "container": {
              "properties": {
                "cpu": {
                  "properties": {
                    "usage": {
                      "properties": {
                        "core": {
                          "properties": {
                            "ns": {
                              "type": "long"
                            }
                          }
                        },
                        "limit": {
                          "properties": {
                            "pct": {
                              "type": "float"
                            }
                          }
                        },
                        "nanocores": {
                          "type": "long",
                          "time_series_metric": "gauge"
                        },
                        "node": {
                          "properties": {
                            "pct": {
                              "type": "float"
                            }
                          }
                        }
                      }
                    }
                  }
                },
                "memory": {
                  "properties": {
                    "available": {
                      "properties": {
                        "bytes": {
                          "type": "long",
                          "time_series_metric": "gauge"
                        }
                      }
                    },
                    "majorpagefaults": {
                      "type": "long"
                    },
                    "pagefaults": {
                      "type": "long",
                      "time_series_metric": "gauge"
                    },
                    "rss": {
                      "properties": {
                        "bytes": {
                          "type": "long",
                          "time_series_metric": "gauge"
                        }
                      }
                    },
                    "usage": {
                      "properties": {
                        "bytes": {
                          "type": "long",
                          "time_series_metric": "gauge"
                        },
                        "limit": {
                          "properties": {
                            "pct": {
                              "type": "float"
                            }
                          }
                        },
                        "node": {
                          "properties": {
                            "pct": {
                              "type": "float"
                            }
                          }
                        }
                      }
                    },
                    "workingset": {
                      "properties": {
                        "bytes": {
                          "type": "long",
                          "time_series_metric": "gauge"
                        }
                      }
                    }
                  }
                },
                "name": {
                  "type": "keyword"
                },
                "start_time": {
                  "type": "date"
                }
              }
            },
            "host": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "namespace": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "node": {
              "type": "keyword",
              "time_series_dimension": true
            },
            "pod": {
              "type": "keyword",
              "time_series_dimension": true
            }
          }
        }
      }
    }
  }
}

摄取时间序列数据

由于时间序列数据流被设计为仅接受最近的数据,因此在本例中,你将使用摄取管道在数据被索引时对数据进行时移。 因此,索引数据将具有最近 15 分钟的 @timestamp。

使用此请求创建管道:

PUT _ingest/pipeline/my-timestamp-pipeline
{
  "description": "Shifts the @timestamp to the last 15 minutes",
  "processors": [
    {
      "set": {
        "field": "ingest_time",
        "value": "{{_ingest.timestamp}}"
      }
    },
    {
      "script": {
        "lang": "painless",
        "source": """
          def delta = ChronoUnit.SECONDS.between(
            ZonedDateTime.parse("2022-06-21T15:49:00Z"),
            ZonedDateTime.parse(ctx["ingest_time"])
          );
          ctx["@timestamp"] = ZonedDateTime.parse(ctx["@timestamp"]).plus(delta,ChronoUnit.SECONDS).toString();
        """
      }
    }
  ]
}

接下来,使用批量 API 请求自动创建 TSDS 并为一组 10 个文档编制索引:

PUT /my-data-stream/_bulk?refresh&pipeline=my-timestamp-pipeline
{"create": {}}
{"@timestamp":"2022-06-21T15:49:00Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":91153,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":463314616},"usage":{"bytes":307007078,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":585236},"rss":{"bytes":102728},"pagefaults":120901,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:45:50Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":124501,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":982546514},"usage":{"bytes":360035574,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1339884},"rss":{"bytes":381174},"pagefaults":178473,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:44:50Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":38907,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":862723768},"usage":{"bytes":379572388,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":431227},"rss":{"bytes":386580},"pagefaults":233166,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:44:40Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":86706,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":567160996},"usage":{"bytes":103266017,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1724908},"rss":{"bytes":105431},"pagefaults":233166,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:44:00Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":150069,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":639054643},"usage":{"bytes":265142477,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1786511},"rss":{"bytes":189235},"pagefaults":138172,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:42:40Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":82260,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":854735585},"usage":{"bytes":309798052,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":924058},"rss":{"bytes":110838},"pagefaults":259073,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:42:10Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":153404,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":279586406},"usage":{"bytes":214904955,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1047265},"rss":{"bytes":91914},"pagefaults":302252,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:40:20Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":125613,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":822782853},"usage":{"bytes":100475044,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":2109932},"rss":{"bytes":278446},"pagefaults":74843,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:40:10Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":100046,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":567160996},"usage":{"bytes":362826547,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":1986724},"rss":{"bytes":402801},"pagefaults":296495,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}
{"create": {}}
{"@timestamp":"2022-06-21T15:38:30Z","kubernetes":{"host":"gke-apps-0","node":"gke-apps-0-0","pod":"gke-apps-0-0-0","container":{"cpu":{"usage":{"nanocores":40018,"core":{"ns":12828317850},"node":{"pct":2.77905e-05},"limit":{"pct":2.77905e-05}}},"memory":{"available":{"bytes":1062428344},"usage":{"bytes":265142477,"node":{"pct":0.01770037710617187},"limit":{"pct":9.923134671484496e-05}},"workingset":{"bytes":2294743},"rss":{"bytes":340623},"pagefaults":224530,"majorpagefaults":0},"start_time":"2021-03-30T07:59:06Z","name":"container-name-44"},"namespace":"namespace26"}}

你可以使用搜索 API 检查文档是否已正确索引:

GET /my-data-stream/_search

对数据运行以下聚合以计算一些有趣的统计数据:

GET /my-data-stream/_search
{
  "size": 0,
  "aggs": {
    "tsid": {
      "terms": {
        "field": "_tsid"
      },
      "aggs": {
        "over_time": {
          "date_histogram": {
            "field": "@timestamp",
            "fixed_interval": "1d"
          },
          "aggs": {
            "min": {
              "min": {
                "field": "kubernetes.container.memory.usage.bytes"
              }
            },
            "max": {
              "max": {
                "field": "kubernetes.container.memory.usage.bytes"
              }
            },
            "avg": {
              "avg": {
                "field": "kubernetes.container.memory.usage.bytes"
              }
            }
          }
        }
      }
    }
  }
}

对 TSDS 进行降采样

TSDS 无法直接降采样。 你需要对其后备索引进行降采样。 你可以通过运行以下命令查看数据流的后备索引:

GET /_data_stream/my-data-stream

在对支持索引进行降采样之前,需要滚动 TSDS,并且需要将旧索引设为只读。

使用 rollver API 滚动 TSDS:

POST /my-data-stream/_rollover/

从响应中复制 old_index 的名称。 在以下步骤中,将索引名称替换为你的 old_index 的名称。

旧索引需要设置为只读模式。 运行以下请求:

PUT /.ds-my-data-stream-2023.11.30-000001/_block/write

接下来,使用 downsample API 对索引进行降采样,将时间序列间隔设置为一小时:

POST /.ds-my-data-stream-2023.11.30-000001/_downsample/.ds-my-data-stream-2023.11.30-000001-downsample
{
  "fixed_interval": "1h"
}

现在你可以修改数据流,并将原始索引替换为降采样后的索引:

POST _data_stream/_modify
{
  "actions": [
    {
      "remove_backing_index": {
        "data_stream": "my-data-stream",
        "index": ".ds-my-data-stream-2023.11.30-000001"
      }
    },
    {
      "add_backing_index": {
        "data_stream": "my-data-stream",
        "index": ".ds-my-data-stream-2023.11.30-000001-downsample"
      }
    }
  ]
}

你现在可以删除旧的后备索引。 但请注意,这会删除原始数据。 如果将来可能需要原始数据,请不要删除索引。

查看结果

重新运行之前的搜索查询(请注意,在查询降采样索引时,需要注意一些细微差别):

GET /my-data-stream/_search

具有新的降采样后备索引的 TSDS 仅包含一份文档。 对于计数器,该文档仅具有最后的值。 对于 gauge,字段类型现在为 aggregate_metric_double。 你会看到基于原始采样指标的 min、max、sum 和 value_count 统计信息:

{
  "took": 3,
  "timed_out": false,
  "_shards": {
    "total": 4,
    "successful": 4,
    "skipped": 0,
    "failed": 0
  },
  "hits": {
    "total": {
      "value": 1,
      "relation": "eq"
    },
    "max_score": 1,
    "hits": [
      {
        "_index": ".ds-my-data-stream-2023.11.30-000001-downsample",
        "_id": "0eL0wC_4-45SnTNFAAABjB5iLgA",
        "_score": 1,
        "_source": {
          "@timestamp": "2023-11-30T04:00:00.000Z",
          "_doc_count": 10,
          "ingest_time": "2023-11-30T04:24:20.124Z",
          "kubernetes": {
            "container": {
              "cpu": {
                "usage": {
                  "core": {
                    "ns": 12828317850
                  },
                  "limit": {
                    "pct": 0.0000277905
                  },
                  "nanocores": {
                    "min": 38907,
                    "max": 153404,
                    "sum": 992677,
                    "value_count": 10
                  },
                  "node": {
                    "pct": 0.0000277905
                  }
                }
              },
              "memory": {
                "available": {
                  "bytes": {
                    "min": 279586406,
                    "max": 1062428344,
                    "sum": 7101494721,
                    "value_count": 10
                  }
                },
                "majorpagefaults": 0,
                "pagefaults": {
                  "min": 74843,
                  "max": 302252,
                  "sum": 2061071,
                  "value_count": 10
                },
                "rss": {
                  "bytes": {
                    "min": 91914,
                    "max": 402801,
                    "sum": 2389770,
                    "value_count": 10
                  }
                },
                "usage": {
                  "bytes": {
                    "min": 100475044,
                    "max": 379572388,
                    "sum": 2668170609,
                    "value_count": 10
                  },
                  "limit": {
                    "pct": 0.00009923134
                  },
                  "node": {
                    "pct": 0.017700378
                  }
                },
                "workingset": {
                  "bytes": {
                    "min": 431227,
                    "max": 2294743,
                    "sum": 14230488,
                    "value_count": 10
                  }
                }
              },
              "name": "container-name-44",
              "start_time": "2021-03-30T07:59:06.000Z"
            },
            "host": "gke-apps-0",
            "namespace": "namespace26",
            "node": "gke-apps-0-0",
            "pod": "gke-apps-0-0-0"
          }
        }
      }
    ]
  }
}

重新运行之前的聚合。 即使聚合在仅包含 1 个文档的降采样 TSDS 上运行,它也会返回与原始 TSDS 上的早期聚合相同的结果。

GET /my-data-stream/_search
{
  "size": 0,
  "aggs": {
    "tsid": {
      "terms": {
        "field": "_tsid"
      },
      "aggs": {
        "over_time": {
          "date_histogram": {
            "field": "@timestamp",
            "fixed_interval": "1d"
          },
          "aggs": {
            "min": {
              "min": {
                "field": "kubernetes.container.memory.usage.bytes"
              }
            },
            "max": {
              "max": {
                "field": "kubernetes.container.memory.usage.bytes"
              }
            },
            "avg": {
              "avg": {
                "field": "kubernetes.container.memory.usage.bytes"
              }
            }
          }
        }
      }
    }
  }
}

此示例演示了降采样如何在你选择的任何时间范围内显着减少为时间序列数据存储的文档数量。 随着时间序列数据的老化和数据分辨率变得不那么重要,还可以对已经降采样的数据执行降采样,以进一步减少存储和相关成本。

对 TSDS 进行降采样的推荐方法是使用 ILM。 要了解更多信息,请尝试使用 ILM 运行降采样示例。这个将在我们的下面一篇文章中进行介绍。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/208596.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

测试面试:不明白什么是质量保障

这是我面试经常问的一个问题,很多人并不明白其中的区别。 如上图,整体的质量体系架构图相对简单,主要包含三个部分:愿景(高质量交付-快、好)、能力(中间三层不同的能力)和…

kerberos详解

一、介绍 kerberos概述 Kerberos始于20世纪80年代早期麻省理工学院(MIT)的一个研究项目,是一个网络身份验证系统。Kerberos提供的完整定义是安全的、单点登录的、可信的第三方相互身份验证服务。 认证过程 相关概念 KDC(key D…

HTML5 的全局属性 hidden 和 display:none 的关系

目录 1,hidden 和 display:none 的关系2,其他隐藏元素的方式2.1,语意上的隐藏2.2,视觉上的隐藏 1,hidden 和 display:none 的关系 hidden - MDN 参考 一句话总结:hidden 是HTML5 新增的全局布尔属性&…

Python | 轻量ORM框架Peewee的基础使用(增删改查、自动创建模型类、事务装饰器)

文章目录 01 简介02 安装03 自动创建模型类04 基础使用4.1 查询4.2 新增4.3 更新4.4 删除 05 事务 01 简介 在使用python开发的过程中,有时需要一些简单的数据库操作,而Peewee正是理想的选择,它是一个小巧而灵活的 Python ORM(对…

Hdoop学习笔记(HDP)-Part.7 安装MySQL

七、安装MySQL mysql主从复制的原理: 1)master将数据改变记录到二进制日志(binary log)中,也即是配置文件log-bin指定的文件(这些记录叫做二进制日志事件,binary log events)&#…

(六)Tiki-taka算法(TTA)求解无人机三维路径规划研究(MATLAB)

一、无人机模型简介: 单个无人机三维路径规划问题及其建模_IT猿手的博客-CSDN博客 参考文献: [1]胡观凯,钟建华,李永正,黎万洪.基于IPSO-GA算法的无人机三维路径规划[J].现代电子技术,2023,46(07):115-120 二、Tiki-taka算法(TTA&#xf…

Windows环境 dockertopdesk 部署gitlab

1.在dockertopdesk里搜索 gitlab镜像 (pull)拉取镜像 2.运行镜像到容器 mkdir gitlab gitlab/etc gitlab/log gitlab/opt docker run -id -p 3000:80 -p 9922:22 -v /root/gitlab/etc:/etc/gitlab -v /root/gitlab/log:/var/log/gitlab -v /root/gitlab/opt:/var/opt/gitla…

IntelliJ IDEA 之初体验(上)

IntelliJ IDEA 是一款由 JetBrains 公司开发的强大的集成开发环境(IDE),专注于 Java 开发,同时支持多种其他编程语言。本文将详细介绍 IntelliJ IDEA 的安装过程以及一些常用的基本操作。 第一步:下载与安装 IntelliJ…

【LeetCode每日一题合集】2023.11.20-2023.11.26 (二叉树中的伪回文路径)

文章目录 53. 最大子数组和解法1——DP解法2——分治(维护区间、类似线段树的思想) 2216. 美化数组的最少删除数(贪心)2304. 网格中的最小路径代价1410. HTML 实体解析器(模拟)2824. 统计和小于目标的下标对…

k8s ingress 无法找到端点

文章目录 ingress rule无法找到端点这个注解是什么意思呢?为何不生效呢?端点无法更新?如何确认ingressclass呢?修复端点无法发现的问题多个ingress controller 架构 ingress rule无法找到端点 在vnnox-cn集群创建ingress&#xf…

IntelliJ IDEA创建springboot项目时不能选择java8的问题解决方案

最近博主也有创建springboot项目,发现了IntelliJ IDEA在通过Spring Initilizer初始化项目的时候已经没有java8版本的选项了。 基于这个问题,有了这篇文章的分享,希望能够帮助大家克服这个困难。 如图,现在创建springboot项目的时…

win10 修改任务栏颜色 “开始菜单、任务栏和操作中心” 是灰色无法点击,一共就两步,彻底解决有图有真相。

电脑恢复了一下出厂设置、然后任务栏修改要修改一下颜色,之前会后来忘记了,擦。 查了半天文档没用,最后找到官网才算是看到问题解决办法。 问题现象: 解决办法: 往上滑、找到这里 浅色改成深色、然后就可以了,就这么简单。 w…

Drift plus penalty 漂移加惩罚Part2——性能分析

文章目录 正文Performance analysisAverage penalty analysis 平均惩罚分析Average queue size analysis 平均队列大小分析Probability 1 convergenceApplication to queues with finite capacityTreatment of queueing systemsConvex functions of time averages Delay tradeo…

服务器数据恢复—服务器断电导致XenServer数据文件丢失的数据恢复案例

服务器数据恢复环境: 某品牌720服务器搭配该品牌某型号RAID卡,使用4块STAT硬盘组建了一组RAID10阵列。服务器上部署XenServer虚拟化平台,系统盘 数据盘两个虚拟机磁盘。虚拟机上安装的是Windows Server操作系统,作为Web服务器使用…

【算法刷题】Day9

文章目录 611. 有效三角形的个数题干:题解:代码: LCR 179. 查找总价格为目标值的两个商品题干:题解:代码: 1137. 第 N 个泰波那契数题干:原理:1、状态表示(dp表里面的值所…

如何让Win11的右键菜单恢复到Win10的样式

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言如何让Win11的右键菜单恢复到Win10的样式1. winr打开运行,输入cmd后回车2.输入命令并回车3.重启计算机 前言 提示:这里可以添加本文要记…

敌方坦克发射思路[java坦克大战]

1.在敌人坦克类,创建Vector用于保存Shot对象 2.当每创建一个敌人坦克对象,就给该敌人坦克对象初始化一个Shot对象(注意子弹初始位置以及必须在设置完敌人坦克初始方向),将该对象加入Vector后,立即启动shot发…

熬夜会秃头——beta冲刺Day7

这个作业属于哪个课程2301-计算机学院-软件工程社区-CSDN社区云这个作业要求在哪里团队作业—beta冲刺事后诸葛亮-CSDN社区这个作业的目标记录beta冲刺Day7团队名称熬夜会秃头团队置顶集合随笔链接熬夜会秃头——Beta冲刺置顶随笔-CSDN社区 一、团队成员会议总结 1、成员工作…

时序预测 | Python实现TCN时间卷积神经网络时间序列预测(多图,多指标)

时序预测 | Python实现TCN时间卷积神经网络时间序列预测(多图,多指标) 目录 时序预测 | Python实现TCN时间卷积神经网络时间序列预测(多图,多指标)预测效果基本介绍环境准备程序设计参考资料预测效果 基本介绍

专注数据采集分析系统研发 做设备与MES系统中转站

数据采集是实现MES系统与设备对接的核心环节。通过采集设备产生的实时数据,将其传输给MES系统进行处理和分析。数据采集可以通过直接连接设备的传感器或者通过设备上安装的采集设备实现。采集的数据可以包括设备的运行状态、产量数据、测量数据、能耗数据等。通过数…