首页> 标签> MySQL
"MySQL"
共 46642 条结果
全部 问答 文章 公开课 课程 电子书 技术圈 体验
程序与数据库连接工具与案例代码
前言提示:在这里先说下 DBUtil.java 文件:JDBC能完成三件事:同一个数据库建立连接向数据库发送SQL语句处理数据库返回结果它是一种用于执行SQL语句的Java API,为多种关系数据库提供统一访问,由一组用Java语言编写的类和接口组成提示:以下是本篇文章正文内容,下面案例可供参考JDBC访问数据库流程JDBC访问数据库的步骤1、开始JDBC操作前要将驱动放到WEB-INF的lib目录下2、程序中首先导包import java.sql.*3、执行查询操作①、加载正确的数据库驱动程序Class.forName("oracle.JDBC.driver.OracleDriver"); //使用Oracle的JDBC驱动程序 Class.forName("com.microsoft.JDBC.sqlserver.SQLServerDriver"); //使用SQL Server的JDBC驱动程序 Class.forName("com.ibm.db2.JDBC.app.DB2Driver"); //使用DB2的JDBC驱动程序 Class.forName("com.mysql.JDBC.Driver"); //使用MySql的JDBC驱动程序 关于使用使用MySql的JDBC驱动程序,如果连不上可以试试下面这个驱动在 mysql和 jdbc中间加个【.cj】driver="com.mysql.cj.jdbc.Driver";②、定义所要连接数据库的地址此处 dbname为数据库的名字String url = "jdbc:mysql://localhost:3306/dbname";③、建立与数据库的连接Connection con=DriverManager.getConnection(url,"root", "root");Connection接口连接MySQL数据库:Connection con =DriverManager.getConnection("jdbc:mysql://host:port/database","user","password");Connection接口连接ORACLE数据库:Connection con = DriverManager.getConnection("jdbc:oracle:thin:@host:port:databse","user","password");④、创建语句对象String sql="select * from food where material like ?" PreparedStatement pstmt=conn.prepareStatement(sql); //带?的SQL语句一定要在执行之前给?赋值,char和varchar都是setString替换?, //对于int型数据可以使用setInt替换? pstmt.setString(1, "%鸡蛋%");//参数1表示第一个?⑤、声明SQL语句将该语句通过Statement对象提交给服务器进行执行ResultSet rs=ps.executeQuery(); //注意,此时executeQuery()不带参数⑥、对查询结果进行分析while(rs.next()){ String name =rs.getString("columName");//根据列名获取字段值 String phone =rs.getString(2);//根据列号获取字段值,从1开始数列号 System.out.println(name+","+phone); }⑦、关闭打开的资源(按定义的逆序关闭)rs.close(); pstmt.close(); con.close();JDBC的优缺点JDBC API 用于连接 Java 应用程序与各种关系数据库。这使得人们在建立客户/服务器应用程序时,通常把 Java 作为编程语言,把任何一种浏览器作为应用程序的友好界面,把 Internet 或Intranet 作为网络主干,把有关的数据库作为数据库后端。使用JDBC具有以下优点:(1)、JDBC API 有利于用户理解。(2)、JDBC 使得编程人员从复杂的驱动器调用命令和函数中解脱出来,可以致力于应用程序中的关键地方。(3)、JDBC 支持不同的关系数据库,使得程序的可移植性大大加强。(4)、JDBC API 是面向对象的,可以让用户把常用的方法封装为一个类以备后用。使用JDBC具有如下缺点:(1)、使用 JDBC访问数据记录的速度会受到一定程度的影响。(2)、JDBC 结构中包含了不同厂商的产品,这就给更改数据源带来了一定的麻烦。DBUtil.java代码及注解JavaWeb项目package dao; import java.sql.DriverManager; import java.sql.ResultSet; import com.mysql.jdbc.Connection; import com.mysql.jdbc.PreparedStatement; public class DBUtil { private static java.sql.Connection con = null;// 连接对象 private static PreparedStatement pstmt = null;// 语句对象 private static ResultSet rs = null; // 结果集对象 //连接数据库 public static Connection getCon(){ //定义所要连接数据库的地址 String url = "jdbc:mysql://localhost:3306/00eshop?useUnicode=true&characterEncoding=UTF-8"; String user = "root"; //数据库用户名 String password = "123456"; //数据库密码 try { //加载正确的数据库驱动程序 Class.forName("com.mysql.jdbc.Driver"); //建立与数据库连接 con = DriverManager.getConnection(url, user, password); //System.out.println("--------------"); 出现横线,代表数据库连接上了 return (Connection) con; } catch (Exception e) { System.out.println(e); return null; } } //关闭数据库,(避免资源浪费,或者其他数据库来访问) public static void close(ResultSet rs,PreparedStatement ps,Connection con){ if (rs != null) { try { rs.close(); } catch (Exception e) { System.out.println(e); } } if (ps != null) { try { ps.close(); } catch (Exception e) { System.out.println(e); } } if (con != null) { try { con.close(); //关闭打开的资源 } catch (Exception e) { System.out.println(e); } } } }注解:Connection 是个接口,这个 Connection 连接成立后才能把SQL语句往这里面传,先跟数据库建立一个良好的联系在DBUtil.java类中定义 getCon() 方法创建数据库链接(第16行)具体说第18 行是什么意思:【String url = "jdbc:mysql://localhost:3306/00eshop?useUnicode=true&characterEncoding=UTF-8 ";】jdbc:是连接数据库的一种形式mysql:数据库的类型是mysqllocalhost:本地地址,也可以换成:【127.0.0.1】3306:端口号(默认数据库端口,最好不要改)这个在Navicat 或 VS Code中可以看到:/ 后面的【00eshop】:是数据库名称? 后的【useUnicode=true&characterEncoding=UTF-8】 :这些是针对不同的 MySql 版本进行传值数据库本地地址和远程地址此报错以一个SSM项目为例:远程地址:例如MySQL 连接远程数据库(192.168.5.542)本地地址:localhost案例:我曾经运行过一个项目,但是他一直在跑,浏览器一直转圈,Tomcat日志中说连接超时一开始我以为是环境配置问题,于是各种检查,重新配置最后发现是因为用了远程的数据库链接地址与本地数据库导致的最后在配置数据库的位置把远程地址改成 localhost本地地址就好了//SpringBoot jdbc.driver=com.mysql.cj.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/hotel?characterEncoding=utf8&useUnicode=true&useSSL=false&serverTimezone=GMT%2B8 jdbc.username=root jdbc.password=123456 //SSM <!-- 配置数据源 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver"/> <property name="url" value="jdbc:mysql://localhost:3306/db_ebook?useUnicode=true&characterEncoding=UTF-8"/> <property name="username" value="root"/> <property name="password" value="123456"/> </bean>
文章
SQL  ·  Oracle  ·  Java  ·  关系型数据库  ·  MySQL  ·  数据库连接  ·  应用服务中间件  ·  API  ·  数据库  ·  C++
2023-02-04
MySQL命令行导入数据库
前言提示:文中记载详细步骤,最后总结中有记录语句:VS Code听说不要钱,用了后却不知道怎么导入导出了下面操作过程,默认mysql是启动状态默认是开机时就自动运行了【win+r】输入【services.msc】进入服务后,在里面找到名称为 mysql 的项,双击就可看它的服务状态是启动还是停止,把它设为启动提示:以下是本篇文章正文内容,下面案例可供参考使用命令行导入第一步:进入MySQL的bin目录下第一种【win+r】输入【cmd】回车进入到MySQL安装目录下的 bin 文件下第二种但是我这个人比较懒,我喜欢直接找到 mysql 安装的位置,打开 bin 文件夹点一下上面这个地址输入【cmd】【地址一定要对,打开后不是就 cd 切换地址】再输入:mysql -hlocalhost -uroot -p123456或者输入【mysql -u root -p】之后,再输入密码也是可以的!第二步:新建数据库并使用【create database Demo;】新建一个数据库:Demo使用数据库【use Demo;】使用该数据库;第三步:选中导入路径下面两种办法二选一,推荐第一种推荐:【source E:\Demo.sql】选中导入路径 没有分号有时候不稳定如果是向左的斜线 有没有分号都可查看表是否存在【show Tables;】查看所有表打开VS Code打开 vs code 后刷新一下现在可以看到已经导进来了注意在输入选中导入路径语句:【source E:\Demo.sql】时,一定要注意:第一:路径中不可以有中文,并且后面没有分号第二:这个 sql 文件最好直接就在C盘或者其他盘下,最好不要放在文件夹里,因为有时候会导不进去就是你把这个sql文件直接拖到你要放的盘符下就好总结命令行操作导入方法1:mysql>source D:\dbname.sql方法2:mysql -u root -p 数据库名 < dbname.sql图形界面操作Navicat导入:运行SQL文件导出:转储SQL文件
文章
SQL  ·  关系型数据库  ·  MySQL  ·  数据库  ·  数据安全/隐私保护  ·  C++
2023-02-04
IDEA显示代码向前和向后跳转的箭头工具按钮 先看效果:
IDEA显示代码向前和向后跳转的箭头工具按钮先看效果:再看设置方法:依次点击View→Toolbar调出工具栏查看代码历史版本这个就是当你把代码突然间搞得乱七八糟的时候,还可以挽回 restore一下只需要选中文件右键选择Local History→Show History,点开即可看到历史版本,常用于自己忘记代码改了哪些内容或需要恢复至某个版本 (注意:只能看近期修改的,太久了也是看不到的)IDEA设置成Eclipse的快捷键这对 Eclipse 转 IDEA 的开发人员来说非常友好,这样不需要记两套快捷键在Settings里面选择Keymap,点击下拉框选择 EclipseSpringBoot工程热部署我们在开发中反复修改类、页面等资源,每次修改后都是需要重新启动才生效,这样每次启动都很麻烦,浪费了大量的时间,我们可以在修改代码后不重启就能生效,在 pom.xml 中添加如下配置就可以实现这样的功能,我们称之为热部署。SpringBoot工程热部署取消匹配大小写取消勾选后,输入小写 s ,也能提示出 String查看方法在哪里被调用【ctrl+alt+h】 可以清楚看到方法在哪些地方被调用优化导包配置File→Settings→Editor→General→Auto Import手动导包:【alt+enter】手动移除未使用包:【crtl+alt+o】显示行号和方法分割线File→Settings→Editor→General→AppearanceIDEA的类注释和方法注释创建文件时,自动生成作者和时间信息在我提供的模板中最重要的写了作者和时间等信息,当几个人一起写项目的时候方便知道是谁写得类注释:第一种:File→Settings→Editor→File and Code Templates→Files当然可以不止选择Class、Interface、Enum也可以选择其他的,下面是代码/** * @programName: ${PACKAGE_NAME} * @ClassName:${NAME} * @Description TODO * @Author: ${USER} * @Create: ${DATE} ${TIME} **/ 这里根据自己的需求添加,配置好之后,再新建类时便会自动生成注释,效果如下:第二种:1、File→Settings→Editor→Live Templates没有组的话就新创建一个组Template Group,我是随便起的名要是以前创建过的话也可以加到以前的组然后选择刚创建的分组,然后创建Live Template填写 live Template的缩写名字、描述和内容,注意内容的开头没有 / ,如下* * @programName: ${PACKAGE_NAME} * @ClassName:${NAME} * @Description TODO * @Author: ${USER} * @Create: ${DATE} ${TIME} **/ 方法注释:这里是以快捷键的形式为大家讲解和类注释的第二种方法类似,这里不再详细每一步,只列出关键步骤,方法如下代码如下:/* * @Description: $description$ * @Param: $params$ * @return: $returns$ * @Author: $USER$ * @Date: $DATE$ $TIME$ */ 最后选择Edit variables,在方框里面 √配置完成以后,我以后在方法上面输入 rej + Enter键, 便自动生成注释然后就可以在里面加东西了效果图如下:IDEA内显示图形化页面这个是idea里面比较好的小功能:显示图形化页面其实也是IDEA连接MySQL数据库选择右侧【Database】如果右侧没有的话:就选择 View →Tool Windows→ Database,之后左侧就弹出了选择右侧【Database】→【+】→【Data Source】→【MySQL】输入你的用户名、密码、数据库名字我的页面下方有个【Download】,那我就选择下载,然后点击【Apply】【ok】最后显示:
文章
关系型数据库  ·  MySQL  ·  Java  ·  数据库  ·  Android开发  ·  数据安全/隐私保护  ·  Windows
2023-02-04
Prometheus 进阶|学习笔记(二)
开发者学堂课程【3天吃透 Prometheus:Prometheus 进阶】学习笔记,与课程紧密联系,让用户快速学习知识。课程地址:https://developer.aliyun.com/learning/course/1244/detail/184545. Histogram quantile 的函数这个函数允许自己我们指一个分位数,这个分位数就是位于0到1之间的,比如定义刚才所说0.5,即表示50分位数,这整个区间内的50分位是谁?跟上这个basename,就是我们自己指定的标签名,加上bucket,它就能通过函数粗略的估算出我们的所有采样当中大概正好中位数名的数是谁。我第一次的描述可能不是特别精确,我再重复一遍。正常情况下,我们所谓的取中位数指的就是在你的整个样本取值中间我们虽然认为我们的取值是0-100,但我们同学不可能正好0分分布到0分到100分之间,很有可能你是30分到99分之间。我想知道30分到99分之间正好中间中位数是谁?他要根据你的范围来做计算,但这种计算只能是一种线性计算,因为我们没有存真正的样本数都是多少,这种计算一定会有偏差。现在大家应该容易理解。很有可能他是这样算的,举个例子,你比如小于等于我现在让你取50分的,现在在60分上的同学有几个?比如同学有几个,落在小于45的有几个,那就意味着45-60之间我们是不是可以算他一个大约数?根据这几个数字我们评估,比如我现在这个范围内有三个同学,而45-60之间一共有15个数字,于是我就取一个最中间数,认为这是他的,就正常计算把3个均匀的分布到这个范围内,差不多最中间数如果是4个,也只能是按照4个,把这4个均匀的分布到这个范围上,找一个中间数,再不然找中间那俩值再做个平均,什么类似这种方式来进行估算。所以它一定得到的不是精确值,只能是估算它的结果。但如果我们要非要得到精确结果怎么办?没办法,histogram这种直方图本身就不支持,因为它本身就是一种线性推算出来,这种偏差一定是存在的。这个图它大体上就描述这种偏差。正常红线表示正常的样本分布应该具有的样子,因为这是正态分布,差不多正常情况下,这种统计都是满足正态分布的。但是蓝线大概表示出来。比如这是分位点,这是1/4分位点,这是四分位点,这是中位数,3/4分位点,这是百分位点。很显然,它估算时,类似于以这种区间的方式来估算,我们的估算值应该是落在直线上,很有可能落在直线上,或者是落在蓝色的画的不规则线上,跟我的红线一定是有偏离,再重复一遍,因为它是个估算,它不是真实的样本值。你的样本值没有被记录。我们要想得到精确样本值怎么办?只有一个办法。我们使用另外一个,叫做summary的类型,因为summary是客户端,直接算好分位数,直接上报服务端直接记,不用计算,因为我已经记好,这几个分位数分别是什么?比如在我们的采样区间内,50分位数是几?75分位数是几?但你想再算60分位数怎么办?对不起,我上报的只有25分位数、50分位数、75分位数和百分位数。没有别的,你就用不到。所以summer的好处是能得到固定分位点上的精确值,但不能去任意估算。这是summer的特点。因为我们说过summer是报什么值的,报什么数的,直接指明我这个分位点。每一个桶里边,你可以认为它不是桶。时间序列记录了每一个分位点上对应的样本,到底是什么?比较常见的是summary直接上报零、零点二五、零点七、五和一几个分位点。我们说过这叫中位数1/4分位数,这是四分三分位数,百分位数也有这样几个点的,比如我想知道百分之50%以下的,或者为0.5以下的,0.9以下的,0.99以下的这几个分位点,什么意思?分位数代表你的采样值有50%大概是什么样?有90%大概是什么样?99%大概什么样?什么意思?仍然以刚才我们同学的例子为例来进行说明。假设我们某一次采样的结果当中,在这某采样的结果当中,我们认为60分位数,或者我们有一个叫做中位数是75,我们认为什么意思?班里边同学有一半小于75,少考的分数是低于75,另外一半是多于75,同样,我们认为叫99分位数99%是70。可以用什么?班里边的同学,99%的同学都低于70分,只有1%的同学是高于70分,这叫统计分布。6.统计分布在监控中的作用我们在监控中有什么作用?很简单,比如我们现在记录的是什么?是我们的HTTP服务器,注意抓的指标是HTTP服务器的请求响应时长,叫response_time_seconds。随便举个例子,就这样一个指标叫http的起响应时长,以秒为计算,开始给它记分位数,想知道我们的网站大概请求时长多少?你要在这用gage来记录会有什么结果?用Gage来记录,那就意思每一次采样它都记下一个所谓的响应时长,这叫Gage。因为我知道响应时长它不可能是个计数器,不同请求,他们的数据可大可小。所以我们要使用gage计数有什么特点?想知道平均时长,我们到底请求响应时长大概位于什么样的区间,有什么样特性。于是我们记录下所有的请求,或者叫我们记录下每一个采样点的请求的具体的响应时长。到最后,我评估一下大家大体上请求时长都有多少于是我取平均数,比如平均数为1.3秒。但是我们说过平均值是会坑人。可能有50%的请求大概都在1.2秒,但是也有个别请求,可能请响应结果为10秒钟。它无法精确地反映出来我们的真正网站的节目响应情况,因此,我们如果把它使用histogram来进行技术会有什么特点?我也可以查出来说99%的请求大概它的时长在是什么?比如我们求取了一个99分位数为1.1,你可以理解什么意思?99%的请求响应时长都不超过1.1秒,我认为网站是正常,1%的异常我们认为是可以接受的。但你使用平均数,你无法知道它到底百分之几有多少。平均值是1.3,但很有可能有很多请求是0.001秒钟完成,但只有50%,大概就在0.001秒之内就能完成。而另外50%很有可能是在5或者在10秒以上完成的,你说平均1.3,你认为这合理吗?你的网站服务,正常吗?这不是一个大坑吗?所以我们说很多时候平均数是无法精确描述我们的真正某一个测量度的特征的,这就是为什么我们要使用分位数的原因,其实对我们将来在我们的网站的应用的监控的响应时长这方面用的最多,基本上分位数都是用在这个位置的,包括比如你在磁盘存数据,多长时间能存完磁盘,请求响应时长,网站请求响应时长等,这些其实都是重要的指标,数据应用监控当中,响应时间是一个特别关键的指标,这也是为什么我这里又利用那么多时间来给大家再次讲解概念的原因,相关知识一定要理解清楚。当然要想使用好分位数确实不是件容易的事。我们回头继续说promql,我们前面已经讲到promql的基础的表达式。 二、prometheus 的聚合函数聚合计算,我们讲过大多数指标我们采集后,不用也不可能去一个一个查看它的样本值,这对我们而言不关键,更重要的是,假如我们的web服务器跑20个实例,因为我们现在网站访问量很大,跑20个实例,这些实例上统计的响应时长也不可能主节点每一个节点的查看。所以多数情况下很有可能会把多个target上的同一个指标合并起来统一进行计算,比如求解它的平均值之类的来进行,所以我们说一般来讲,单个指标的价值不大,监控场景中往往需要联合并可视化一组指标这概念,这一组指标很有可能是来自于不同target的同一指标。也有可能是位于某一个对应的指标名称下的多个维度,我可以给它聚合起来进行计算,这种联合机制所谓叫聚合操作。比如像计数、求和平均值、分位数、标准差及方差等统计函数,把这些函数应用于时间序列的样本之上,我们让它生成具有统计学意义的结果,所以我们对于做监控的同学来说,了解统计学知识有时候还是很有必要的,当然也不一定非要去懂,回顾中学的什么叫标准差,什么叫方差也可以,接着我们也可以对查询结果事先按照某种分类机制进行分组,叫groupby。各位在学MySQL的时候应该学过,我们班里边所有同学,你可以求平均,比如这某一次考试,求所有同学的平均得分,也可以干什么?我们班里边一共分4组,求每一个组的平均得分,这就是分组统计,或者是每一个组各自的有多少个同学等。这种就叫分组统计,分组其中包括分组统计数、分组求平均值、分组求和等,这个叫计数,可能更合适一点。聚合操作其实就是由prometheus内置的聚合函数来进行计算。它可以针对一组值进行计算并返回注意单个值或少量几个值。既然叫聚合,不能越聚越多,它其实是一种折叠的效果,它应该起到一种叫做折叠的效果。我们要减少数量的prometheus内置提供了11个聚合函数,我们也可以把它称为叫做聚合运算符,但是各位要记得的是,这有个特别要点,重要的要点,这些运算符仅支持应用于单个即时向量的元素。意思是这些计算的函数是不支持用在范围向量之上,其返回值也是具有少量元素的新向量,甚至是只有一个元素的,只有一个元素不一定叫标量,因为它可能得到的结果刚好有只有一个元素,但有些值是标量,因为它本身不具有向量的意义,它称为叫标量。这些聚合运算符既可以基于向量表达式返回结果中的时间序列的所有标签维度进行分组聚合,也可以仅基于指定标签维度的分组。再分组聚合。什么意思?比如这里有个是序列,有指标名,它有三个标签。我可以只针对标签1做聚合,也可以针对标签1标签2做分组聚合。也可以把所有的标签拿过来做分组聚合。所有标签都拿过就意味着只有这一个值,这一个序列自己能聚合。话回来即多个target上这个序列可能就不止一个,这是prometheus的聚合函数。我们来学习这些聚合函数都是什么以及它该怎么用。1.聚合表达式promql中的聚合操作语法是以下两种格式,其中任何一个都行。我们来看怎么用,第一,使用聚合,聚合函数或者叫聚合操作符<aggr-op>([parameter,]<vector expression>)[without│by(label list>)], 我们要使用的聚合函数比如叫avg,你要使用的是avg,这表示我要在这写avg,这叫向量表达式,就表示你要打算对哪个向量表达式。我们要知道过滤就和我们前面所说的时间序列过滤器,针对过滤器本身做聚合,怎么聚?可以整个聚合,也可以指定的标签聚合。其中without叫排除法,意思是要把指标排完后,排除以后把剩下的指标为标准进行聚合。也可以使用by,这表示什么?包含法就以我指定的指标进行聚合,反过来的不聚合。 下面这种表达格式跟上面一样:<aggr-op>[without│by(label list>)] ([parameter,]<vector expression>),只是下面把without写前面。意思without和by既可以直接写在聚合函数后面,也可以写在小括号括起来的聚合表达式的后面。这就所谓的聚合操作的基本的语法格式。我们聚合时可以先分组后聚合,叫分组聚合。所以without和by分组与否的特别重要标准,它俩不能同时使用。因without表示排除法,表示把某些标签排除以后把剩下的标签用来做聚合。而by表示以仅以指定的标签做聚合。事实上,每一个函数只有功能上的区别,在表达格式上,在使用的语法格式上没有区别。我们举个例子就知道。我把我的prometheus再次启动,user/local/Prometheus,我们让它运行。 现在我们去打开站点,我们打开表达式浏览器,看里边有哪些指标可以被我们使用。当然更重要的是,我们要想聚合,要看怎么聚合。要求和我们说过,一般要用在gauge类型的指标上还记得求平均值也应该是gauge类型的指标,一定要记得聚合函数只能用于及时向量而且还不能用于范围向量,因而我们在这里可用指标。这是一个9090,大家知道这是prometheuse自己的指标。9090是prometheus进程自己的监听的端口,我们也可以使用9100,这是node的端口,1.1上好像没启用,我看意义上应该node exporter所输入的指标。我们找一个Gauge类型的指标而后就可以对它做聚合。这是最容易理解的,还回到9090里。我们就直接搜索,在查找一个gauge,这里它的标签太少,我们要找两个以上标签的。各位看 Node file system available bytes,叫节点文件系统的可用空间,以字节为单位,filesystems space available to non-root userBytes,底下定义这是sdae。设备sdae文件系统是什么?挂载点是什么?大概还剩这么多空间,这是第二个,这是第三个。能看懂这意思,所以我们就查这个指标叫Node file system available bytes。复制后我在这里先把它过滤出,我们看它的所有指标。 各位注意这里的区别,首先,这有节点123各自每一个节点上的统计,所以instance代表的节点,如果我们要只统计单一节点,instance就必须要过滤,我们要以它为分组进行聚合,分别统计每一个节点上的设备,同样的逻辑,如果我们考虑我们计算出来所有节点上的所有空闲文件系统的剩余空间之和是多大?很显然,我所有是不是都可以不过滤?我们就直接使用sum,叫sum求和就可以,后面使用括号括起,我们格式这叫操作符,要使用括号括起来,这里还有个参数。有些聚合函数要求有参数,但SUM不要求。我们既然没有指定任何聚合分组的标准,那意味着事实上这里就表示把所有节点上的所有磁盘设备的空闲空间全部加起就取得一个结果。假如我们要分节点,以节点每一个节点上空闲空间多少,我们就使用by(instance)(Node_filesystem_avail_bytes)就可,sum对它进行求和。把by写前面写后边都可以,by对应的叫做instance标签execute,by (instance),这也需要个括号,这就是所谓的叫node01上的所有的空闲空间之和,这容易理解。很显然,我们要根据别的标准进行聚合。再比如我只看看所有节点上的sdae的空间的大小,很显然我们就基于device进行聚合就可以,就这么简单,看你自己的需要,我们也可以根据挂载点进行聚合,amount每一个挂载点,比如我们这就分每个节点上的根还剩多少空间,每个节点上的boat还剩多少空间就可以,甚至于对其他的挂载点,你像这run,我们不聚合,你可以写得更复杂一点。比如在这我们先去过滤它的mountpoint的值,要么是boot,要么是跟,我们先取出来,只取出来这样对应的指标序列。 对这些指标序列,我再分进行聚合,选sum先聚合就可以。而聚合时,我们还可以对各个挂载点分别进行聚合。意思就是我算所有节点上boot的空间有多大,所有点根的共同性规定多大,即the by-的问题,你by mount point,就根据我们的mountpoint本身进行聚合,也就意味着每一节上的所有的boot剩余空间是这么大,容易理解,只要各位知道这样怎么用,我就不一一去解释每一个函数的意义,就没不用一一去演示,因为它的格式都是一样。当然我一直用的是by,你也可以使用without等,这根据需要,根据自己需要的场景。于是我们来看后续的这些函数都有什么功能,它们分别都是什么。2.11个聚合函数其实大多数都很容易理解,而且各位都应该都使用过。像刚才我一直使用sum求和,avg平均值,count就是计数,这三个应该最容易理解,还有两个更容易理解的最大值和最小值,其他几个我们需要简单解释一下。比如这个叫标准差,标准差是描述数据波动大小的或者称为叫波动程度的,叫做标准差。对样本直求方差,它是求取标准差过程中的一个中间状态,它们的意义比较相近,方差和标准差的统计学的意义比较相近,但他们适用场景会有所区别。接着topk,这是我们做排序的时候用到的最多。比如像刚才我们得到的所谓的过滤出后,我们期望得到空闲空间量最大的磁盘空间是谁,最大的设备是谁,就可以使用topk,还可以分组进行聚合,每一个节点上,它可能有很多个磁盘挂载点。我们取出来空闲空间量最大的各自的前两个,这不就是topk吗?而bottomk则是最小的几个,topk刚刚说过叫由大而小,叫逆序。排完序后取指定的数量,上面是大,下面是小,而bottomk上面是小,下面是大,是顺序排序,依然是求最上面两个,所以我们说topk是取得最大指定的数量,而bottomk是取的最小的指定数量。bottomk和topk到底是返回几个?这两个都是需要指参数parameter,现在就有意义。比如返回前10个,返回前5个,这个数字的意义。下面quantile,叫分位数,用于评估数据的分布状态的,该函数会返回分组内指定的分位数的值,注意这给我们刚才讲的Histoquantile或者叫histogramquantile不同histogramquantile函数只适用于叫histo数据类型,而这适用的是什么?应该是一个gag类型的数据或者是一个counter类型的数据。所以它本来就是样本值。它从各样本值里边找一个中位数,找一个1/4分位数,找3/4分位数。这跟我们刚才讲的histogramquantile是有所不同的。histogramquantile是不用自己的样本值,直接保留的就是桶存储桶和计数,summary直接保存分位数,用不着样本值。而如果我们需要用样本值的时候,你可能使用gage,使用counter计数,但偶尔我们需要在这样的样本值上去求得这整个样本的分布状态。这个时候我们就要使用quantile来定义。所以它是两回事。再重复一遍,这是为什么他俩名字都不一样。后面count_values,这个指的是对分组内的时间序列的样本值进行数量统计,它跟count是有很相像的。但是count_values有它的特殊作用,而且count_values是接受参数的。它跟bottomk跟topk一样,你可以指定我只对内范围内的多少个矩形计数或多大范围进行计数,类似于这种,再重复一遍,count_values是用于在时间序列中的每一个样本值出现的次数进行计数或者精确地讲比如counter,我这里指定一个时间序列,它算出里一共有100个数,100个样本,就一共有100个样本,而count_values指的是它在里边它认为你其中这100个样本里,3出现6次,7出现8次,对每一个样本值进行分别计数,这叫count values,因此count_values会输出很多个时间序列它的返回值,每一个值都是一个时间序列。其他的应该就没有什么特别需要再说明。各位只需要知道比较复杂的函数只有后4个,就是topkey,bottomk,quantile和countvalues。因为它们4个是需要接受参数,前几个一个逆序,一个顺序。这个表示到底是参数,应该是你打算得到哪个分位值。比如五十分位值,九十九分位值,你要指定是哪一个分位值。而count values可以不用给它传参数,但我们要传参数就意味着你要指定哪个样本值,大概就是这样,这是它的聚合函数。
文章
存储  ·  Prometheus  ·  监控  ·  Cloud Native  ·  数据可视化  ·  关系型数据库  ·  MySQL  ·  开发者
2023-02-04
Prometheus 监控系统|学习笔记(三)
开发者学堂课程【3天吃透 Prometheus:Prometheus 监控系统】学习笔记,与课程紧密联系,让用户快速学习知识。课程地址:https://developer.aliyun.com/learning/course/1244/detail/184521.  CPU 使用率我们继续来描述。这个target我们现在能够正常监控了,于是我们就可以过滤节点级的数据了,比如像 nodes 可以看到会多出来很多指标,自动能够进行补全了。其中有一个像 CPU 相关的node CPU seconds.execute,你会发现我们这个主机上一共有四个核心,它们分别被标示为CP0、1、2、3,每一个核心分别有多种不同状态或者多种不同模式下的时间占用,比如空闲的有多少,io wait 的状态有多少,刚才我们可以都看到了,他就能展示到这了。那我们接下来可以自己在这来进行过滤了,比如我们只看一看所谓空闲比例有多大?我们可以定义  node e=idle,来做一个execute 调查,现在就只有 idle , CPU 或者 CPU 核心的空闲比例有多少,这叫空闲时长,空闲比例你可以这么理解,因为它是个 seconds ,如果我们要想知道我们 CPU 的使用率有多高,那我们就可以进行计算了,用 CPU 自己减去它的已用,然后再除以100,这不就是一个所谓的百分比了吗?他再乘上100,就是百分比的实际数字了。那因而我们来看,如果我们要期望能够对我们的 PromQL  或者对我们 Prometheus 中的这些指标数据,投射到刚才我们讲到的监控方法论当中的,比如像 Use上去大概怎么做,我这里专门给出了说明,以便于各位后面自己参考这个来使用。比如说我们看看 CPU 使用率,每台主机 CPU 在5分钟之内的平均使用率应该怎么计算,看这个公式。首先我们可以计算一下我们每一个节点或者每一颗CPU,甚至说我们按节点为类别进行计算,你无论有多少个核心,就都算在同一颗CPU也可以,那这个表达式就来让我们获取到每个主机上的 CPU 的使用率。能看懂这个公式吗?我来给大家做个简单的解释,因为这也是我们下一次课的重中之重。因此我们这里先要有一个基本的了解,稍微有点难度。第一, node_cpu_seconds_total 这是我们的指标名称,就是刚才各位在看的指标,所以我们过滤一下我们所关注的模式的指标,叫 node e=idle ,就能过滤出来一个所谓的几个指标时间序列,然后我们对它做速率计算,这是一个函数叫 irate ,它是一个灵敏度非常高的速率计算函数,然后5m五分钟表示我们对每一个时间序列来讲,取出来,从此刻开始往前倒推五分钟之内的所有样本数据,对这些样本数据做速率计算,你可以认为说是每一个样本减去它的前一个样本,你可以这么去理解吧,就类似于这种格式,或者是每个样本和它的前面样本之间要取一个差叫做△,如果说它是个累加型的数据,该样本减去前一个样本还要去除以时长来计算速率,大概是这样一个逻辑。那因此这个 irate 就可以理解为像类似这种格式就,一个样本减去前个样本除以时间,再用这个样本再减前一个样本除以时间,就类似这种格式让我们可以计算出速率来。事实上 irate 你可以理解为就是最后两个计算的,他没有那么多时间,所以说即便无论你指多长时间,所以我们认为它是一个灵敏度更高的这个函数.接着我们对这两个的数据取平均值,平均完以后然后再做聚合,怎么聚合?我们基于每一个实例聚合,就是如果是同一台主机上的 CPU ,不管你有几颗,我们这些对这些CPU 做平均计算,那就得到的是我们真正的这个 CPU 的负载,而不是每个核心的负载的。用1减去空闲的,那就是使用的部分,乘以100,就可以换算成百分之几的概念了。比如1.06就1.06%就是这意思。否则的话你可能得到数据是0.0106。图上输入的数据是正常情况下要求的数据,接下来我们要给它做速率计算,因而我们要指明一个时间范围,这个时间范围就代表了所谓的叫做区间向量也叫范围向量,它会取到一堆的样本,对这一堆的样本我们可以做速率计算,那这个速率可以是rate,也可以是 irate ,当然rate可能不精准,使用 irate 得到这个速率应该更精准一点 。接着对 irate 的计算结果,我们还可以给他求平均值,大家计算出来是四个值,那么一个核心的负载可能不一样,因而我现在要给他去取平均值,那就叫 avg 这就是做聚合计算,那么聚合的时候基于什么进行聚合?那么使用avg去 by 比如我们每一个实例上面,你无论拥有多少个核心,我们都要对它做聚合计算。 各位看对于这个实例而言,它的四个核心在 idle 模式也就是空闲比例,做一个平均值,就得到这么一数据: 这是空闲的,因为它本身其实你可以理解就是个百分比。那我减一下得到的就是叫使用的,叫使用率,但这个使用率数字它不是一个百分数,所以我们可以对整个数据再给他去乘上100,你可以认为这个乘后的结果就是一个直接所应该能够得到的百分比数据,那就意味着我们当前 CPU 使用率是0.2%。Prometheus 本来就是用来替代 Zabbix的,它是一个完整意义上的监控系统。所以我们随着课程的展开就知道,它本来就是一个双精度浮点数,其实我们在展示的时候可以基于各种各样的取舍,每个 Instance 刚才讲过,其实就代表了一个 target ,只不过在不同语境当中的概念不一样。不同语境指的是如果我们要作为被监控目标进行配置的时候,它就叫target,而配置出来之后就叫 Instance 。我这样讲,大家是不是可以听明白,但事实上之所以非要去区别 target 和 Instance 在于有些target尤其是服务发现配置,只配置一个target,但我通过服务发现可以发现多个,所以 target 严格意义上和 Instants 不是等同的概念,你可以认为每个 Instants 就是一个真正能暴露、能输出、能吐出来指标数据的实例。 target 更像是我们配置出来能够让我们的 Prometheus 找到 Instants 的入口,就是学 MySQL 时学的自由即责任,我们把这东西搞明白了,才能更好地使用 Prometheus 。这可能就是大家发现这个所谓的 Prometheus 内建的 UI 的坏处,我们辛辛苦苦写的 PromQL 一刷新它就没了,它不会保存下来,以后想再用,你还得再写一遍,就很悲催。所以我们要正常用一些外置的,比如像各种展示界面或者叫记录规则,我们把它保存下来,以便于以后能复用,这才是我们所需要的,那这个时候我们需要部署一个 Garafana 来进行展示,不过我们回头再说 Garafana ,我们把当前这个话题给大家说完。 2.  CPU 的饱和度刚才我们通过这个方式给大家讲到了如何去获取CPU的使用率,大家不要着急,我下一节课会详细讲PromQL 它的格式和具体怎么用、有多少种聚合函数、有多少种内置函数,以及向量匹配的时候如何进行,还是那句话,你把那个东西搞明白了,其实 Prometheus 最难的一关已经过去了,至于说像高可用之类的,对运维工程师、对于架构师来讲,这难道能是什么障碍吗?我觉得应该不是。 PromQL 就是 Prometheus 自己内建的。刚才已经说到了我们如何去评估 CPU 的使用率的,大概就是这种方式。下一个我们怎么去评估 CPU 的饱和度?  什么叫饱和度?你可以理解为就是CPU的平均负载、跟踪 CPU 的平均负载本身就能获得关于CPU 的饱和度,就是 CPU 在他的单位时间内,他的工作的满载率有多高?比如说你在上班的时候,你的老板说你工作不饱和,意思就是你没有所有时间内都在工作,一定有一些空闲时间在那玩手机了摸鱼了之类的,那这种就表示不饱和,那因而我们去评估的就是在用于正常工作的时间比例有多大,这叫饱和度。那因此对于我们 CPU 来讲,它其实就是将主机上的CPU数量考虑在内的一段时间内的平均运行队列的长度。这个长度应该是多长合适,其实有个非常简单的办法,就是我们使用 node 自己内建的有 load 开头的几个指标,比如 load1、load5、load15。各位应该已经明白了,这表示节点上过去一分钟的平均负载、过去五分钟的平均负载和过去十五分钟的平均负载。这里显示了我们当前的实例它CPU 过去一分钟的平均负载。点 Graph ,它会绘一个图出来,各位可以看到这个线状图,还能输出为面积图。因为我这里只有一个node,所以它只显示出来一个图形,如果配置多个 node 的话,每个 node 如果负载不一样,可能会有多个图形显示,如果要使用堆叠图、堆叠面积图的话,他们应该会堆起来,然后还能有一个很好的对比效果来进行显示。这个时候对于这个数据很关键,这个数据到底多大算是 CPU 很饱和,一般来讲应该是正常这个数据不能长时间大于 CPU 核心数量。你比如说我们当前节点上一共有四个核心,然后这个数值是8那我们就认为当前的 CPU 已经是非常饱和了的工作逻辑。就正常情况下一个核心在某一时刻时时刻刻都在运行任务,你比如说我们 CPU 没有空闲时间,所以它但凡只要大于 CPU 的数量,而且是长时间大于,我们就认为它是饱和,这个队列可能就会不断的累积,而且会越来越长。要想看出哪个 CPU 占用最高的,刚才第一个我们就已经解释出来了, CPU 如果不做聚合的话,它会算出来每一个核心的使用率,聚合以后,会得出来所有 CPU平均下来的这个所谓使用率,这是我们的饱和度评估。当然,我们还可以写很复杂的方式来进行计算饱和度。你比如说上述图片中涉及的表达式:node_load1>on(instance) 可能更复杂,那么还是那句话,可能等到下节课大家才能真正把它搞明白。我这里给大家做个简单的解释:他的意思就是说我们去计算一下 CPU 在过去一分钟的平均负载所取得的结果,是不是大于该节点上 CPU 的所有核心数量的二倍。如果是,而且长时间是,我们就认为这个 CPU 就是处于高负荷的状态下。那像这种一旦满足条件了的,我们就认为该报警了,因为你的 CPU 实在是压力太大了,很有可能你的应用程序出bug了,或者是访问量,或者你CPU的性能有点弱了,那我们需要去扩充,或者我们需要去扩展我们的应用规模了等等。如果说我们有中央控制器的话,比如我们配置在 Kubernetes 之上,这时候 Kubernetes 甚至能够基于这个所谓采集过来的节点上的 CPU 的饱和度,来判定我们是不是应该加节点了。如果所有的CPU所有的主节点的CPU的饱和度都很高,那他这个时候可以调用云控制器或者云底层的那个公用云的 API 加一些节点进来,把我们的应用程序更好的负载到、分摊到多个不同节点上去,就能实现某种意义上的自动化运维的逻辑。 3. 内存使用率下一个我们看怎么去评估内存使用率,还是那句话,这是 USE 方法当中让我们关注的个重点指标,我们通过介绍让大家知道 Prometheus 怎么去使用指标的。 noed _exporter 要暴露多个以 node _memory 为前缀的指标,我建议各位可以重点关注一下几个:比如 node _memory_MemTotal 总内存空间、MemFree 空闲内存,不过这个空闲是MemTotal 减去真正使用的,而且减去了 Buffers 还减去了 Cached 。所以到底我们还有多少内存可以使用?可以这么来算:真正可用的内存应该是这三个和,加Free 加 Buffers 加Catched,这其实是我们的可用内存量。用 MemTotal 减去这三个的值,我们认为这才是真正的已用内存量。因此我们要想去计算内存使用率,可以是这三个之和,第一个减去后三者之和,再除以第一个就是内存使用率了。底下这个图里边的这个表达式更长,但它比第一个容易理解多了。他的意思就是总内存空间减去空闲空间,再减去用于 Buffer 的空间,再减去用作 Catched 的空间。但凡学过 linux 的同学应该都理解这个概念,然后我们再用这个值去除以总空间,再乘上100,其实就是我们内存使用率的概念。这是小学算术,是非常容易计算的。Available的值不是刚才说了吗? MemFree + Buffers + Catched 。怎么放 Garafana 的出图,我们后面会讲,其实你就把这一个 PromQL 在 Garafana 上点击创建图形,把这个表达式写进去保存,它就会直接生成图了,就这么简单。所以我们说你只要把这个 PromQL 写好了,就能生成,或者再生成图就不是什么麻烦事了。 Prometheus 就是自己的最大劣势就在于他自己内建的这个 UI是没办法让我们持久长久去使用这样的语句的。关键是要会写公式,你要先知道它是怎么运行的,我们是怎么用的才行。鉴于时间关系,我就不去再去输入了,因为太耽误时间了。4.  MySQL exporter  如果我们要想监控 MySQL 怎么办,这个就不演示了,还是那句话,鉴于时间关系我给大家说清楚。 我们怎么去监控 MySQL ,比如现在有个 MySQL 的主从复制的集群,一主两从。现在我要想监控 MySQL服务怎么办?正常情况下话,应该是同样的逻辑,这三个主机上分别运行 MySQL 进程, MySQL 自己并没有内建 Prometheus 键入的测量系统,所以我们就不得不在每一个主机上部署一个专门的组件叫做 MySQL exporter ,因为 node_export只能导出系统级的指标,它不能导出 MySQL的指标,比如你执行过多少个 select 语句,执行了多少个update语句,内部的InnoDB Buffer Catch 有多大,这些他们都没办法知道,因而我们需要一个专门的暴露器来暴露 MySQL 的这些指标,那每一个节点都应该装一个叫做MySQL exporter 。这个 MySQL exporter 其实就是 MySQL 的客户端,他应该能够连到 MySQL 上,有权限以某个用户的身份连入 MySQL 去读取 MySQL 内键各种状态数据,把这个数据取出来以后,由它转换为 Prometheus 兼容的指标格式。转换成这个指标格式以后, Prometheus Server 就可以周期性去抓取,抓取的的时候,像 MySQL Exporter 抓取的意思就是给我一个指标数据,这个时候 MySQL Exporter 就会实时的去向 MySQL 发一次查询,把数据拿过来在本地做计算,再把计算好的结果报告给 Prometheus Server ,每一个实例都是如此。所以这时候你可以理解为这三个实例很有可能是通过同一个target配置发现的,是三个instance。然后对应的这每一个实例都是有一个IP加一个端口来进标示的,我们把它称作一个target,可以这么理解,当然我把它称为叫instance更合适,希望大家能理解。如果是 Java 程序的话怎么监控?很显然那我们应该去做使用 Jvm 的 Exporter ,事实上 Jvm 之上通常还有一定程序,比如像 Tomcat 、Elastisearch 对于那些对应的应用程序,还应该做进一步的监控,这点各位也要知道。 Prometheus 提供了大量的 Exporter ,有的是他自己提供的,有的是第三方机构提供的。他自己提供的,你可以理解为是官方认证的比较关键的, Prometheus 的官方站点上直接能看到下载的页面,在这能找到 node Exporter 、 MySQL Exporter 、memcatchedd_exporter 、hadoop_exporter ,这里没有列出来的,有些也支持,可能我们下载的时候需要到 githab 上去下。其实这个 Exporter 也不是什么难事,很多公司很有可能都自己研发了这样的 Exporter ,使用 GO 语言或者使用 Python 编程,写一个 Exporter 应该是很不麻烦的,因为它有 client library ,我们直接调这个 client library,使用 Python 去写一个 Exporter ,去暴露几个指标数据,简直不要太简单了。我们可能要装很多 Exporter ,但事实上在生产环境当中,如果是略具规模的企业,怎么可能在一个主机上装太多应用。那因而通常一个被监控的主机之上那至少应该会有两个以上的 Exporter :第一,应该有我们的节点的node Exporter ,如果运行了MySQL 那应该还有个 MySQL Exporter,运行 MySQL 还不够吗?打算在上面还跑什么别的应用程序,一般而言,大家知道我们很多服务都是 Dedicated , Dedicated 就表示专用服务器。如果不是专用的没关系,比如再有一个 Nginx ,那应该还有一个 Nginx Exporter 。再运行一个 Prometheus ,  Prometheus 就不用了, Prometheus 自己有Exporter,因为它内置的有 instrumentation 。如果是 Docker ,我们可能需要借助 cAdvisor ,其实 Docker 现在自己内置的也有它的监控接口,直接就可以抓取它这个所谓的 Exporter 。 Nginx 的话,选 VTS 就更好了,使用 VTS 这种方式会更合适。有的同学也肯定就想明白了,既然如此,那是不是说我有个一百来台主机,我的监控抓的指标可能会上万了?没错。所以我的 Prometheus 在存储方面,不光是 Prometheus ,所有的监控系统,只要指标足够多,那在存储方面压力就很大, Zabbix最大缺陷在于它默认使用的存储系统 SQL 类型的存储系统,MySQL 、PostgreSQL 、或者 Oracle 系统,这种系统内置支持事务还有各种约束,那每一次指标数据的插入都要各种约束、检查之类的。即便只做索引扫描和检查,这个评估也不是一个小的负载,所以我们使用 Zabbix 监控如果没有充分优化的话,很快就会遇到性能瓶颈,以至于很多大厂后来就不得不运行多套这样 Zabbix 监控系统,很尴尬,他们只好自研,阿里的是自研的,小米是自研的,已经开源了在这了,OpenFilename、大众点评资源叫cat等等,这些都是基础设施,大家也不要觉得说装一些 Exporter 包是什么大不了的事,有些像分布式链路追踪系统,我们甚至还要自己在被跟踪的应用内部打点的,做埋点的,不做埋点怎么去跟踪、调用内部的数据,都必须要有自省的逻辑,你要买个 Exporter ,你要么打点,这个我相信对于很多朋友来讲,应该不是什么特别难理解的事。坦率的讲,我这可能没办法把每个概念都要解释一下,你可以理解为对 Prometheus 而言,他每个 target 如果自己内置了instrumentation,这个instrumentation就是我们监控系统埋的一个探针或者埋的一个点,所以我们可以理解就这个概念。那如果是分布一定追踪,那它应该是一个专门用来做性能追踪的,做调用追踪的客户端库的这个内置的程序模块,那我们也称为叫埋点。很显然介绍到这里,我相信大家应该有所了解了:一个完整意义上的监控系统,它通常应该监控的指标非常多,刚才已经讲到这个概念,这是第一个;第二个我们监控系统是 IT 系统的基础设施。彼得德鲁克就说过:“你如果不能监控,你就不能管理。”所以对我们运维工程师来讲,哪怕我们架构师来讲,对我们 DevOps 工程师来讲,如果我们运行了很多系统或者叫组件,这些组件如果我们不能监控它,你就没办法管理它,因为你不知道它什么时候出问题了,也不知道内部到底运行什么状态,那我们作何管理?所以我们认为监控系统是我们 IT 信息系统的基础设施之一。即便是我们不用分布式调用链接跟踪,即便是我们不用日志存储和搜索系统,但监控系统通常是必不可少的。有句话虽然略具夸张的概念:“无监控不运维。”那事实上对于 SRE 工程。这个 SRE 叫系统站点可靠性工程。到如此重要的今天,监控系统的重要性几乎又上了一个台阶,所以这也是我们应该掌握的系统的最重要、最核心组件之一。大家要注意,当然如果做事前监控,后面我们讲 PromQL 的时候,我会给大家讲一些比如做线性分析,就是基于所谓的叫做回归测试来做简单分析的,我们真正要做事前监控的话,恐怕也得到 DevOps ,自己要研发一些算法,基于机器学习的方式来做事先监控,否则的话可能这些数据就算我们采集到的数据,你也很难知道它的真正意义是什么。
文章
存储  ·  Prometheus  ·  运维  ·  监控  ·  Cloud Native  ·  关系型数据库  ·  MySQL  ·  应用服务中间件  ·  nginx  ·  容器
2023-02-04
nacos持久化
@[toc]1、nacos持久化持久化:管理的配置信息持久化。注意:默认nacos存在配置信息持久化,默认的持久化方式为内嵌数据库derby(无法友好的展示数据)。2、单机模式支持Mysql  在0.7版本之前,在单机模式时nacos使用嵌入式数据库实现数据的存储,不方便观察数据存储的基本情况。0.7版本增加了支持mysql数据源能力,具体的操作步骤:1.安装数据库,版本要求:5.6.5+2.初始化mysql数据库,数据库初始化文件:nacos-mysql.sql3.修改conf/application.properties文件,增加支持mysql数据源配置(目前只支持mysql),添加mysql数据源的url、用户名和密码。spring.datasource.platform=mysql db.num=1 db.url.0=jdbc:mysql://11.162.196.16:3306/nacos_devtest?characterEncoding=utf8&connectTimeout=1000&socketTimeout=3000&autoReconnect=true db.user=nacos_devtest db.password=youdontknow再以单机模式启动Nacos,nacos所有写嵌入式数据库的数据都写到了mysql。3、将nacos持久化到Mysql中3.1 在linux系统中安装mysql数据库服务数据库版本要求:5.6.5+3.1.1 添加官方的yum源创建并编辑mysql-community.repo文件vi /etc/yum.repos.d/mysql-community.repo3.1.2 编写mysql下载源粘贴以下内容到源文件中[mysql57-community] name=MySQL 5.7 Community Server baseurl=http://repo.mysql.com/yum/mysql-5.7-community/el/7/$basearch/ enabled=1 gpgcheck=0 gpgkey=file:///etc/pki/rpm-gpg/RPM-GPG-KEY-mysql3.1.3 安装Mysqlyum install mysql-community-server -y3.1.4 启动mysqlsystemctl start mysqld3.1.5 获取临时密码grep 'temporary password' /var/log/mysqld.log3.1.6 修改root用户密码mysqladmin -u root -p password 回车 输入原始密码 在输入新的密码我的密码(系统中不是明文显示的):Root!Q2w3.1.7 使用root用户以及修改之后的密码登录到mysql mysql -uroot -p'Root!Q2w'3.1.8 开启mysql远程连接权限,登录mysql之后执行:grant all privileges on *.* to 'root'@'%' identified by 'Root!Q2w' with grant option;再执行刷新权限命令:flush privileges;3.2 nacos持久化到mysql数据库3.2.1 创建数据库nacos 编码方式为utf-83.2.2 在nacos库中执行nacos-mysql.sql文件内容如下/* * Copyright 1999-2018 Alibaba Group Holding Ltd. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /******************************************/ /* 数据库全名 = nacos_config */ /* 表名称 = config_info */ /******************************************/ CREATE TABLE `config_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(255) DEFAULT NULL, `content` longtext NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip', `app_name` varchar(128) DEFAULT NULL, `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', `c_desc` varchar(256) DEFAULT NULL, `c_use` varchar(64) DEFAULT NULL, `effect` varchar(64) DEFAULT NULL, `type` varchar(64) DEFAULT NULL, `c_schema` text, PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfo_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info'; /******************************************/ /* 数据库全名 = nacos_config */ /* 表名称 = config_info_aggr */ /******************************************/ CREATE TABLE `config_info_aggr` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(255) NOT NULL COMMENT 'group_id', `datum_id` varchar(255) NOT NULL COMMENT 'datum_id', `content` longtext NOT NULL COMMENT '内容', `gmt_modified` datetime NOT NULL COMMENT '修改时间', `app_name` varchar(128) DEFAULT NULL, `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfoaggr_datagrouptenantdatum` (`data_id`,`group_id`,`tenant_id`,`datum_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='增加租户字段'; /******************************************/ /* 数据库全名 = nacos_config */ /* 表名称 = config_info_beta */ /******************************************/ CREATE TABLE `config_info_beta` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtext NOT NULL COMMENT 'content', `beta_ips` varchar(1024) DEFAULT NULL COMMENT 'betaIps', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip', `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfobeta_datagrouptenant` (`data_id`,`group_id`,`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_beta'; /******************************************/ /* 数据库全名 = nacos_config */ /* 表名称 = config_info_tag */ /******************************************/ CREATE TABLE `config_info_tag` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', `tag_id` varchar(128) NOT NULL COMMENT 'tag_id', `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtext NOT NULL COMMENT 'content', `md5` varchar(32) DEFAULT NULL COMMENT 'md5', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', `src_user` text COMMENT 'source user', `src_ip` varchar(20) DEFAULT NULL COMMENT 'source ip', PRIMARY KEY (`id`), UNIQUE KEY `uk_configinfotag_datagrouptenanttag` (`data_id`,`group_id`,`tenant_id`,`tag_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_info_tag'; /******************************************/ /* 数据库全名 = nacos_config */ /* 表名称 = config_tags_relation */ /******************************************/ CREATE TABLE `config_tags_relation` ( `id` bigint(20) NOT NULL COMMENT 'id', `tag_name` varchar(128) NOT NULL COMMENT 'tag_name', `tag_type` varchar(64) DEFAULT NULL COMMENT 'tag_type', `data_id` varchar(255) NOT NULL COMMENT 'data_id', `group_id` varchar(128) NOT NULL COMMENT 'group_id', `tenant_id` varchar(128) DEFAULT '' COMMENT 'tenant_id', `nid` bigint(20) NOT NULL AUTO_INCREMENT, PRIMARY KEY (`nid`), UNIQUE KEY `uk_configtagrelation_configidtag` (`id`,`tag_name`,`tag_type`), KEY `idx_tenant_id` (`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='config_tag_relation'; /******************************************/ /* 数据库全名 = nacos_config */ /* 表名称 = group_capacity */ /******************************************/ CREATE TABLE `group_capacity` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `group_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Group ID,空字符表示整个集群', `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量', `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数,,0表示使用默认值', `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_group_id` (`group_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='集群、各Group容量信息表'; /******************************************/ /* 数据库全名 = nacos_config */ /* 表名称 = his_config_info */ /******************************************/ CREATE TABLE `his_config_info` ( `id` bigint(64) unsigned NOT NULL, `nid` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `data_id` varchar(255) NOT NULL, `group_id` varchar(128) NOT NULL, `app_name` varchar(128) DEFAULT NULL COMMENT 'app_name', `content` longtext NOT NULL, `md5` varchar(32) DEFAULT NULL, `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, `src_user` text, `src_ip` varchar(20) DEFAULT NULL, `op_type` char(10) DEFAULT NULL, `tenant_id` varchar(128) DEFAULT '' COMMENT '租户字段', PRIMARY KEY (`nid`), KEY `idx_gmt_create` (`gmt_create`), KEY `idx_gmt_modified` (`gmt_modified`), KEY `idx_did` (`data_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='多租户改造'; /******************************************/ /* 数据库全名 = nacos_config */ /* 表名称 = tenant_capacity */ /******************************************/ CREATE TABLE `tenant_capacity` ( `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID', `tenant_id` varchar(128) NOT NULL DEFAULT '' COMMENT 'Tenant ID', `quota` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '配额,0表示使用默认值', `usage` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '使用量', `max_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个配置大小上限,单位为字节,0表示使用默认值', `max_aggr_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '聚合子配置最大个数', `max_aggr_size` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '单个聚合数据的子配置大小上限,单位为字节,0表示使用默认值', `max_history_count` int(10) unsigned NOT NULL DEFAULT '0' COMMENT '最大变更历史数量', `gmt_create` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `gmt_modified` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_tenant_id` (`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='租户容量信息表'; CREATE TABLE `tenant_info` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT 'id', `kp` varchar(128) NOT NULL COMMENT 'kp', `tenant_id` varchar(128) default '' COMMENT 'tenant_id', `tenant_name` varchar(128) default '' COMMENT 'tenant_name', `tenant_desc` varchar(256) DEFAULT NULL COMMENT 'tenant_desc', `create_source` varchar(32) DEFAULT NULL COMMENT 'create_source', `gmt_create` bigint(20) NOT NULL COMMENT '创建时间', `gmt_modified` bigint(20) NOT NULL COMMENT '修改时间', PRIMARY KEY (`id`), UNIQUE KEY `uk_tenant_info_kptenantid` (`kp`,`tenant_id`), KEY `idx_tenant_id` (`tenant_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='tenant_info'; CREATE TABLE `users` ( `username` varchar(50) NOT NULL PRIMARY KEY, `password` varchar(500) NOT NULL, `enabled` boolean NOT NULL ); CREATE TABLE `roles` ( `username` varchar(50) NOT NULL, `role` varchar(50) NOT NULL, UNIQUE INDEX `idx_user_role` (`username` ASC, `role` ASC) USING BTREE ); CREATE TABLE `permissions` ( `role` varchar(50) NOT NULL, `resource` varchar(255) NOT NULL, `action` varchar(8) NOT NULL, UNIQUE INDEX `uk_role_permission` (`role`,`resource`,`action`) USING BTREE ); INSERT INTO users (username, password, enabled) VALUES ('nacos', '$2a$10$EuWPZHzz32dJN7jexM34MOeYirDdFAZm2kuWj7VEOJhhZkDrxfvUu', TRUE); INSERT INTO roles (username, role) VALUES ('nacos', 'ROLE_ADMIN'); 3.2.3 修改nacos配置文件持久化信息到mysql中4、nacos数据持久化测试这时访问192.168.159.22:8848/nacos里面的配置都是空的 ,那个EMS命名空间是我刚创建的我在EMS导入两个配置可以看到,数据库中数据有更新,持久化成功。测试controller能否拿到远端数据:可以看到,已经拿到了远端配置中心的custom.username的值。
文章
存储  ·  关系型数据库  ·  MySQL  ·  Linux  ·  Nacos  ·  数据库  ·  数据安全/隐私保护
2023-02-04
docker-compose容器编排部署
@toc  本文是对Docker+Nginx打包部署前后端分离项目这篇文章的补充,原文是简单的用docker部署的,需要一个一个pull镜像,一个一个启动容器,很麻烦,现在使用docker-compose一行命令解决多个容器的启停。1、Docker-Compose是什么?  Docker-Compose是Docker官方的开源项目,负责实现对Docker容器集群的快速编排。2、应用场景   Compose允许用户通过一个单独的docker-compose.yml模板文件(YAML 格式)来定义一组相关联的应用容器为一个项目(project)。可以很容易地用一个配置文件定义一个多容器的应用,然后使用一条指令安装这个应用的所有依赖,完成构建。Docker-Compose 解决了容器与容器之间如何管理编排的问题。3、docker-compose部署SpringBoot项目3.1 编写Dockfile# 基础镜像使用java FROM java:8 # 作者 MAINTAINER xtt # VOLUME 指定临时文件目录为/tmp,在主机/var/lib/docker目录下创建了一个临时文件并链接到容器的/tmp VOLUME /tmp # 将jar包添加到容器中并更名为auth_docker.jar ADD service-system.jar auth_docker.jar # 运行jar包 RUN bash -c 'touch /auth_docker.jar' ENTRYPOINT ["java","-jar","/auth_docker.jar"] #暴露8800端口作为微服务 EXPOSE 88003.2 编写docker-compose.yaml  这里主要三个服务,一个是我们的后端服务,一个redis服务,一个mysql服务  三个容器使用同一个docker network。version: "3" services: guigu_auth: build: context: ./sysrole dockerfile: Dockerfile container_name: guigu_auth restart: always privileged: true ports: - "8800:8800" volumes: - ./:/data networks: - auth_network depends_on: - redis - mysql redis: image: redis:6.0.8 container_name: redis restart: always privileged: true ports: - "6379:6379" volumes: - ./redis/redis.conf:/etc/redis/redis.conf - ./redis/data:/data networks: - auth_network command: redis-server /etc/redis/redis.conf mysql: image: mysql:8.0.31 restart: always container_name: mysql privileged: true environment: MYSQL_ROOT_PASSWORD: 'wsxhz888' MYSQL_ALLOW_EMPTY_PASSWORD: 'no' MYSQL_DATABASE: 'guigu-auth' MYSQL_USER: 'xtt' MYSQL_PASSWORD: 'wsxhz888' ports: - "3307:3306" volumes: - ./mysql/db:/var/lib/mysql - ./mysql/conf/my.cnf:/etc/my.cnf - ./mysql/init:/docker-entrypoint-initdb.d networks: - auth_network command: --default-authentication-plugin=mysql_native_password --character-set-server=utf8mb4 --collation-server=utf8mb4_general_ci networks: auth_network:3.3 修改工程配置  修改配置文件,由于使用的同一个docker network,所以容器之间可以通过域名访问,与IP无关。修改后的配置文件如下所示。3.4 将相关文件上传到服务器  后端项目打成jar包并和Dockerfile、docker-compose.yaml一同上传到服务器指定目录下。  项目打包:  将文件上传到服务器,上传之后如下所示:3.5 执行docker-compose up  运行如下命令:docker-compose up -d  查看正在运行的容器:docker ps  可以看到,启动了三个容器,分别是我们的后端微服务、redis和mysql。关闭容器的命令:docker-compose stop  再次开启容器:docker-compose up -d   可以看到,很方便,一个命令实现多个容器的启停,不像原来使用docker那样一个一个关闭和开启容器了。   这里基本上就完了,可以进入到mysql容器内部建库建表就可以了,如果配置了启动的sql脚本那就更方便了。
文章
SQL  ·  NoSQL  ·  关系型数据库  ·  MySQL  ·  Java  ·  Redis  ·  Docker  ·  微服务  ·  容器
2023-02-04
Prometheus 存储和集群|学习笔记(二)
开发者学堂课程【3天吃透 Prometheus:Prometheus 存储和集群】学习笔记,与课程紧密联系,让用户快速学习知识。课程地址:https://developer.aliyun.com/learning/course/1244/detail/184514、Prometheus 存储配置(1)配置参数口--storage.tsdb.path:数据储存路线,WAL日志亦会储存于该目录下,默认为data;-storage.tsdb.retention.time:样本数据在储存中保存的时间长,超过该时间长的数据就会被删除;默认为15d;(可以自己更改时间)--storage.tsdb.retention.size:每个 Block 的最大字节数(不包含WAL 文件),支持B、KB、MB、GB、TB、PB和EB,例如512MB等:--storage.tsdb.wal-compression:是否启用 WAL 的压缩机制,2.20及以后的版本中默认即为启用;(2)容量规划needed_disk_space=retention_time_scconds*ingested_samples_per_second*bytes_per_sample需要用到的磁盘空间=保存时长*每秒钟的平均样本数*每个样本的字节数(每个样本值几乎是等同的)例:1秒钟采集一个样本,每个样本大小大约为1.7KB,保存30天所需的磁盘空间为   10000*1.7KB*30*86400目前固态硬盘不再是稀有物,完全可以把批发读写这样的数据放在性能比,磁盘IO性能较好的设备上进行保存。但固态硬盘的可靠性不如机械硬盘,可以让固态硬盘当缓存,自己将程序再写一遍然后定期同步到机械硬盘中。5、Prometheus 远程存储Prometheus 本地存储时间不长,若想长期存储,存到Prometheus 并不合适因为 Prometheus 是一个监控系统,它的核心功能是监控。因而 Prometheus 最好能使用专门外置的存储系统来存储数据。Prometheus 没有除 tsdb 这样的引擎之外的其他存储设备,它可以直接支持借助于远端的第三方的存储服务来存储数据,远端的存储服务要使用 Adapter 来进行适配。 Adapter 对于 Prometheus,可以通过 PrometheusQL 把数据查出再导入到另外一个存储系统中。读取时,适配器将数据从存储系统中读出,然后交给 Prometheus 的内存再显示给用户。对 Prometheus 而言,适配器对写和读是分开操作的,写可以写在一个存储中,读可以在另外一个存储中读,只要存储本身是可以复制同步过来。它允许本身就是一个集群的可以发往不同的节点。Prometheus 可通过基于 gRPC 的适配器对接到远程存储适配器主要处理里“读”和“写”两种数据操作,它们可分别通过不同的URL完成(1)配置远程读存储url.//读服务器的地址、端口等。最重要的一项。如果存储确实需要认证则提供一种方式即可。[name:<string>]//取域名 [<labelname>:<labelvalue>…]//过滤数据 [remote_timeout:<duration>|default=1m] [read_recent:<Boolean>|default=false] //远程服务是否需要认证是否需要代理。 [username:<string>] [password:<sercret>] [password_file:<string>] [bearer_token:<string>] [bearer_token_file:<filename>] [<tls_config>] [proxy_ult<string>](2)配置远程写存储除了与“读存储相同部分的配置参数外,还有这些专用配置参数queue_config://要配置队列,因为远程服务比较慢。Prometheus请求很快,可以使用队列先暂存起来。[capacity:<int>|default=2500] [max_shards:<int>|default=200] [min_shards:<int>|default=1] [max_samples_per_send:<int>|default=500] [batch_send_deadline:<duration>|default=5s] [min_backoff:<duration>|default=30ms] [max_backoff:<duration>|default=100ms] [send:<boolean>|default=true] [send_interval<duration>|default=1m] Prometheus 俨然就是一个分步式监控系统,各种功能都是以Prometheus solo  为中心辐射出去,各种第三方解决方案或者自己独立解决方案。最麻烦的地方在于alergen mange 可能会宕机,存储也有可能会宕机,对存储本身最好利用自己的功能做成集群的形式。例如三个节点做成的集群才是可用的。Prometheus 自己也应该做成集群,GRAFARA 也要多个。手动维护的话要组合的东西太多不容易操作,就算不使用 KMS 可以使用单机编排,若单机编排承载不了,就使用 KBS。这么多实例该如何部署,接下来讲解 Prometheus 集群。 三、Prometheus 集群1、Prometheus Server 简单多实例建立起多个 Prometheus Server,同时工作,共同收集同一组指标时存在数据不一致的可能性;特点:不支持数据长期存储;仅适用于小规模的系统环境; 所谓 Prometheus 集群就是为了提高可用性跑两个 Prometheus。两个Prometheus 共同监控同一组target。PrometheusA 有自己的TSDB,PrometheusB 也有自己的 TSDB,数据存储在本地,即使它们的抓取周期配置相同但启动时间点不一样也会导致抓取周期不同,二者数据很难完全相同。因此存在数据不一致的可能性。Prometheus 每一个都在本地保存数据,意味着是有状态的,从这个角度讲 Prometheus 是有状态应用。也可以使用将有状态变成无状态的方式共享。 2、Prometheus 多实例共享同一远程存储在前一种模型的基础上,为多个 PromethcusServer 添加一个共享的远程存储支持数据的长期存储Prometheus Server 恢复后能够快速恢复数据仅适用于小规模的系统环境: PrometheusA 和 PrometheusB 可以对接同一个远程存储。此时PrometheusA 与 PrometheusB 都直接把数据存到远端,此时对于proxy依然通过代理来访问,但因为 grafara要展示数据源,而 Prometheus 本地没有数据, grafara支持多种数据源,通过inflax 可以直接在 3rd-party storage展示。即直接用inflaxDB 的查询接口展示即可。这样做解决了数据不一致的问题,还支持长期存储, PrometheusServer 恢复后能够快速恢复数据,但仅适用于小规模的系统环境,因为单个 Prometheus 实例所支持的能够抓取的目标是有限的,这只是解决了存储问题而未解决扩展问题。3、扩展 PrometheusPrometheus Federation(Prometheus联邦)设定多台 Promethcus Server,分别监控不同的 Target;可基于地址位置、机房、业务等纬度来拆分监控对象;设定一台主节点,来合开多个分片的 Prometheus Server 各自抓取的数据;主节点使用 Prometheus federationAPI 进行数据合并;主节点也 PrometheusGrafana 的数据源; 工作方式如上图:可以做多个 Prometheus,每个 Prometheus负责监控一组应用,很多个 MySQL 用一个专门的 Prometheus监控,并且这个 Prometheus 只监控 MySQL 。另一个 Prometheus 只负责监控 Node。显然一个只能展示 MySQL 的监控,另一个只能查询 Node 的监控数据。如果要期望他们合在一起进行展示查询,就需要通过 Federation 合并在一起被中央 Prometheus 统一存储。这是一种分布式逻辑,中央 Prometheus 不会去其他被监控服务器上抓取指标,而是到其他多个 Prometheus 上提取并合并指标。但这样一来每一组都需要提高可用性。4、混合联邦模型与集群共享存储多台 Prometheus 服务器分别监控不同的 Target ,而后使用两台或以上的 Prometheus Server 基于 FederationAPI 合并监控数据至共享的远程存储能监控更具规模的系统环境,但部署复杂; 假设一个数据中心,因为系统是多机房的,数据中心中的每一个机房里面部署一个 Prometheus 作为合并房,合并一个机房中监控的多个不同指标。比如可以将 My SQL 和 Node 合并起来。合并起来后存储被中央全局 Prometheus 所抓取。抓取完后集中式放在 Ser-party storage 中。为了避免过于复制,没必要将每一级别都考虑的非常完整。混合联邦模型与集群共享存储,既有可用性提升又有扩展模型。但如果手动组织过于困难。 5、Alertmanager 高可用Gossip 协议多 Alertmanager 实例的场景中,告警信息可能会被重复发送;Gossip 机制可为多个 Alertanager 之间提供了信息传递的机制以确保在多个 Alertmanager 分别接收到相同告警信息的情况下,只会有一个告警通知被发送给 Receiver;Gossip 是分布式系统中被广泛使用的协议,用于实现分布式节点之间的信息交换和状态同步; Alertmanager 高可用比 Prometheus 高可用更加麻烦,如下图所示有两个 Prometheus Server,为了可用性配置了每个 Prometheus Server 都能使用两个 Alertmanager实例进行报警。但如果这两个 Alertmanager 都在正常工作,一个 Prometheus Server 触发一次告警后,两个 Alertmanager 同时给一个用户发告警是没有必要的,还会让用户更受困扰。两个 Alertmanager 可以认为在 Prometheus 组合的时候是有状态的,或者需要一次中央协调节点 leader,实在没有 leader 也可以使用中央协作机制,需要使用流言协议。每一个节点拿到信息以后都会将一些信息尽可能让其他节点明白这个节点做过的事情,以确保其他节点不会重复发送告警,这是借助流言协议进行协作的。当我们启动 Alertmanager 的时候。会有 gossip not settled的信息提示。因为在指定部署的时候只有一个 Alertmanager 所以没必要设定,但即便是设定了也无法发出。提示为gossipe settled:proceeding。因为只有一个实例,但多实例的 Alertmanager 必须要使用流言协议组织成集群,以确保同一个Prometheus Server 触发的告警不会被重复发送。这是 Alertmanager 内置的一种功能,所以只要部署了Alertmanager 就可以使用该功能。Gossip 是无状态的,但事实上也并非完全是无状态因为导入一个告警后它可能对一个 Gossip 有效,对另一个无效。
文章
存储  ·  缓存  ·  Prometheus  ·  监控  ·  Cloud Native  ·  关系型数据库  ·  MySQL  ·  数据中心  ·  时序数据库  ·  开发者
2023-02-04
PromQL 进阶|学习笔记(二)
开发者学堂课程【3天吃透 Prometheus:PromQL 进阶】学习笔记,与课程紧密联系,让用户快速学习知识。课程地址:https://developer.aliyun.com/learning/course/1244/detail/184485. Histogram quantile 的函数这个函数允许自己我们指一个分位数,这个分位数就是位于0到1之间的,比如定义刚才所说0.5,即表示50分位数,这整个区间内的50分位是谁?跟上这个basename,就是我们自己指定的标签名,加上bucket,它就能通过函数粗略的估算出我们的所有采样当中大概正好中位数名的数是谁。我第一次的描述可能不是特别精确,我再重复一遍。正常情况下,我们所谓的取中位数指的就是在你的整个样本取值中间我们虽然认为我们的取值是0-100,但我们同学不可能正好0分分布到0分到100分之间,很有可能你是30分到99分之间。我想知道30分到99分之间正好中间中位数是谁?他要根据你的范围来做计算,但这种计算只能是一种线性计算,因为我们没有存真正的样本数都是多少,这种计算一定会有偏差。现在大家应该容易理解。很有可能他是这样算的,举个例子,你比如小于等于我现在让你取50分的,现在在60分上的同学有几个?比如同学有几个,落在小于45的有几个,那就意味着45-60之间我们是不是可以算他一个大约数?根据这几个数字我们评估,比如我现在这个范围内有三个同学,而45-60之间一共有15个数字,于是我就取一个最中间数,认为这是他的,就正常计算把3个均匀的分布到这个范围内,差不多最中间数如果是4个,也只能是按照4个,把这4个均匀的分布到这个范围上,找一个中间数,再不然找中间那俩值再做个平均,什么类似这种方式来进行估算。所以它一定得到的不是精确值,只能是估算它的结果。但如果我们要非要得到精确结果怎么办?没办法,histogram这种直方图本身就不支持,因为它本身就是一种线性推算出来,这种偏差一定是存在的。这个图它大体上就描述这种偏差。正常红线表示正常的样本分布应该具有的样子,因为这是正态分布,差不多正常情况下,这种统计都是满足正态分布的。但是蓝线大概表示出来。比如这是分位点,这是1/4分位点,这是四分位点,这是中位数,3/4分位点,这是百分位点。很显然,它估算时,类似于以这种区间的方式来估算,我们的估算值应该是落在直线上,很有可能落在直线上,或者是落在蓝色的画的不规则线上,跟我的红线一定是有偏离,再重复一遍,因为它是个估算,它不是真实的样本值。你的样本值没有被记录。我们要想得到精确样本值怎么办?只有一个办法。我们使用另外一个,叫做summary的类型,因为summary是客户端,直接算好分位数,直接上报服务端直接记,不用计算,因为我已经记好,这几个分位数分别是什么?比如在我们的采样区间内,50分位数是几?75分位数是几?但你想再算60分位数怎么办?对不起,我上报的只有25分位数、50分位数、75分位数和百分位数。没有别的,你就用不到。所以summer的好处是能得到固定分位点上的精确值,但不能去任意估算。这是summer的特点。因为我们说过summer是报什么值的,报什么数的,直接指明我这个分位点。每一个桶里边,你可以认为它不是桶。时间序列记录了每一个分位点上对应的样本,到底是什么?比较常见的是summary直接上报零、零点二五、零点七、五和一几个分位点。我们说过这叫中位数1/4分位数,这是四分三分位数,百分位数也有这样几个点的,比如我想知道百分之50%以下的,或者为0.5以下的,0.9以下的,0.99以下的这几个分位点,什么意思?分位数代表你的采样值有50%大概是什么样?有90%大概是什么样?99%大概什么样?什么意思?仍然以刚才我们同学的例子为例来进行说明。假设我们某一次采样的结果当中,在这某采样的结果当中,我们认为60分位数,或者我们有一个叫做中位数是75,我们认为什么意思?班里边同学有一半小于75,少考的分数是低于75,另外一半是多于75,同样,我们认为叫99分位数99%是70。可以用什么?班里边的同学,99%的同学都低于70分,只有1%的同学是高于70分,这叫统计分布。6.统计分布在监控中的作用我们在监控中有什么作用?很简单,比如我们现在记录的是什么?是我们的HTTP服务器,注意抓的指标是HTTP服务器的请求响应时长,叫response_time_seconds。随便举个例子,就这样一个指标叫http的起响应时长,以秒为计算,开始给它记分位数,想知道我们的网站大概请求时长多少?你要在这用gage来记录会有什么结果?用Gage来记录,那就意思每一次采样它都记下一个所谓的响应时长,这叫Gage。因为我知道响应时长它不可能是个计数器,不同请求,他们的数据可大可小。所以我们要使用gage计数有什么特点?想知道平均时长,我们到底请求响应时长大概位于什么样的区间,有什么样特性。于是我们记录下所有的请求,或者叫我们记录下每一个采样点的请求的具体的响应时长。到最后,我评估一下大家大体上请求时长都有多少于是我取平均数,比如平均数为1.3秒。但是我们说过平均值是会坑人。可能有50%的请求大概都在1.2秒,但是也有个别请求,可能请响应结果为10秒钟。它无法精确地反映出来我们的真正网站的节目响应情况,因此,我们如果把它使用histogram来进行技术会有什么特点?我也可以查出来说99%的请求大概它的时长在是什么?比如我们求取了一个99分位数为1.1,你可以理解什么意思?99%的请求响应时长都不超过1.1秒,我认为网站是正常,1%的异常我们认为是可以接受的。但你使用平均数,你无法知道它到底百分之几有多少。平均值是1.3,但很有可能有很多请求是0.001秒钟完成,但只有50%,大概就在0.001秒之内就能完成。而另外50%很有可能是在5或者在10秒以上完成的,你说平均1.3,你认为这合理吗?你的网站服务,正常吗?这不是一个大坑吗?所以我们说很多时候平均数是无法精确描述我们的真正某一个测量度的特征的,这就是为什么我们要使用分位数的原因,其实对我们将来在我们的网站的应用的监控的响应时长这方面用的最多,基本上分位数都是用在这个位置的,包括比如你在磁盘存数据,多长时间能存完磁盘,请求响应时长,网站请求响应时长等,这些其实都是重要的指标,数据应用监控当中,响应时间是一个特别关键的指标,这也是为什么我这里又利用那么多时间来给大家再次讲解概念的原因,相关知识一定要理解清楚。当然要想使用好分位数确实不是件容易的事。我们回头继续说promql,我们前面已经讲到promql的基础的表达式。 二、prometheus 的聚合函数聚合计算,我们讲过大多数指标我们采集后,不用也不可能去一个一个查看它的样本值,这对我们而言不关键,更重要的是,假如我们的web服务器跑20个实例,因为我们现在网站访问量很大,跑20个实例,这些实例上统计的响应时长也不可能主节点每一个节点的查看。所以多数情况下很有可能会把多个target上的同一个指标合并起来统一进行计算,比如求解它的平均值之类的来进行,所以我们说一般来讲,单个指标的价值不大,监控场景中往往需要联合并可视化一组指标这概念,这一组指标很有可能是来自于不同target的同一指标。也有可能是位于某一个对应的指标名称下的多个维度,我可以给它聚合起来进行计算,这种联合机制所谓叫聚合操作。比如像计数、求和平均值、分位数、标准差及方差等统计函数,把这些函数应用于时间序列的样本之上,我们让它生成具有统计学意义的结果,所以我们对于做监控的同学来说,了解统计学知识有时候还是很有必要的,当然也不一定非要去懂,回顾中学的什么叫标准差,什么叫方差也可以,接着我们也可以对查询结果事先按照某种分类机制进行分组,叫groupby。各位在学MySQL的时候应该学过,我们班里边所有同学,你可以求平均,比如这某一次考试,求所有同学的平均得分,也可以干什么?我们班里边一共分4组,求每一个组的平均得分,这就是分组统计,或者是每一个组各自的有多少个同学等。这种就叫分组统计,分组其中包括分组统计数、分组求平均值、分组求和等,这个叫计数,可能更合适一点。聚合操作其实就是由prometheus内置的聚合函数来进行计算。它可以针对一组值进行计算并返回注意单个值或少量几个值。既然叫聚合,不能越聚越多,它其实是一种折叠的效果,它应该起到一种叫做折叠的效果。我们要减少数量的prometheus内置提供了11个聚合函数,我们也可以把它称为叫做聚合运算符,但是各位要记得的是,这有个特别要点,重要的要点,这些运算符仅支持应用于单个即时向量的元素。意思是这些计算的函数是不支持用在范围向量之上,其返回值也是具有少量元素的新向量,甚至是只有一个元素的,只有一个元素不一定叫标量,因为它可能得到的结果刚好有只有一个元素,但有些值是标量,因为它本身不具有向量的意义,它称为叫标量。这些聚合运算符既可以基于向量表达式返回结果中的时间序列的所有标签维度进行分组聚合,也可以仅基于指定标签维度的分组。再分组聚合。什么意思?比如这里有个是序列,有指标名,它有三个标签。我可以只针对标签1做聚合,也可以针对标签1标签2做分组聚合。也可以把所有的标签拿过来做分组聚合。所有标签都拿过就意味着只有这一个值,这一个序列自己能聚合。话回来即多个target上这个序列可能就不止一个,这是prometheus的聚合函数。我们来学习这些聚合函数都是什么以及它该怎么用。1.聚合表达式promql中的聚合操作语法是以下两种格式,其中任何一个都行。我们来看怎么用,第一,使用聚合,聚合函数或者叫聚合操作符<aggr-op>([parameter,]<vector expression>)[without│by(label list>)], 我们要使用的聚合函数比如叫avg,你要使用的是avg,这表示我要在这写avg,这叫向量表达式,就表示你要打算对哪个向量表达式。我们要知道过滤就和我们前面所说的时间序列过滤器,针对过滤器本身做聚合,怎么聚?可以整个聚合,也可以指定的标签聚合。其中without叫排除法,意思是要把指标排完后,排除以后把剩下的指标为标准进行聚合。也可以使用by,这表示什么?包含法就以我指定的指标进行聚合,反过来的不聚合。 下面这种表达格式跟上面一样:<aggr-op>[without│by(label list>)] ([parameter,]<vector expression>),只是下面把without写前面。意思without和by既可以直接写在聚合函数后面,也可以写在小括号括起来的聚合表达式的后面。这就所谓的聚合操作的基本的语法格式。我们聚合时可以先分组后聚合,叫分组聚合。所以without和by分组与否的特别重要标准,它俩不能同时使用。因without表示排除法,表示把某些标签排除以后把剩下的标签用来做聚合。而by表示以仅以指定的标签做聚合。事实上,每一个函数只有功能上的区别,在表达格式上,在使用的语法格式上没有区别。我们举个例子就知道。我把我的prometheus再次启动,user/local/Prometheus,我们让它运行。现在我们去打开站点,我们打开表达式浏览器,看里边有哪些指标可以被我们使用。当然更重要的是,我们要想聚合,要看怎么聚合。要求和我们说过,一般要用在gauge类型的指标上还记得求平均值也应该是gauge类型的指标,一定要记得聚合函数只能用于及时向量而且还不能用于范围向量,因而我们在这里可用指标。这是一个9090,大家知道这是prometheuse自己的指标。9090是prometheus进程自己的监听的端口,我们也可以使用9100,这是node的端口,1.1上好像没启用,我看意义上应该node exporter所输入的指标。我们找一个Gauge类型的指标而后就可以对它做聚合。这是最容易理解的,还回到9090里。我们就直接搜索,在查找一个gauge,这里它的标签太少,我们要找两个以上标签的。各位看Node file system available bytes,叫节点文件系统的可用空间,以字节为单位,filesystems space available to non-root userBytes,底下定义这是sdae。设备sdae文件系统是什么?挂载点是什么?大概还剩这么多空间,这是第二个,这是第三个。能看懂这意思,所以我们就查这个指标叫Node file system available bytes。复制后我在这里先把它过滤出,我们看它的所有指标。各位注意这里的区别,首先,这有节点123各自每一个节点上的统计,所以instance代表的节点,如果我们要只统计单一节点,instance就必须要过滤,我们要以它为分组进行聚合,分别统计每一个节点上的设备,同样的逻辑,如果我们考虑我们计算出来所有节点上的所有空闲文件系统的剩余空间之和是多大?很显然,我所有是不是都可以不过滤?我们就直接使用sum,叫sum求和就可以,后面使用括号括起,我们格式这叫操作符,要使用括号括起来,这里还有个参数。有些聚合函数要求有参数,但SUM不要求。我们既然没有指定任何聚合分组的标准,那意味着事实上这里就表示把所有节点上的所有磁盘设备的空闲空间全部加起就取得一个结果。假如我们要分节点,以节点每一个节点上空闲空间多少,我们就使用by(instance)(Node_filesystem_avail_bytes)就可,sum对它进行求和。把by写前面写后边都可以,by对应的叫做instance标签execute,by (instance),这也需要个括号,这就是所谓的叫node01上的所有的空闲空间之和,这容易理解。很显然,我们要根据别的标准进行聚合。再比如我只看看所有节点上的sdae的空间的大小,很显然我们就基于device进行聚合就可以,就这么简单,看你自己的需要,我们也可以根据挂载点进行聚合,amount每一个挂载点,比如我们这就分每个节点上的根还剩多少空间,每个节点上的boat还剩多少空间就可以,甚至于对其他的挂载点,你像这run,我们不聚合,你可以写得更复杂一点。比如在这我们先去过滤它的mountpoint的值,要么是boot,要么是跟,我们先取出来,只取出来这样对应的指标序列。对这些指标序列,我再分进行聚合,选sum先聚合就可以。而聚合时,我们还可以对各个挂载点分别进行聚合。意思就是我算所有节点上boot的空间有多大,所有点根的共同性规定多大,即the by-的问题,你by mount point,就根据我们的mountpoint本身进行聚合,也就意味着每一节上的所有的boot剩余空间是这么大,容易理解,只要各位知道这样怎么用,我就不一一去解释每一个函数的意义,就没不用一一去演示,因为它的格式都是一样。当然我一直用的是by,你也可以使用without等,这根据需要,根据自己需要的场景。于是我们来看后续的这些函数都有什么功能,它们分别都是什么。2.11个聚合函数其实大多数都很容易理解,而且各位都应该都使用过。像刚才我一直使用sum求和,avg平均值,count就是计数,这三个应该最容易理解,还有两个更容易理解的最大值和最小值,其他几个我们需要简单解释一下。比如这个叫标准差,标准差是描述数据波动大小的或者称为叫波动程度的,叫做标准差。对样本直求方差,它是求取标准差过程中的一个中间状态,它们的意义比较相近,方差和标准差的统计学的意义比较相近,但他们适用场景会有所区别。接着topk,这是我们做排序的时候用到的最多。比如像刚才我们得到的所谓的过滤出后,我们期望得到空闲空间量最大的磁盘空间是谁,最大的设备是谁,就可以使用topk,还可以分组进行聚合,每一个节点上,它可能有很多个磁盘挂载点。我们取出来空闲空间量最大的各自的前两个,这不就是topk吗?而bottomk则是最小的几个,topk刚刚说过叫由大而小,叫逆序。排完序后取指定的数量,上面是大,下面是小,而bottomk上面是小,下面是大,是顺序排序,依然是求最上面两个,所以我们说topk是取得最大指定的数量,而bottomk是取的最小的指定数量。bottomk和topk到底是返回几个?这两个都是需要指参数parameter,现在就有意义。比如返回前10个,返回前5个,这个数字的意义。下面quantile,叫分位数,用于评估数据的分布状态的,该函数会返回分组内指定的分位数的值,注意这给我们刚才讲的Histoquantile或者叫histogramquantile不同histogramquantile函数只适用于叫histo数据类型,而这适用的是什么?应该是一个gag类型的数据或者是一个counter类型的数据。所以它本来就是样本值。它从各样本值里边找一个中位数,找一个1/4分位数,找3/4分位数。这跟我们刚才讲的histogramquantile是有所不同的。histogramquantile是不用自己的样本值,直接保留的就是桶存储桶和计数,summary直接保存分位数,用不着样本值。而如果我们需要用样本值的时候,你可能使用gage,使用counter计数,但偶尔我们需要在这样的样本值上去求得这整个样本的分布状态。这个时候我们就要使用quantile来定义。所以它是两回事。再重复一遍,这是为什么他俩名字都不一样。后面count_values,这个指的是对分组内的时间序列的样本值进行数量统计,它跟count是有很相像的。但是count_values有它的特殊作用,而且count_values是接受参数的。它跟bottomk跟topk一样,你可以指定我只对内范围内的多少个矩形计数或多大范围进行计数,类似于这种,再重复一遍,count_values是用于在时间序列中的每一个样本值出现的次数进行计数或者精确地讲比如counter,我这里指定一个时间序列,它算出里一共有100个数,100个样本,就一共有100个样本,而count_values指的是它在里边它认为你其中这100个样本里,3出现6次,7出现8次,对每一个样本值进行分别计数,这叫count values,因此count_values会输出很多个时间序列它的返回值,每一个值都是一个时间序列。其他的应该就没有什么特别需要再说明。各位只需要知道比较复杂的函数只有后4个,就是topkey,bottomk,quantile和countvalues。因为它们4个是需要接受参数,前几个一个逆序,一个顺序。这个表示到底是参数,应该是你打算得到哪个分位值。比如五十分位值,九十九分位值,你要指定是哪一个分位值。而count values可以不用给它传参数,但我们要传参数就意味着你要指定哪个样本值,大概就是这样,这是它的聚合函数。
文章
存储  ·  Prometheus  ·  监控  ·  Cloud Native  ·  数据可视化  ·  关系型数据库  ·  MySQL  ·  开发者
2023-02-04
PromQL 使用基础|学习笔记(三)
开发者学堂课程【3天吃透 Prometheus:PromQL 使用基础】学习笔记,与课程紧密联系,让用户快速学习知识。课程地址:https://developer.aliyun.com/learning/course/1244/detail/184475.匹配器匹配器怎么使用?对于Prometheus的匹配器来说,我们需要做标签过滤时,你使用标签名 label name,后面使用一个操作符 operator 跟上一个值 value 来进行评判。这里的中间 operator 意思是对标签来讲叫 label name,我希望它的值要满足什么条件,所以操作符指的就是叫做匹配或者称之为叫做比较表达式构建中的一个常用的字符串比较操作符,或者叫字符串过滤操作符。因为这里我们要过滤的是你的标签对应的标签值。匹配什么,第一等值比较,第二取不等之比较,不等于则为真,等于则为假。表示模式匹配,比较匹配则为真,不匹配则为假,模式不匹配,比较匹配则为假,不匹配则为真,这样 4 种 比较操作符,或者叫做模式匹配符。要注意的是,匹配到空标签值的匹配器的时候,比如这样写,则该指标名称上所有未使用标签的时间序列也符合条件,所以标签值不能为空,意思就是标签逻辑不支持匹配空值,一旦匹配空值,意思就是标签,这个标签意思就意味着有没有都行,它不是用来匹配空值。等于空值,意味标签有没有都行,而不是标签值是空的,大家要注意这一点,这是 promQL比较诡异的一点,所以我们也一样。我们其实并没有一个底下的所有标签,里边也是一样,没有一个叫因为的标签,所以写 ENV =空,ENV =空意味没写,等于什么也没写。因为我们压根就没有因为标签这些,实际所有实验学的都没有。而有因为标签的,写不写的结果是一样的,所以我们说一定要记得他没法挑选空值的标签。接着,正则表达式将执行完全锚定机制,意思是你给定智能表达式模式,一定要能匹配标签的所有值,整个字串只匹配部分是不算,它要匹配指定的标签的整个值。举个例子,比如现在有个标签叫做job= node _exporter,写个表达式,这样写job 匹配node。请问假如有个时序,时间序列叫 Promhttp,它有这么个标签,请问符不符合条件?我的表达式是Prom_http{job=~“node”},这是上面原来的时间序列的标示,这是我写的表达式,请问上面序列符不符合?底下表达式是不符合的。node 虽然能匹配到字串,但要记住它的匹配逻辑是叫完全锚定,只有能够你的模式,只有能匹配到整个标签的值才认为是匹配的。所以这应该要写成比如Prom_http{job=~“node.*”},就意味能匹配它,要把整个值全匹配,要完全锚定的意思,所以它是假设是做整个字串前后完整锚定的,所以你要写的模式一定要打算匹配哪一种,特征是要一定要写完整。接着向量选择器至少要包含一个指标名,或者至少有一个不会匹配到空字串的匹配器,其实可以有3种组合,仅给名称,如果不给名,就要给匹配器,而你的匹配器匹配是空的。到底是什么条件?就是没条件,所以要么能匹配出来一个指标名,要么能匹配出有一个既定的返回的是非空值的匹配器,否则的话就相当于挑整个数据集。prometheus 不允许这样的操作,所以至少要包含一个指标名,或者有一个不会匹到空值,所以{job=””}就是非法的,因为它既没有名称,又匹配的是空值,这就不行。另外我们也可以使用它做标签名,在里边这样写来过滤指标名,刚才给大家说过。匹配器有这样的概念,我们就容易的使用起,或者在使用上就可以有一些进阶。比如我想知道node,至少有一些特定的可以给他们取出。比如我想知道 node CPU 相关的指标,写 node CPU接着 second total,这就可以查出结果,既然是 total ,我们说过都应该是计数器,对计数器而言,直接展示出没作用。我们通常要对它做速率运算。我们不说那么复杂,要知道的是第一我们期望找到所有以 node cpu 开头的那些序列,怎么办?刚才给大家说过,应该使用划括号下划线 name 对它的值做匹配吗?匹配叫 node的CPU,你只写这么多是不行的,我们要做完全锚定,跟上.*,这样来进行检查和匹配,看这里都是 node的CPU开头的指标。因为那么多节点,这样挑选其实是一个不明确的做法,应该有多少时间系列返回出。但是要知道,这是对名称做过滤的。我希望对名称做过滤以后再找其他的限定。比如我们希望看用户空间的时间消耗。要 model=user, model =nice是 model =idle大家知道 idle 表示什么?这里有空吗?有 Idol 吗?好像没有,就使用户空间的,所以加第二个条件, mode=user,做等值匹配,{__name__=~”node_cpu.*”,”mode=user”},这样它就挑选出这样的几个时序,有 mode 标签,而且它只是 user 的,比刚才少。如果是 user 也行,是nice 或者 system 也可以,需要添加SYS,这里称为模式匹配,叫做 user 或sys,有user,没有sys, user 或 sys开头的或者 nice , nice 应该是有,要查看 user , nice 的也都出现,所以用逗号隔开。这样实际上是两个域条件,这样我们可以写复杂的表达式。再次重复,中间后面加个时间范围,这叫范围选择,或者叫范围向的选择器,但不能绘图,绘图会出错。6. 范围向量选择器范围向量选择器怎么用?有哪些要点我们需要注意,同级时向量选择器的唯一不同之处在于范围向量选择器需要在表达后紧跟一个方括号来表达,需要表达需在时间序列上返回的样本所处的时间范围。而这个时间范围指是以当前时间点为基准,时间点逆向过去的时间长度。比如 5 分钟,时间格式就是一个整数,必须使用整数,后跟一个时间单位。比如5m 的 m 就是单位,它支持使用单位毫秒、秒分钟、小时、天、周和年,没有月,注意它没有月的表达方式好,它对我们来讲,它一共保存的数据没有使用远程存储的时候可能不会太长。所以我们多数情况应该用的都是小时或者天,甚至是周的时间范围。但是要注意的是,我们必须使用整数时间,一定要记住,所以你不能使用 1. 5 小时,这是不对的。但你可以使用 1 小时 30 分。这不同单位级别进行组合,而且单位需要从大到小才行,注意可以将多个不同级别的单位进行串联组合,以时间单位大小由大到小进行排序,比如 1 小时 30 分。千万要记得不能使用小数,需要注意的是向量选择器范围,那是一定时间范围内的数据样本,虽然不同时间序列上的数据抓取的时间点我们说过,但它时间戳不会严格对齐的原因我此前说过是 prometheus在趋势上是准确的,但并非是绝对精准的。因为时间点是被分散开的。这叫范围向量选择器。比如这已经使用了 1 小时,过去 1 小时内的时间样本。这样本数量反馈的可能会比较多,而且不能绘图,所以只 execute。 看到,这是对第一个时间序列来讲,它防着一个小时的时间样本,因为它每 15 秒采集一次,所以这数据量会非常大。缩短一点,比如 1 分钟,一分钟每一个就只有 4 个样本。因为每 15 秒采样一次,正符合我们所推测的样本。刚才有讲过,范围向量选择器绝大多数都是跟 rate 函数或者 irate 函数一起使用的,用来我们计算特定时间范围内的平均值来表达速率的概念。一般来讲,把它们取出求平均值就行。如果是计数器,我们应该一起来进行计算。但如果是非计数器性值,你使用 AVG 也行,这叫求平均值。不过这里告诉我们有些地方是有问题的,因为这是一个向量,我们这里要使用rate, ready blue。我们要查看指标,叫做返回值类型,才能知道该怎么计算。可能这几个指标类型完全不一样,有适用于第一个不适用第二种,有适用第二种,不适用第一种,可能是这个意思,因为他反对指标数量过多。我们还是按照一个特定的,比如 GAG 类型,可以直接求平均值,而 counter 类型的,还记得我们的指标类型吗? counter 计数器我们要计算速率, Gage 我们可以计算平均值。一般而言,这是聚合,另外还有两个直方图,还有 summary 摘要。如果两个指标返回的数据类型不一样,使用同一个函数就会出错。像刚才我们应该出现这种问题,我们可以给它归类到同一个指标上。比如node,CPU,guest, second total,可以是固定的防疫特定的值。这些应该都是 counter 类型的数据。如果是counter,我们就可以做 rate 计算来求得一段时间范围内的变化速率,当然我们 CPU 利用率很低,所以你看它的采样值都是0,它做圆整,加起来不到1,因为节点都很空闲。7. 偏移量修改器偏移量修改器什么意思?刚才指标,或者以prometheus为例。 大家看到这每一个指标返回的都是什么值?我刚才解释过,这叫及时向量,也就是时下这一刻最近一次的采样的样本。如果我想知道 5 分钟之前那个样本怎么办?我这里加5M 意味着什么?这是 5 分钟之内的采用样本,所有样本。 我需要找 5 分钟之前那个样本,这需要偏移,我们需要这样写,仍然即时向量。我们使用 offsite,后面指定 5 分钟,表示往前推, 5 分钟之前及时向量,这叫偏移,是上次的采样本看是否存在,这就不是最新的样本。 25 分钟之前的,这就偏移量。同样的逻辑,如果我们需要在这里指定一个时间范围,又指定 5 分钟,比如在这里指定1 小时 5 分钟,这是一个什么?表示 5 分钟之前开始计算,再往后回逆一个小时,表示不是以时下这个时间点往后逆一个小时而以5 分钟之前那个时间点,我可以再往前逆一个小时,所以叫偏移量,这就是偏移的结果,它依然是一个范围。向量没出错,但它是被偏移,画图应该能理解,在 MySQL 上或者其他的数据服务上应该学过类似的概念。正常情况下,我们查询时,及时指的时下这一刻的时间。当然我们时下这一刻可能没有样本,但他一定寻找最近这一次样本,这叫及时或叫瞬时。如果我们要想找过去某个特定时间点的,就表示我们要使用 offset 偏移到过去,这叫偏移的一个范围。找过去时间如果是范围向量,以时下时间,比如这是当前这一刻,找最近以它为起点,往前偏 5 分钟,这是我们过去一直用的时间点返回的范围向量。但是我们也可以只过去一个小时,往前偏 5 分钟。比如这是当前的时间,往前逆一个小时,这是一个小时之前那个时间点。从这个时间段为基准,再往前找 5 分钟,这是所谓叫偏移量为一个小时,叫 offset 一个小时。跟我刚才所举例子略不同,找的是过去 5 分钟的范围内的。刚才表达式他写的是1 小时5 分钟,我刚才画的图表解释意思叫一个小时之前,以一个小时之前的时间点为准,往前逆 5 分钟,这是 5 分钟之内的时间值,数据值。 四、PromQL 指标类型Prom QL 的指标类型,刚才已经讲解过,接下来详细介绍这些指标数据各自该怎么处理以及能怎么处理?第一, counter, 我们讲这叫计数器,单条递增,除非重置,数值一定是增长。第二,仪表盘,已经解释过,可增可减的数据,所以我们说这种数据一般不会拿来直接展示的,没有实际作用,我们通常需要对它做特定时间范围内做 rate 或者 irate 计算。既然可曾可减,那我可以取 AV G ,取平均值,也可以在一个范围内取最大值,取最小值,计算方差,计算标准差等,这叫仪表盘。一般而言这些应该可以计算。histogram ,直方图,把一个时间范围,把我们所期望的时间范围内的样本分成多段,每一段,当然每一段的大长度是固定的。每一段单独进行计数做什么?第一,对每一段而言,我取出它的样本个数。第二,对每一段内的样本值求和,所以我们可以对应的结果取分位数,比如中位数。中位数和平均数有何区别?中位数也叫中间数,比如1352070,他们的平均值应该知道,差不多在 20 左右,中位数最中间数为5。比如全国人民的平均工资是20,你是不是会被平均?因为一半以上的人都为20,所以我们需要用平均值。很多时候会有概念上的偏差,会产生长尾效应,中位数可能更能代表一般情况。所以这个时候我们求中位数就是5。但是如果这个范围内的采样值非常多怎么办?我们就要分段,这一段,这个区间分成多个区间来计算。所以我们说 histogram 作为直方图,可以用于分析异常值而引起平均值过大的问题。这不就异常值吗?引起的平均值过大分位数是因为你用 135 进行平均,比如叫 50 分位数,叫 50 分位数,它其实是百分位的结果。再看后半段的平均值,计算出它的差别应该是非常大,所以这样我们就知道前一半后一半之间的数据差别很大,而不至于整体平均,也看不出来中间。其实这些数据离散性非常高。1.counter 和 gauge看对它的详细说明, 先看对 counter 说明。通常 counter 的总数并没有直接作为一个的奖励概念,而需要借助于rate,topk, increase 和 irate 等函数来生成样本数据的变化状况。 rate 叫速率,既然要速率,必须要指定时间范围,刚才给大家讲因为它的速率指的是在特定时间范围内的 Delta 值。叫 Delta 的平均值。意思为从第一个样本到第二样本取一个差,从第二个样本到第三样本取一个差,第三个样本到第四个样本取个差。把这些差值拿来平均,叫 Delta 平均值。我们称为叫增速或叫变化速度,若是单调递增的就是增速,速度可能增加,也可能向下。topk,该指标下请求总数排名前 n ,所以叫 topK,或者为排序完以后前key。比如 top K3 加这个指标,意思在这个指标下,每一个时间序列排名前三的,不能要每一个时间序列,而是所有时间序列当中值排名前三的。irate 叫高灵敏度函数,它是一个用于计算指标的瞬时速率。它用于时间范围内的最后一个值减去前一个来计算,而不是所有值,所以叫最后两个样本进行计算。所以相对于irate函数,irate更适用于短期时间范围,只 2 个小时计算没有意义,通常计算 2 分钟内的,这是 counter 常用的几个函数。还有 increase,increase,有点叫极差的概念。你指定一个范围内,它用最大值减去最小值,叫增长多少,所以叫increase,名称叫极差。这都是统计学当中的一些基本概念。班里面有没有同学学习统计学,如果有,可以把统计学的概念给大家解释比如什么叫极查,方差,标准差,什么叫回归。如果有,我建议各位把人自发找出来给大家解释,这对我们学监控作用很大。后面 gauge ,用于存储机制,可增可减,所以常用于求和取平均值、最小值、最大值等聚合计算。也可以使用 PROM QL 的叫 predict the liner,叫线性回归来做预测,还可以使用 Delta 函数。我们解释这两个函数, predict the linear 函数可以预测时间,序列在v,这是序列 v ,在指定时间后的值。它通过线性回归的方式来预测样本数据的变化趋势。比如我可以这里叫磁盘的文件系统,比如是取得某个文件系统的已用空间,或者叫空闲空间。我们对它做线性回归计算。如 5 天以后,这里 t 叫 5 天,意思就是计算文件系统的空闲空间。 5 天以后还有多少。你可以选 5 天以后小于0,或者以 5 天以后小于1。假如自己单位,要取出来看单位是多大,如果单位是 G, 就小于1,就表示 5 天以后只剩 1G ,这个时候只剩 1G 时应该报警。所以指的意思我们可以预测,但这种预测一般不准。你文件系统虽然只剩 1 个 g ,但是半年不写一个数据进去,这种报警就没有什么作用,所以大家都明白,半年不写一个数据,这种线性违规分析,它可能也不会报警,delta表示计算范围向量中的每个时间序列值的最后一个值,第一个值,每个时间序列的第一个值与最后一个值的差,从而展示出不同时间序列上样本值的差值,其实就是极差。delta来返回所有时间序列,因为这是个选择器,返回所有时间范围内的所有时间序列的极差。因此你看 Delta CPU temple serious cell say the cells。它意思就是指返回 CPU 的温度的,这就能取开主机上的 CPU 温度。 2H 表示什么?表示现在 CPU 温度和两个小时之间的 CPU 温度有什么区别?有多大?给它计算出。这对我们分析很重要。比如HTTP 服务器,它计算 HTTP 请求,你可以算 HTTP 请求。或者看你要是个日志文件,它可以算你的日志文件大小。日志文件现在跟 2 小时之前看看这日志文件差别有多大。日志文件增长了 2 k,再过一会增长了5K,再过一会,每两小时增长100K,再过个半月,每两个小时增加 1 个g。这说明我们访问量越来越大,通过文件的分析大小差值,我们就能得出来我的网站访问量是不是足够大,而且异常值。比如我的网站被别人做 DDoS 攻击。我们过去计算出的结果就是日志增长量,每两个小时增加平均 10K 。突然间有一会它的增加量两个小时,跟 2 时之前比较是 20 个g,能分析出来你的网站一定遭攻击。这叫delta。
文章
存储  ·  Prometheus  ·  监控  ·  Cloud Native  ·  关系型数据库  ·  MySQL  ·  网络安全  ·  开发者
2023-02-04
1 2 3 4 5 6 7 8 9
...
20
跳转至:
阿里云开发者学堂
129593 人关注 | 7309 讨论 | 12049 内容
+ 订阅
  • 【开发者7日学】求职达人训练营上线啦~快来打卡赢好礼
  • 开发者5日学【消息队列全家桶产品训练营】上线 快来 APP打卡赢积分
  • 开发者社区答题闯关赛12月期榜单公布啦!
查看更多 >
数据库
252583 人关注 | 50737 讨论 | 94862 内容
+ 订阅
  • 阿里云国际版账号注册常见问题汇总
  • 阿里云国际站一级分销商,只需一个邮箱即可注册国际账号,可代充值
  • 记CentOS7.6 zabix5.0-0 —agent2监控Mysql数据库
查看更多 >
开发与运维
5622 人关注 | 131425 讨论 | 301869 内容
+ 订阅
  • 记CentOS7.6 zabix5.0-0 —agent2监控Mysql数据库
  • 【算法日记】快速幂:关于我知道答案却做不出来这档事
  • 【Java实用技术】java中关于整数的几个冷知识,总有一个你不知道
查看更多 >
云原生
233929 人关注 | 11329 讨论 | 45277 内容
+ 订阅
  • 淘宝小游戏背后的质量保障方案
  • 天猫汽车商详页的SSR改造实践
  • Logback基本使用
查看更多 >
安全
1191 人关注 | 23954 讨论 | 81266 内容
+ 订阅
  • 阿里云国际版账号注册常见问题汇总
  • 阿里云国际站注册下单流程
  • 阿里云国际站版账号购买云服务器:国际阿里云分销商,注册USDT充值教程
查看更多 >