作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!


背景

已知:在prometheus中,每个业务节点通过prometheus client API 来在本地汇聚数据。

然后提供HTTP协议,通过 /metrics 路径把业务节点上的metric数据暴露给prometheus.

协议采用文本格式+GZIP压缩,虽然GZIP压缩率比较高,但是文本协议终归还是不够精简。

思路

如何让每个expoter上的数据传输尽可能的精简呢?

  1. 二进制协议
  2. 通过字典来合并重复的字符串
  3. 既然是一次完整的采样,那么时间戳一定都是一样的。只要采用一个时间戳就行了。
  4. 浮点数如果没有小数部分,就按整数来存储;整数采用7bit的变长编码,节约空间。

具体存储格式

序列化后的格式可以表示如下:

message Metric{
map<int32, int32> labels = 1; //用下标来表示字典中存储的第N个字符串
repeated float64 values = 2;
} message Metrics{
bytes gzip_dict = 1; //字典表,经过GZIP压缩
repeated Metric metrics = 2; // 监控数据
int64 global_timestamp = 3; //全局的时间戳
}

运行期的字典,可以表示如下:

type LabelDictForEncode struct{
Data []byte //所有的label name 和 label value顺序存放在大数组中,用\0分割
Labels map[string]int // 每个字符串,指向大数组中的下标
} type LabelDictForDecode struct{
Data []byte //所有的label name 和 label value顺序存放在大数组中,用\0分割
Labels map[int][]byte //下标,指向大数组中的某一段
}

因此,可以把:

foo{label1="value1",label2="value2"}

bar{label1="value1",label2="value3"}

简化为以下字典:

  • foo
  • bar
  • label1
  • label2
  • value1
  • value2
  • value3

    相同的内容越多,压缩的空间越大。

    当然,还可以排序,合并相同前缀……

最后,每个metric只要索引字典里面的值就可以了。

传输前使用ZSTD压缩,占用空间会进一步缩小。

【一个构想】pull方式获取expoter上的数据,如何更加精简?的更多相关文章

  1. HttpClient get和HttpClient Post请求的方式获取服务器的返回数据

    1.转自:https://blog.csdn.net/alinshen/article/details/78221567?utm_source=blogxgwz4 /*  * 演示通过HttpClie ...

  2. ios - 如何获取app上的数据

    做过ios开发的人应该都用过Charles,通常叫它花瓶.Charles是Mac下常用的对网络流量进行分析的工具,类似于Windows下的Fiddler.在开发iOS程序的时候,往往需要调试客户端和服 ...

  3. 获取百度地图POI数据一(详解百度返回的POI数据)

    POI是一切可以抽象为空间点的现实世界的实体,比如餐馆,酒店,车站,停车场等.POI数据具有空间坐标和各种属性,是各种地图查询软件的基础数据之一.百度地图作为国内顶尖的地图企业,其上具有丰富的POI数 ...

  4. 22SpringMvc_jsp页面上的数据传递到控制器的说明

    假设有这个一个业务:在jsp页面上写入数据,然后把这个数据传递到后台. 效果如下:

  5. Amzon MWS API开发之 上传数据

    亚马逊上传数据,现有能操作的功能有很多:库存数量.跟踪号.价格.商品....... 我们可以设置FeedType值,根据需要,再上传对应的xml文件即可. 下面可以看看FeedType类型 这次我们拿 ...

  6. 如何判断一个C++对象是否在堆栈上(通过VirtualQuery这个API来获取堆栈的起始地址,然后就可以得到答案了),附许多精彩评论

      昨天有人在QQ群里问到如何判断一个C++对象是否在堆栈上, 我在网上搜索了下, 搜到这个么一个CSDN的帖子http://topic.csdn.net/t/20060124/10/4532966. ...

  7. 获取UILabel上最后一个字符串的位置。获取文字长度和高度,自动换行

    //行的高度. -(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPat ...

  8. 获取第上一个兄弟元素 屏蔽浏览器的差异(PreviousElementSibling)

    //获取element上一个兄弟元素 function getPreviousElementSibling(element){ //能力检测 判断是否支持PreviousElementSibling ...

  9. 大一C语言学习笔记(11)---编程篇--写一个程序,可以获取从键盘上输入的的三个数,并能够判断是否可以以这三个数字作为边长来构成一个三角形,如果可以的话,输出此三角形的周长及面积,要求 0 bug;

    考核内容: 写一个程序,可以获取从键盘上输入的的三个数,并能够判断是否可以以这三个数字作为边长来构成一个三角形,如果可以的话,输出此三角形的周长及面积: 答案: #include<stdio.h ...

  10. 使用IO映射的方式获取tiny4412板子上的ID号

    在以前的文章中,有一篇 基于ARM-contexA9-Linux驱动开发:如何获取板子上独有的ID号 在那篇文章中,具体可以参考.那时候我使用了简单的字符设备驱动框架,最终的ID号通过read方法可将 ...

随机推荐

  1. Solon v1.9.1,让 Java 快速启动

    相对于 Spring Boot 和 Spring Cloud 的项目: 启动快 5 - 10 倍. (更快) qps 高 2- 3 倍. (更高) 运行时内存节省 1/3 ~ 1/2. (更少) 打包 ...

  2. explain分析

    explain分析字段:id.select_type.type.partitions.type.possible_keys.key.key_len.ref.rows.rows.filtered.ext ...

  3. C++11实用特性1

    1 原始字面量 有时候在输出一个路径字符串时,编译器会将其中的部分内容识别成转义字符进行输出,可以用R "xxx(原始字符串)xxx"其中()两边的字符串可以省略.原始字面量R可以 ...

  4. Go--较复杂的结构类型

    一.List List是一种有序的集合,可以包含任意数量的元素.与数组相比,list的长度可以动态调整,可以随时添加或删除元素,类似于切片 在go中,List是一个双向链表的实现. 实例 packag ...

  5. 【驱动】串口驱动分析(三)-serial driver

    简介 前两节我们介绍串口驱动的框架和tty core部分.这节我们介绍和硬件紧密相关的串口驱动部分. UART驱动部分依赖于硬件平台,而TTY驱动和具体的平台无关.虽然UART部分依赖于平台,但是不管 ...

  6. C# 用树形列表 动态 显示菜单

    如图 页面加载 private void Form1_Load(object sender, EventArgs e) { GetMenu(treeView1, menuStrip1);//将menu ...

  7. longjmp 使 C++ RAII 失效

    C 语言的 longjmp 没有进行栈展开,而是直接跳转.从 longjmp 到 setjmp 之间的所有析构函数都没有调用,也就是 RAII 失效. #include <setjmp.h> ...

  8. socket TCP DPT 网络编程

    复习: ARP协议: 广播和单播 通过ip地址获得mac地址 机器A发起一个arp请求(只包含A的ip地址) 交换机接收到请求,广播这条消息 所有的机器都会接受到这条请求,只有需要寻找的机器B的ip地 ...

  9. RL 基础 | 如何搭建自定义 gym 环境

    需实现的方法: __init__(self): 需定义 action_space 和 observation_space,使用 space.Box 之类来表示(from gym import spac ...

  10. Elasticsearch 索引与文档的常用操作总结二:复杂条件查询

    本文为博主原创,未经允许不得转载: 1.  查询所有:match_all GET /es_db/_doc/_search { "query":{ "match_all&q ...