一起来学ElasticSearch(十)

简介: 前言目前正在出一个Es专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~承接上文,上节给大家讲的es聚合还有一点内容,本节给大家更完~本文偏实战一些,为了方便演示,本节示例沿用上节索引,好了, 废话不多说直接开整吧~聚合排序我们如何在聚合结果中进行自定义字段排序呢?

前言

目前正在出一个Es专题系列教程, 篇幅会较多, 喜欢的话,给个关注❤️ ~

承接上文,上节给大家讲的es聚合还有一点内容,本节给大家更完~

本文偏实战一些,为了方便演示,本节示例沿用上节索引,好了, 废话不多说直接开整吧~

聚合排序

我们如何在聚合结果中进行自定义字段排序呢?

默认排序

之前给大家讲过,默认情况下terms聚合默认使用doc_count倒序排列,也可以使用_count同样代表doc_count,下面一起看个例子:

GET req_log/_search
{
"aggs": {
 "req_count": {
   "terms": {
     "field": "path"
   }
 }
}
}

返回:

.....此处省略
"aggregations" : {
    "req_count" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "/api/post/3",
          "doc_count" : 3
        },
        {
          "key" : "/api/post/6",
          "doc_count" : 3
        },
        {
          "key" : "/api/post/1",
          "doc_count" : 2
        },
        {
          "key" : "/api/post/2",
          "doc_count" : 2
        },
        {
          "key" : "/api/post/4",
          "doc_count" : 2
        },
        {
          "key" : "/api/post/10",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/12",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/20",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/7",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/8",
          "doc_count" : 1
        }
      ]
    }
  }

看结果可以看到,默认下_count倒序,如果想升序怎么操作呢?

GET req_log/_search
{
"aggs": {
 "req_count": {
   "terms": {
     "field": "path",
     "order": {
       "_count": "asc"
     }
   }
 }
}
}

再看结果:

 .... 此处省略
  "aggregations" : {
    "req_count" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "/api/post/10",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/12",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/20",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/7",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/8",
          "doc_count" : 1
        },
        {
          "key" : "/api/post/1",
          "doc_count" : 2
        },
        {
          "key" : "/api/post/2",
          "doc_count" : 2
        },
        {
          "key" : "/api/post/4",
          "doc_count" : 2
        },
        {
          "key" : "/api/post/3",
          "doc_count" : 3
        },
        {
          "key" : "/api/post/6",
          "doc_count" : 3
        }
      ]
    }
  }

看结果,它是按照_count升序排序的。当然,这里也可以按照_key进行排序,来看个例子:

GET req_log/_search
{
"aggs": {
 "req_count": {
   "terms": {
     "field": "times",
     "order": {
       "_key": "asc"
     }
   }
 }
}
}

结果:

 ....
 "aggregations" : {
    "req_count" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 6,
      "buckets" : [
        {
          "key" : 20,
          "doc_count" : 1
        },
        {
          "key" : 30,
          "doc_count" : 1
        },
        {
          "key" : 80,
          "doc_count" : 2
        },
        {
          "key" : 89,
          "doc_count" : 1
        },
        {
          "key" : 120,
          "doc_count" : 1
        },
        {
          "key" : 150,
          "doc_count" : 1
        },
        {
          "key" : 210,
          "doc_count" : 1
        },
        {
          "key" : 270,
          "doc_count" : 1
        },
        {
          "key" : 380,
          "doc_count" : 1
        },
        {
          "key" : 400,
          "doc_count" : 1
        }
      ]
    }
  }

指定了times字段,_key按照升序进行排序

同层级自定义排序

那如何进行自定义排序呢?我们依然从层级上来讲,首先给大家说说同层级怎么进行排序,下面看个例子:

假设,有这么一个需求:要求统计所有请求日志中请求耗时最高的api,怎么做呢?

其实很简单,我们只需要将排序的字段存在聚合的内容按照指定的字段进行排序即可,来看具体操作

GET req_log/_search
{
"aggs": {
 "req_total": {
   "terms": {
     "field": "path",
     "order": {
       "total_times": "desc"
     }
   },
   "aggs": {
     "total_times": {
       "sum": {
         "field": "times"
       }
     }
   }
 }
}
}

结果:

