先说结论

  • vm-insert与vm-storage之间采用极其简单的通讯协议

    • 对于简单的场景,越简单性能越高
    • vm-insert连接到vm-storage后,先发送字符串vminsert.02,vm-storage收到后回复字符串ok,然后握手成功
    • vm-insert发送一个字节的压缩标志给vm-storage:1.默认会启用zstd压缩算法;2.除非命令行中使用-rpc.disableCompression来禁止压缩
    • 通讯协议使用:固定字节表示长度 + ZSTD压缩内容
      • ZSTD的压缩解压缩速度比最快的snappy稍慢,但是压缩率比zlib还要高。
    • 通讯协议看起来是单工的————也就是说,是请求-响应模式;无法在一个TCP通道上做到多个请求+响应。(为了简单嘛,也能理解)
    • 通讯的回包也极其简单:返回1代表成功,返回2代表存储节点只读。
  • 序列化方面:
    • vm-insert中:直接在一个buffer里面追加内容
    • 每个字段使用 length + value的形式
    • 因此序列化很快(从占用空间的维度说,并不见得比PB更好)
  • 高数据压缩比:
    • 从之前的监控数据统计来看,vm-insert进来的数据和发送到vm-storage的数据相差29倍
    • 简单协议+自定义序列化+合并发送+zstd压缩,最终达到了这个效果,牛逼
  • 合并发送:
    • vm-insert的每个http处理handle中,每个请求的所有metrics先序列化到context的buffer中
    • 然后放到connection对象的buffer中
    • connection对象的buffer达到一定长度后,进行压缩,然后发送给storage
    • 有坑:vm-insert转发到vm-storage必然有一定时间的延迟;且vm-insert突然崩溃的话,必然丢失部分数据。
      • 在监控数据极少的情况下,会不会一直等待?还没有看到对这种情况的处理。
  • 并发的处理:
    • http handle部分的处理是并行的,放到connection的buffer的时候加锁了(还有挺多细节没看明白)
  • vm-storage的寻址:
    • 对所有的label_name + label_value + projectid + accountid进行了hash运算
    • 使用了性能吊炸天的xxhash库
    • 使用uint64的hashcode,然后通过hash一致性算法,取得后端多个storage节点的下标
    • 因此:同一个time series被固定的发到一个后端节点上。storage节点的增加和减少只影响部分time series
    • 理论上可以修改源码,比如只对__name__取hashcode,这样的话,同一个监控项会被发到同一个存储节点上
  • 后端容灾的处理:
    • 如果发送给vm-storage失败,会对数据反序列化,然后重新计算hashcode,然后重新选vm-storage节点。

      • 新增vm-storage只能重启vm-insert,因此不存在对新服务发现的需要
    • vm-storage节点的侦测、迁移、恢复的逻辑,还没看到。

