• 总结:Prometheus存储


    一、介绍

    prometheus 提供了本地存储(TSDB)时序型数据库的存储方式,在2.0版本之后,压缩数据的能力得到了大大的提升(每个采样数据仅仅占用3.5byte左右空间),单节点情况下可以满足大部分用户的需求,但本地存储阻碍了prometheus集群化的实现,因此在集群中应当采用 其他时序性数据来替代,比如influxdb。

    prometheus 分为三个部分,分别是:抓取数据存储数据查询数据

    在早期有一个单独的项目叫做 TSDB,但是,在2.1.x的某个版本,已经不单独维护这个项目了,直接将这个项目合并到了prometheus的主干上了。

    二、案例

    我们的prometheus目前申请了三个文件系统NFS,托管集群存在一个文件系统,QKE集群存在另一个文件系统,单都是存储到云端(StorageClass)。

    存储的方式:每个prometheus实例对应一个目录,如果有多个prometheus实例,则对应多个目录。

    另外,注意,每个文件系统对应一个StorageClass自由对象。

    以prometheus托管集群为例,如下是创建StorageClass

     关键的两个文件:

    创建StorageClass资源对象:

    1. kind: StorageClass
    2. apiVersion: storage.k8s.io/v1
    3. metadata:
    4. name: prometheus-data-03
    5. provisioner: prometheus-data-03/nfs
    6. reclaimPolicy: Retain

    创建StorageClass后,还需要K8S存储插件进行真正的存储工作:

    nfs-client-provisioner 可动态为kubernetes提供pv卷,是Kubernetes的简易NFS的外部provisioner,本身不提供NFS,需要现有的NFS服务器提供存储。持久卷目录的命名规则为:${namespace}-${pvcName}-${pvName}。

    树莓派k8s集群安装nfs-client-provisioner_崔一凡的技术博客_51CTO博客

    1. kind: Deployment
    2. apiVersion: apps/v1
    3. metadata:
    4. name: nfs-provisioner-03
    5. spec:
    6. selector:
    7. matchLabels:
    8. app: nfs-provisioner-03
    9. replicas: 1
    10. strategy:
    11. type: Recreate
    12. template:
    13. metadata:
    14. labels:
    15. app: nfs-provisioner-03
    16. spec:
    17. serviceAccount: nfs-provisioner
    18. containers:
    19. - name: nfs-provisioner
    20. image: docker-registry.xxx.virtual/hubble/nfs-client-provisioner:v3.1.0-k8s1.11
    21. volumeMounts:
    22. - name: nfs-client-root
    23. mountPath: /persistentvolumes
    24. env:
    25. - name: PROVISIONER_NAME
    26. value: prometheus-data-03/nfs
    27. - name: NFS_SERVER
    28. value: hubble-587ceb02-5e85e802.cnhz1.qfs.xxx.storage
    29. - name: NFS_PATH
    30. value: /hubble-wuhan-lkg
    31. volumes:
    32. - name: nfs-client-root
    33. nfs:
    34. server: hubble-587ceb02-5e85e802.cnhz1.qfs.xxx.storage
    35. path: /hubble-wuhan-lkg

    上面的server地址其实就是云存储那边提供的地址:

    部署prometheus:

    1. kind: Service
    2. apiVersion: v1
    3. metadata:
    4. name: prometheus-headless
    5. namespace: example-nfs
    6. labels:
    7. app.kubernetes.io/name: prometheus
    8. spec:
    9. type: ClusterIP
    10. clusterIP: None
    11. selector:
    12. app.kubernetes.io/name: prometheus
    13. ports:
    14. - name: web
    15. protocol: TCP
    16. port: 9090
    17. targetPort: web
    18. - name: grpc
    19. port: 10901
    20. targetPort: grpc
    21. ---
    22. apiVersion: v1
    23. kind: ServiceAccount
    24. metadata:
    25. name: prometheus
    26. namespace: example-nfs
    27. ---
    28. apiVersion: rbac.authorization.k8s.io/v1beta1
    29. kind: ClusterRoleBinding
    30. metadata:
    31. name: prometheus-example-nfs
    32. subjects:
    33. - kind: ServiceAccount
    34. name: prometheus
    35. namespace: example-nfs
    36. roleRef:
    37. kind: ClusterRole
    38. name: prometheus
    39. apiGroup: rbac.authorization.k8s.io
    40. ---
    41. apiVersion: apps/v1
    42. kind: StatefulSet
    43. metadata:
    44. name: prometheus
    45. namespace: example-nfs
    46. labels:
    47. app.kubernetes.io/name: prometheus
    48. spec:
    49. serviceName: prometheus-headless
    50. podManagementPolicy: Parallel
    51. replicas: 2
    52. selector:
    53. matchLabels:
    54. app.kubernetes.io/name: prometheus
    55. template:
    56. metadata:
    57. labels:
    58. app.kubernetes.io/name: prometheus
    59. spec:
    60. serviceAccountName: prometheus
    61. securityContext:
    62. fsGroup: 1000
    63. runAsUser: 0
    64. affinity:
    65. podAntiAffinity:
    66. requiredDuringSchedulingIgnoredDuringExecution:
    67. - labelSelector:
    68. matchExpressions:
    69. - key: app.kubernetes.io/name
    70. operator: In
    71. values:
    72. - prometheus
    73. topologyKey: kubernetes.io/hostname
    74. containers:
    75. - name: prometheus
    76. image: docker-registry.xxx.virtual/hubble/prometheus:v2.34.0
    77. args:
    78. - --config.file=/etc/prometheus/config_out/prometheus.yaml
    79. - --storage.tsdb.path=/prometheus
    80. - --storage.tsdb.retention.time=30d
    81. - --web.external-url=/example-nfs/prometheus
    82. - --web.enable-lifecycle
    83. - --storage.tsdb.no-lockfile
    84. - --storage.tsdb.min-block-duration=2h
    85. - --storage.tsdb.max-block-duration=1d
    86. ports:
    87. - containerPort: 9090
    88. name: web
    89. protocol: TCP
    90. livenessProbe:
    91. failureThreshold: 6
    92. httpGet:
    93. path: /example-nfs/prometheus/-/healthy
    94. port: web
    95. scheme: HTTP
    96. periodSeconds: 5
    97. successThreshold: 1
    98. timeoutSeconds: 3
    99. readinessProbe:
    100. failureThreshold: 120
    101. httpGet:
    102. path: /example-nfs/prometheus/-/ready
    103. port: web
    104. scheme: HTTP
    105. periodSeconds: 5
    106. successThreshold: 1
    107. timeoutSeconds: 3
    108. resources:
    109. requests:
    110. memory: 1Gi
    111. limits:
    112. memory: 30Gi
    113. volumeMounts:
    114. - mountPath: /etc/prometheus/config_out
    115. name: prometheus-config-out
    116. readOnly: true
    117. - mountPath: /prometheus
    118. name: prometheus-storage
    119. - mountPath: /etc/prometheus/rules
    120. name: prometheus-rules
    121. - name: thanos
    122. image: docker-registry.xxx.virtual/hubble/thanos:v0.25.1
    123. args:
    124. - sidecar
    125. - --tsdb.path=/prometheus
    126. - --prometheus.url=http://127.0.0.1:9090/example-nfs/prometheus
    127. - --reloader.config-file=/etc/prometheus/config/prometheus.yaml.tmpl
    128. - --reloader.config-envsubst-file=/etc/prometheus/config_out/prometheus.yaml
    129. - --reloader.rule-dir=/etc/prometheus/rules/
    130. env:
    131. - name: POD_NAME
    132. valueFrom:
    133. fieldRef:
    134. fieldPath: metadata.name
    135. ports:
    136. - name: http-sidecar
    137. containerPort: 10902
    138. - name: grpc
    139. containerPort: 10901
    140. livenessProbe:
    141. httpGet:
    142. port: 10902
    143. path: /-/healthy
    144. readinessProbe:
    145. httpGet:
    146. port: 10902
    147. path: /-/ready
    148. volumeMounts:
    149. - name: prometheus-config-tmpl
    150. mountPath: /etc/prometheus/config
    151. - name: prometheus-config-out
    152. mountPath: /etc/prometheus/config_out
    153. - name: prometheus-rules
    154. mountPath: /etc/prometheus/rules
    155. - name: prometheus-storage
    156. mountPath: /prometheus
    157. volumes:
    158. - name: prometheus-config-tmpl
    159. configMap:
    160. defaultMode: 420
    161. name: prometheus-config-tmpl
    162. - name: prometheus-config-out
    163. emptyDir: {}
    164. - name: prometheus-rules
    165. configMap:
    166. name: prometheus-rules
    167. volumeClaimTemplates:
    168. - metadata:
    169. name: prometheus-storage
    170. labels:
    171. app.kubernetes.io/name: prometheus
    172. spec:
    173. storageClassName: prometheus-data-03
    174. accessModes:
    175. - ReadWriteOnce
    176. volumeMode: Filesystem
    177. resources:
    178. requests:
    179. storage: 100Gi
    180. limits:
    181. storage: 300Gi

    --storage.tsdb.min-block-duration:控制数据落盘的时间,即最小落盘时间是2小时

    --storage.tsdb.min-block-duration:控制数据落盘的时间,即最大落盘时间是1天

    --storage.tsdb.retention.time配置本地保留30天数据,减少空间占用;
     

    如上,volumeClaimTemplates即是定义一个PVC,如何创建PV呢?使用StorageClass定义的模板去创建PV。

    那么prometheus查询数据的时候是怎么查的呢?

    其实对于prometheus来说,就是从prometheus这个实例提供的接口查询数据而已,和普通的容器一样,不管是云存储还是node存储或是其他存储,对于容器来说是透明的,都是从挂载到的目录去查询,所以远端对于prometheus来说就是查本地的目录文件。

    三、存储原理

    prometheus将采集到的样本以时间序列的方式保存在内存(TSDB 时序数据库)中,并定时保存到硬盘中。

    与zabbix不同,zabbix会保存所有的数据,而prometheus本地存储会保存15天,超过15天以上的数据将会被删除,若要永久存储数据,有两种方式:

    • 方式一:修改prometheus的配置参数“storage.tsdb.retention.time=10000d”;
    • 方式二:将数据引入存储到Influcdb中。

    prometheus按照block块的方式来存储数据,每2小时为一个时间单位,首先会存储到内存中,当到达2小时后,会自动写入磁盘中。

    为防止程序异常而导致数据丢失,采用了WAL机制,即2小时内记录的数据存储在内存中的同时,还会记录一份日志,存储在block下的wal目录中。当程序再次启动时,会将wal目录中的数据写入对应的block中,从而达到恢复数据的效果。

    当删除数据时,删除条目会记录在tombstones 中,而不是立刻删除。

    prometheus采用的存储方式称为“时间分片”,每个block都是一个独立的数据库。优势是可以提高查询效率,查哪个时间段的数据,只需要打开对应的block即可,无需打开多余数据。

    四、数据备份

    1、完全备份

      备份prometheus的data目录可以达到完全备份的目的,但效率较低。

    2、快照备份

    prometheus提供了一个功能,是通过API的方式,快速备份数据。实现方式:

    • 首先,修改prometheus的启动参数,新增以下两个参数:
    1. --storage.tsdb.path=/usr/local/share/prometheus/data \
    2. --web.enable-admin-api
    • 然后,重启prometheus
    • 最后,调用接口备份:
    1. # 不跳过内存中的数据,即同时备份内存中的数据
    2. curl -XPOST http://127.0.0.1:9090/api/v2/admin/tsdb/snapshot?skip_head=false
    3. # 跳过内存中的数据
    4. curl -XPOST http://127.0.0.1:9090/api/v2/admin/tsdb/snapshot?skip_head=true

     skip_head作用:是否跳过存留在内存中还未写入磁盘中的数据,仍在block块中的数据, 默认是false

    五、数据还原

    利用api方式制作成snapshot后,还原时将snapshot中的文件覆盖到data目录下,重启prometheus即可!

    添加定时备份任务(每周日3点备份)

    1. crontable -e #注意时区,修改完时区后,需要重启 crontab systemctl restart cron
    2. 0 3 * * 7 sudo /usr/bin/curl -XPOST -I http://127.0.0.1:9090/api/v1/admin/tsdb/snapshot >> /home/bill/prometheusbackup.log

  • 相关阅读:
    MySQL基础学习总结(三)
    软件定义汽车,通信连接世界 | 2024汽车软件与通信大会开幕
    OKHttp
    java计算机毕业设计ssm智慧农贸信息化管理平台(源码+系统+mysql数据库+Lw文档)
    【附源码】计算机毕业设计SSM图书销售系统设计
    【异常检测】数据挖掘领域常用异常检测算法总结以及原理解析(一)
    Spring Security整合企业微信的扫码登录,企微的API震惊到我了
    [附源码]计算机毕业设计JAVAjsp宾馆客房管理系统
    vue3 - 开发和生产环境通过Mock模拟真实接口请求
    SPA(单页应用)首屏加载速度慢怎么解决?
  • 原文地址:https://blog.csdn.net/w2009211777/article/details/126014725