....
 "aggregations" : {
    "req_total" : {
      "doc_count_error_upper_bound" : 0,
      "sum_other_doc_count" : 0,
      "buckets" : [
        {
          "key" : "/api/post/8",
          "doc_count" : 1,
          "total_times" : {
            "value" : 9000.0
          }
        },
        {
          "key" : "/api/post/6",
          "doc_count" : 3,
          "total_times" : {
            "value" : 3160.0
          }
        },
        {
          "key" : "/api/post/7",
          "doc_count" : 1,
          "total_times" : {
            "value" : 870.0
          }
        },
        {
          "key" : "/api/post/12",
          "doc_count" : 1,
          "total_times" : {
            "value" : 630.0
          }
        },
        {
          "key" : "/api/post/4",
          "doc_count" : 2,
          "total_times" : {
            "value" : 610.0
          }
        },
        {
          "key" : "/api/post/2",
          "doc_count" : 2,
          "total_times" : {
            "value" : 410.0
          }
        },
        {
          "key" : "/api/post/10",
          "doc_count" : 1,
          "total_times" : {
            "value" : 270.0
          }
        },
        {
          "key" : "/api/post/1",
          "doc_count" : 2,
          "total_times" : {
            "value" : 230.0
          }
        },
        {
          "key" : "/api/post/3",
          "doc_count" : 3,
          "total_times" : {
            "value" : 189.0
          }
        },
        {
          "key" : "/api/post/20",
          "doc_count" : 1,
          "total_times" : {
            "value" : 120.0
          }
        }
      ]
    }
  }

深层级自定义排序

接下来难度加深,假设有这么一个需求:

统计每天请求中为GET请求,并且按照请求耗时倒序排序,找出每天请求耗时最高的api

需求很短,但理解起来有不少关键点:

  • 需要统计每天的结果
  • 请求为GET
  • 结果按照请求耗时倒序排序

这个怎么做呢?一起来看一下。先添加点数据,以便更好的理解这个例子:

POST req_log/_bulk
{ "index": {}}
{ "times" : 180, "method" : "GET", "path" : "/api/post/1", "created" : "2023-02-09" }
{ "index": {}}
{ "times" : 120, "method" : "GET", "path" : "/api/post/3", "created" : "2023-02-09" }
{ "index": {}}
{ "times" : 140, "method" : "GET", "path" : "/api/post/2", "created" : "2023-02-09" }
{ "index": {}}
{ "times" : 130, "method" : "GET", "path" : "/api/post/20", "created" : "2023-02-09" }
{ "index": {}}
{ "times" : 60, "method" : "GET", "path" : "/api/post/9", "created" : "2023-02-09" }

下面我们就按照需求,把结果统计出来:

GET req_log/_search
{
"aggs": {
 "date": {
   "date_histogram": {
     "field": "created",
     "calendar_interval": "1d",
     "format": "yyyy-MM-dd"
   }, 
   "aggs": {
     "req_path": {
       "terms": {
         "field": "path",
         "order": {
           "req_method>total_times": "desc"
         }
       },
       "aggs": {
         "req_method": {
           "filter": {
             "terms": {
               "method": [
                 "GET"
               ]
             }
           },
           "aggs": {
             "total_times": {
               "sum": {
                 "field": "times"
               }
             }
           }
         }
       }
     }
   }
 }
}
}

结果返回:

.... 此处省略
"aggregations" : {
    "date" : {
      "buckets" : [
        {
          "key_as_string" : "2023-02-01",
          "key" : 1675209600000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/6",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 1300.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-02",
          "key" : 1675296000000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/8",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 9000.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-03",
          "key" : 1675382400000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/6",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 960.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-04",
          "key" : 1675468800000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/3",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 80.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-05",
          "key" : 1675555200000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/1",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 150.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-06",
          "key" : 1675641600000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/20",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 120.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-07",
          "key" : 1675728000000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/2",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 30.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-08",
          "key" : 1675814400000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/3",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 20.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-09",
          "key" : 1675900800000,
          "doc_count" : 6,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/1",
                "doc_count" : 2,
                "req_method" : {
                  "doc_count" : 2,
                  "total_times" : {
                    "value" : 260.0
                  }
                }
              },
              {
                "key" : "/api/post/2",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 140.0
                  }
                }
              },
              {
                "key" : "/api/post/20",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 130.0
                  }
                }
              },
              {
                "key" : "/api/post/3",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 120.0
                  }
                }
              },
              {
                "key" : "/api/post/9",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 60.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-10",
          "key" : 1675987200000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/4",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 400.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-11",
          "key" : 1676073600000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/3",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 89.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-12",
          "key" : 1676160000000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/2",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 380.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-13",
          "key" : 1676246400000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/10",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 270.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-14",
          "key" : 1676332800000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/12",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 630.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-15",
          "key" : 1676419200000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/4",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 210.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-16",
          "key" : 1676505600000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/6",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 900.0
                  }
                }
              }
            ]
          }
        },
        {
          "key_as_string" : "2023-02-17",
          "key" : 1676592000000,
          "doc_count" : 1,
          "req_path" : {
            "doc_count_error_upper_bound" : 0,
            "sum_other_doc_count" : 0,
            "buckets" : [
              {
                "key" : "/api/post/7",
                "doc_count" : 1,
                "req_method" : {
                  "doc_count" : 1,
                  "total_times" : {
                    "value" : 870.0
                  }
                }
              }
            ]
          }
        }
      ]
    }
  }