【源码阅读】vm-insert与vm-storage之间的通讯的更多相关文章

  1. 【源码阅读】Java集合之一 - ArrayList源码深度解读

    Java 源码阅读的第一步是Collection框架源码,这也是面试基础中的基础: 针对Collection的源码阅读写一个系列的文章,从ArrayList开始第一篇. ---@pdai JDK版本 ...

  2. parseInt的源码阅读

    parseInt的源码阅读 Integer.parseInt()这个方法的功能小巧又实用,实现起来困难不大,没有很复杂.这里就来看一下Java的源码是怎么写的吧,走一边大婶写过的代码,应该会有点收获吧 ...

  3. 转-OpenJDK源码阅读导航跟编译

    OpenJDK源码阅读导航 OpenJDK源码阅读导航 博客分类: Virtual Machine HotSpot VM Java OpenJDK openjdk 这是链接帖.主体内容都在各链接中.  ...

  4. openjdk源码阅读导航

    转自:http://rednaxelafx.iteye.com/blog/1549577 这是链接帖.主体内容都在各链接中. 怕放草稿箱里过会儿又坑掉了,总之先发出来再说…回头再慢慢补充内容. 先把I ...

  5. avalon源码阅读(1)

    来源 写angularJS源码阅读系列的时候,写的太垃圾了. 一个月后看,真心不忍直视,以后有机会的话得重写. 这次写avalonJS,希望能在代码架构层面多些一点,少上源码.多写思路. avalon ...

  6. Sping学习笔记(一)----Spring源码阅读环境的搭建

    idea搭建spring源码阅读环境 安装gradle Github下载Spring源码 新建学习spring源码的项目 idea搭建spring源码阅读环境 安装gradle 在官网中下载gradl ...

  7. JDK源码阅读-------自学笔记(一)(java.lang.Object重写toString源码)

    一.前景提要 Object类中定义有public String toString()方法,其返回值是 String 类型. 二.默认返回组成 类名+@+16进制的hashcode,当使用打印方法打印的 ...

  8. JDK源码阅读-FileInputStream

    本文转载自JDK源码阅读-FileInputStream 导语 FileIntputStream用于打开一个文件并获取输入流. 打开文件 我们来看看FileIntputStream打开文件时,做了什么 ...

  9. JDK源码阅读-FileDescriptor

    本文转载自JDK源码阅读-FileDescriptor 导语 操作系统使用文件描述符来指代一个打开的文件,对文件的读写操作,都需要文件描述符作为参数.Java虽然在设计上使用了抽象程度更高的流来作为文 ...

  10. JDK源码阅读-Reference

    本文转载自JDK源码阅读-Reference 导语 Java最初只有普通的强引用,只有对象存在引用,则对象就不会被回收,即使内存不足,也是如此,JVM会爆出OOME,也不会去回收存在引用的对象. 如果 ...

随机推荐

  1. CF1057B DDoS 题解

    Content 有一个长度为 \(n\) 的数列 \(a_1,a_2,...,a_n\),求出满足 \(\sum\limits_{i=l}^r a_i>100\times(r-l+1)\) 的区 ...

  2. java IO操作和计算操作:工作内存和主内存 volatile关键字作用;原子操作对象AtomicInteger ....

    应该停止但无法停止的计算线程 如下线程示例,线程实例中while循环中的条件,在主线程中通过调用实例方法更新后,while循环并没有更新判断变量是否还成立.而是陷入了while(true)死循环. i ...

  3. UE4之第一个飞机游戏

    开始之前 UE4官网 初识ue4教程(1~9节): https://www.bilibili.com/video/BV164411Y732?p=1 第一个飞机游戏: http://www.sikied ...

  4. 【LeetCode】Balanced Binary Tree 算法优化 解题报告

    Balanced Binary Tree Better Solution [LeetCode] https://leetcode.com/submissions/detail/40087813/ To ...

  5. 【LeetCode】723. Candy Crush 解题报告 (C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 暴力 日期 题目地址:https://leetcode ...

  6. 【LeetCode】438. Find All Anagrams in a String 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 滑动窗口 双指针 日期 题目地址:https://l ...

  7. javascript原始值和引用值类型及区别

    原始值和引用值类型及区别 首先,原始值和引用值类型都是js中的数据类型,为了充分利用存储空间,定义了不同的数据类型,而且js是弱类型,动态语言,数据类型可变. 原始值(简单数据类型) 存储在栈中的简单 ...

  8. 问题--ImportError: DLL load failed: 找不到指定的模块

    今天在运行别人的项目时出现了问题: ImportError: DLL load failed: 找不到指定的模块. 解决方法: 卸载后重新安装. 详情参考: Python报错:ImportError: ...

  9. 从头造轮子:python3 asyncio 之 run(2)

    前言 书接上文,本文造第二个轮子,也是asyncio包里面非常常用的一个函数run 一.知识准备 ● 相对于run_until_complete,改动并不大,就是将入口函数重新封装了一下,基础知识主要 ...

  10. 使用.NET 6开发TodoList应用(16)——实现查询排序

    系列导航及源代码 使用.NET 6开发TodoList应用文章索引 需求 关于查询的另一个需求是要根据前端请求的排序字段进行对结果相应的排序. 目标 实现根据排序要求返回排序后的结果 原理与思路 要实 ...