Meta

Meta 数据存储的是系统的内部信息,比如用户信息、数据库信息、RP 信息、shard 的元数据、CQ、subscription 等。相关的配置有:

[meta]
dir = ""
retention-autocreate = true
logging-enabled = true

数据结构

Meta 数据格式是一种多层的结构,底层(通讯层)是通过 Protobuf 的方式描述的,对于单节点的 InfluxDB,通过 Protobuf 协议与磁盘交互。

DAO 层数据格式定义见 meta.proto,下面给出了最外层的数据定义,可见主要存储的是节点、数据库、用户、Shard 等信息。

// services/meta/internal/meta.proto
message Data {
    required uint64 Term = 1;
    required uint64 Index = 2;
    required uint64 ClusterID = 3;

    repeated NodeInfo Nodes = 4;
    repeated DatabaseInfo Databases = 5;
    repeated UserInfo Users = 6;

    required uint64 MaxNodeID = 7;
    required uint64 MaxShardGroupID = 8;
    required uint64 MaxShardID = 9;

    // added for 0.10.0
    repeated NodeInfo DataNodes = 10;
    repeated NodeInfo MetaNodes = 11;
}

// COMMANDS 相关
...

业务层(DTO)数据格式大致与 DAO 类似,两者提供了相互转换的方法,即种 Struct 都有对应的 marshal 和 unmarshal 方法:

Client

client 是 Meta 模块暴露出去的接口,外部对 Meta 数据的所有操作都通过 Client,Client 在服务启动的时候初始化:

下面是系统初始化时,新建 Client 的调用栈:

Server 代表一个 InfluxDB 进程,里面包含一个 MetaClient 的 field,这个 MetaClient 会暴露给各个模块使用。

下面我们:加载数据 => 查询数据 => 更新数据 => 持久化数据 的逻辑来看 Client 是怎么实现的

加载数据

Server 初始化 MetaClient 后,立即调用 MetaClient 的 Open 方法,Open 方法会加载磁盘的上的 meta 目录,通过 protobuf 反序列化成 DAO 层的 data,然后再转换成 DTO 层的 data:

查询数据

数据从磁盘加载进来后会提供给各个模块查询,Client 有很多查询方法,这里不一一列出了。查询逻辑比较简单,下面只给出一些例子:

更新数据

这里个更新数据包括删除 database、创建用户等各种操作。为了保证数据一致性,这里实现采用复制一份数据的方式,即每次更新数据时都会先复制一份,然后更新复制出来的数据,最后替换老的数据。

绝大部分更新操作都采用如下范式:

比如创建 database、创建 shard group,见如下代码:

持久化数据

持久化操作在两种场景会触发:

  • 各种更新操作,见上节。

  • 在初始化 Client 的时候,若这个节点的 Raft Index 是 1,则会立即持久化。

持久化的逻辑也比较简单:

  • 创建临时文件

  • 通过 protobuf 协议把内存结构的数据转换成字节数组

  • 字节数组写入文件

  • 把临时文件更新为正式文件

Last updated

Was this helpful?