从结果来看,可以看出是按照日期每天进行统计的,除了9号其它的数据都是一条,所以我们之前插了一些9号的数据,我们重点看9号的数据,里边的数据是按照请求耗时倒序排序的。

查询语句看似复杂,其实拆解开很简单,其实就是将上节讲的深层聚合,加个排序,如果还不熟悉的小伙伴,建议上节温习一下。说一下几个关键词:

  • date_histogram, 日期表达式,允许我们聚合以时间为单位, 所以calendar_interval就是时间单位,支持分,时,天,周,月,季度,年
"date_histogram": {
   "field": "created",
   "calendar_interval": "1d",
   "format": "yyyy-MM-dd"
}, 

  • req_method>total_times 这个>大家可以简单理解为类似css选择器的>,我们可以通过它将结果进行链接

size结合使用

假设,需求又变动了,嫌数据太多,我只想看到想要的数据,在原有的基础上,返回每天请求耗时最多的前两条数据,怎么做? 这是一个比较常见的需求

我们可以通过指定size,这个其实前几节都给大家讲过,下面一起看下吧~

GET req_log/_search
{
"aggs": {
 "date": {
   "date_histogram": {
     "field": "created",
     "calendar_interval": "1d",
     "format": "yyyy-MM-dd"
   }, 
   "aggs": {
     "req_path": {
       "terms": {
         "field": "path",
         "order": {
           "req_method>total_times": "desc"
         },
         "size": 2
       },
       "aggs": {
         "req_method": {
           "filter": {
             "terms": {
               "method": [
                 "GET"
               ]
             }
           },
           "aggs": {
             "total_times": {
               "sum": {
                 "field": "times"
               }
             }
           }
         }
       }
     }
   }
 }
}
}

返回:

...省略
{
    "key_as_string" : "2023-02-09",
    "key" : 1675900800000,
    "doc_count" : 6,
    "req_path" : {
    "doc_count_error_upper_bound" : 0,
    "sum_other_doc_count" : 3,
    "buckets" : [
        {
        "key" : "/api/post/1",
        "doc_count" : 2,
        "req_method" : {
            "doc_count" : 2,
            "total_times" : {
            "value" : 260.0
            }
        }
        },
        {
        "key" : "/api/post/2",
        "doc_count" : 1,
        "req_method" : {
            "doc_count" : 1,
            "total_times" : {
            "value" : 140.0
            }
        }
        }
    ]
    }
}
...省略

可以看出9号的数据只返回了两条,是不是很简单~

去重

es中如何进行去重呢? 下面一起看下

cardinality & 去重统计

es聚合中使用cardinality来做去重操作,去重结果可能并不是很准确,但是可以保证极小的内存消耗和极高的响应效率

下面看个例子:

GET req_log/_search
{
"aggs": {
 "path_num": {
   "cardinality": {
     "field": "path",
     "precision_threshold": 100
   }
 }
}
}

结果返回:

 "aggregations" : {
    "path_num" : {
      "value" : 11
    }
  }

从结果得出,一共存在11个api

  • precision_threshold 代表的是精度,接受的范围是0–40,000

percentiles & 百分比统计

有时候,我们需要统计百分比,那么在es中如何进行操作呢? 可以使用latency_percentiles来进行统计,来看个例子

GET req_log/_search
{
  "aggs": {
    "latency_percentiles": {
      "percentiles": {
        "field": "times",
        "percents": [
          30,
          40,
          50,
          60,
          70,
          80,
          99
        ]
      }
    }
  }
}

结果:

"aggregations" : {
    "latency_percentiles" : {
      "values" : {
        "30.0" : 120.0,
        "40.0" : 133.0,
        "50.0" : 165.0,
        "60.0" : 251.99999999999994,
        "70.0" : 398.0,
        "80.0" : 873.0,
        "99.0" : 9000.0
      }
    }
  }

大家第一眼看到这个结果可能有点懵,我们看到结果返回了我们之前指定的百分比percents里边就是指定百分比的,意思大概这样:

  • 在所有请求中有30%的请求耗时达到了120

其它以此类推,有时候老板让我们统计在所有订单中,愿意付费的用户大概是多少,在付费用户中,付款金额的指标是多少,是不是就会统计了~

percentile_ranks & 百分比统计(反向)

为什么说是反向呢?假设,有这么一个需求,我想统计请求耗时达到80, 120,600的请求大概占比多少?这也是一个很常见的反向需求,就像平时老板问你,购买黄金vip,白银vip,铂金vip的用户占比多少。

接着看刚刚的需求:

GET req_log/_search
{
  "aggs": {
    "load": {
      "percentile_ranks": {
        "field": "times",
        "values": [
          80,
          120,
          600
        ]
      }
    }
  }
}

 返回:

...
"aggregations" : {
    "load" : {
      "values" : {
        "80.0" : 18.181818181818183,
        "120.0" : 31.818181818181817,
        "600.0" : 74.37137330754351
      }
    }
  }
....

从结果来看,请求耗时达到80的占比18%其它依次类推,对比刚刚的percentiles是不是它的百分比在后边,为了方便理解,所以叫反向

结束语

本节到此就结束了,大家一定要学会举一反三,可以给自己出一些常见的场景需求,结合前面学的内容巩固一下,不用去背查询语句,理解了就可以。

下节我们就正式进入SpringBoot框架整合ES的相关内容~

本着把自己知道的都告诉大家,如果本文对您有所帮助,点赞+关注鼓励一下呗~

相关文章

项目源码(源码已更新 欢迎star⭐️)

往期并发编程内容推荐

博客(阅读体验较佳)

推荐 SpringBoot & SpringCloud (源码已更新 欢迎star⭐️)






相关实践学习
以电商场景为例搭建AI语义搜索应用
本实验旨在通过阿里云Elasticsearch结合阿里云搜索开发工作台AI模型服务,构建一个高效、精准的语义搜索系统,模拟电商场景,深入理解AI搜索技术原理并掌握其实现过程。
ElasticSearch 最新快速入门教程
本课程由千锋教育提供。全文搜索的需求非常大。而开源的解决办法Elasricsearch(Elastic)就是一个非常好的工具。目前是全文搜索引擎的首选。本系列教程由浅入深讲解了在CentOS7系统下如何搭建ElasticSearch,如何使用Kibana实现各种方式的搜索并详细分析了搜索的原理,最后讲解了在Java应用中如何集成ElasticSearch并实现搜索。  
相关文章
|
中间件 API PHP
Laravel 日志、调试、输出、授权等技巧总结
我们可以使用 Log::info(),或使用更短的 info() 额外参数信息,来了解更多发生的事情
866 0
|
SQL JSON 关系型数据库
Flink CDC实践(二)
Flink CDC实践(二)
|
NoSQL MongoDB
mongoTemplate批量保存数据mongoDB批量保存数据
mongoTemplate批量保存数据mongoDB批量保存数据
626 2
|
Arthas 监控 Java
|
11月前
|
SQL NoSQL Java
Java使用sql查询mongodb
通过MongoDB Atlas Data Lake或Apache Drill,可以在Java中使用SQL语法查询MongoDB数据。这两种方法都需要适当的配置和依赖库的支持。希望本文提供的示例和说明能够帮助开发者实现这一目标。
456 17
|
前端开发 JavaScript Java
如何使用JSR 303 进行后台数据校验?
这篇文章详细介绍了如何使用JSR 303进行后端数据校验,包括JSR 303的基本概念、使用原因、常见操作,以及如何通过注解进行数据校验、分组校验和自定义校验注解的方法和实际应用示例。
如何使用JSR 303 进行后台数据校验?
|
Ubuntu Java
蓝易云 - ubuntu22安装和部署Kettle8.2
现在你应该可以看到Kettle的图形界面了。这就完成了Ubuntu 22上Kettle 8.2的安装和部署。
377 1
|
弹性计算 安全 Ubuntu
新手3分钟1Panel安装教程,使用阿里云服务器CentOS操作系统
在阿里云CentOS 7.9服务器上安装1Panel面板,包括远程连接ECS、执行安装命令、设置安装目录(默认/opt)、开启20410端口、配置安全入口和用户密码。记得在阿里云安全组中开放20410端口以访问面板。
1323 0
新手3分钟1Panel安装教程,使用阿里云服务器CentOS操作系统
|
监控 关系型数据库 数据库
PostgreSQL和greenplum的copy命令如何使用?
【6月更文挑战第5天】PostgreSQL和greenplum的copy命令如何使用?
561 2
|
消息中间件 Java Kafka
Flink背压问题之checkpoint超时如何解决
Apache Flink是由Apache软件基金会开发的开源流处理框架,其核心是用Java和Scala编写的分布式流数据流引擎。本合集提供有关Apache Flink相关技术、使用技巧和最佳实践的资源。

热门文章

最新文章