Skip to content

Tutorial v2.4.7

chengshiwen edited this page Jun 24, 2021 · 2 revisions

Influx Proxy 说明文档 v2.4.7

Influx Proxy 是一个基于高可用、一致性哈希的 InfluxDB 集群代理服务,实现了 InfluxDB 高可用集群的部署方案,具有动态扩/缩容、故障恢复、数据同步等能力。连接到 Influx Proxy 和连接原生的 InfluxDB Server 没有显著区别 (支持的查询语句列表),对上层客户端是透明的,上层应用可以像使用单机的 InfluxDB 一样使用,Influx Proxy 会处理请求的转发,并对各个 InfluxDB 集群节点进行管理。Influx Proxy 基于饿了么开源的 Influx-Proxy,并进一步开发和优化,支持了更多的特性,移除了 Python、Redis 依赖,解决了需要额外配置 KEYMAPS 、数据负载不均衡的问题。

目录

架构

image/architecture.png

架构示例

  • client:influxdb-java、influxdb-shell (influx)、curl、浏览器等客户端
  • load balance:负载均衡,如 F5、Nginx、LVS、HAProxy 等
  • influx-proxy:influx-proxy 实例,架构示意图部署了两个 influx-proxy 实例
  • circle:一致性哈希环(circle),一个 circle 包含了若干个 influxdb 实例,共同存储了一份全量的数据,即每个 circle 都是全量数据的一个副本,各个 circle 数据互备。不同 circle 不能包含相同 influxdb 实例,每个 circle 包含的 influxdb 实例个数可以不相等。circle 只是一种逻辑划分,无实体存在,架构示意图配置了三个 circle
  • influxdb:influxdb 实例,以 url 进行区分,可以部署在同一服务器上以不同端口运行多个实例,一个 influxdb 实例只存储了一份全量数据的一部分数据

原理

设计原理

一致性哈希原理

原理文章:一致性Hash(Consistent Hashing)原理剖析

  • 一致性哈希算法解决了分布式环境下机器扩缩容时,简单的取模运算导致数据需要大量迁移的问题
  • 一致性哈希算法能达到较少的机器数据迁移成本,实现快速扩缩容
  • 通过虚拟节点的使用,一致性哈希算法可以均匀分担机器的数据负载

一致性哈希 circle 设计

  • 一个 circle 是一个逻辑上的一致性哈希环,包含少数的物理节点和更多数的虚拟节点
  • 一个 circle 中的所有 influxdb 实例对应了这个一致性哈希环的物理节点

数据存储位置

  • 每个 circle 维护了一份全量数据,一个 influxdb 实例上的数据只是从属 circle 数据的一部分
  • 每个 circle 数据存储位置计算:
    db,measurement + influxdb实例列表 + 一致性哈希算法 => influxdb实例
    
  • influxdb实例列表不发生改变时,db,measurement将只会唯一对应一台influxdb实例
  • influxdb实例列表发生改变时,需要对少量机器数据进行迁移,即 重新平衡 (rebalance)

请求流程

写请求

  • client 请求 load balance 地址
  • load balance 根据负载均衡算法选择一个 influx-proxy 转发请求
  • influx-proxy 收到请求,根据请求中 db 和 measurement 信息,每个 circle 使用一致性哈希算法计算出一个 influxdb 实例,并将请求转发给这些 influxdb 实例
  • influxdb 实例处理请求,写入数据
  • 若存在 influxdb 实例宕掉,或者网络、存储故障导致无法 influxdb 无法写入,则 influx-proxy 会将数据写入到缓存文件中,并直到 influxdb 实例恢复后重新写入

读请求

  • client 请求 load balance 地址
  • load balance 根据负载均衡算法选择一个 influx-proxy 转发请求
  • influx-proxy 收到请求,选择一个所有 influxdb 实例都正常运行、状态健康的 circle
  • 若请求中带有 db 和 measurement 信息,该 circle 使用一致性哈希算法计算出一个 influxdb 实例,并将请求转发给这个 influxdb 实例;若请求中只带有 db 信息,则判断为数据库相关的集群查询语句,并将请求转发给该 circle 的所有 influxdb 实例
  • influxdb 实例处理请求,读出数据,返回给 influx-proxy
  • 若是单个实例返回数据,则直接返回 client;若是多个实例返回数据,则合并后返回 client

特性

  • 支持 query 和 write
  • 支持部分集群 influxql
  • 过滤了部分危险的 influxql
  • 集群对上层客户端透明,如同单机 InfluxDB 访问
  • 支持写入失败时将数据缓存到文件,然后重写
  • 支持数据库分库存储,基于一致性哈希
  • 支持动态扩/缩容、故障恢复、数据同步等工具
  • 部署简单,只有二进制程序和配置文件
  • 支持写数据时附带 precision 参数
  • 支持 influxdb-java, influxdb shell and grafana 接入
  • 支持认证和 https,支持 influxdb 认证和 https
  • 支持认证信息加密
  • 支持 /health 负载健康状态查询
  • 支持数据库白名单限制
  • 支持 gzip
  • 支持版本信息显示

用法

$ ./influx-proxy -h
Usage of ./influx-proxy:
  -config string
      proxy config file (default "proxy.json")
  -version
      proxy version

版本信息显示:

$ ./influx-proxy -version
Version:    2.4.7
Git commit: 83b8c73
Go version: go1.10.8
Build time: 2020-05-12 18:53:29
OS/Arch:    linux/amd64

程序启动命令:

$ ./influx-proxy -config proxy.json
2020/05/12 17:53:44.317711 proxy.go:132: 2 circles loaded from file
2020/05/12 17:53:44.317799 proxy.go:134: circle 0: 2 backends loaded
2020/05/12 17:53:44.317804 proxy.go:134: circle 1: 2 backends loaded
2020/05/12 17:53:44.317808 proxy.go:136: hash key: idx
2020/05/12 17:53:44.317818 proxy.go:138: db list: [db1 db2]
2020/05/12 17:53:44.319154 main.go:57: http service start, listen on :7076

配置

配置示例

一份配置文件示例如下,采用 JSON 格式:

{
    "circles": [
        {
            "name": "circle-1",
            "backends": [
                {
                    "name": "influxdb-1-1",
                    "url": "http://127.0.0.1:8086",
                    "username": "",
                    "password": ""
                },
                {
                    "name": "influxdb-1-2",
                    "url": "http://127.0.0.1:8087",
                    "username": "",
                    "password": ""
                }
            ]
        },
        {
            "name": "circle-2",
            "backends": [
                {
                    "name": "influxdb-2-1",
                    "url": "http://127.0.0.1:8088",
                    "username": "",
                    "password": ""
                },
                {
                    "name": "influxdb-2-2",
                    "url": "http://127.0.0.1:8089",
                    "username": "",
                    "password": ""
                }
            ]
        }
    ],
    "listen_addr": ":7076",
    "db_list": ["db1", "db2"],
    "data_dir": "data",
    "mlog_dir": "log",
    "hash_key": "idx",
    "vnode_size": 256,
    "flush_size": 10000,
    "flush_time": 1,
    "check_interval": 1,
    "rewrite_interval": 10,
    "write_timeout": 10,
    "idle_timeout": 10,
    "log_enabled": false,
    "username": "",
    "password": "",
    "auth_secure": false,
    "https_enabled": false,
    "https_cert": "",
    "https_key": ""
}

配置约定

  • 零值定义:
    • 整数的零值:0,字符串的零值:"" (空字符串),布尔值的零值:false,列表的零值:[]
  • 字段 未出现 在配置文件中:
    • 以下字段说明中没有提及默认值的字段,若没有出现在配置文件中,程序将使用零值

字段说明

  • circles: circle 列表
    • name: circle 名称,要求不同 circle 名称不同,必填
    • backends: circle 包含的 influxdb 后端实例列表,必填
      • name: 实例名称,要求不同后端实例名称不同,必填
      • url: 实例 url,支持 https 协议,必填
      • username: 实例认证用户,若 auth_secure 开启则启用认证加密,空表示实例无认证
      • password: 实例认证密码,若 auth_secure 开启则启用认证加密,空表示实例无认证
  • listen_addr: proxy 监听地址: ip:port,一般不绑定 ip,默认为 :7076
  • db_list: 允许访问的 db 列表,空表示不限制 db 访问,默认为 []
  • data_dir: 保存缓存数据的目录,存放 .dat 和 .rec 文件,默认为 data
  • mlog_dir: 用于记录重新平衡、故障恢复、数据同步、错误数据清除的日志目录,默认为 log
  • hash_key: 配置一致性哈希算法的 key,可选值为 idxnameurl,分别使用 backend 实例的索引 index、name、url 的值进行 hash,默认值为 idx
    • 一旦 hash_key 设定,尽量不要变更,否则需要 rebalance
    • 若 backend 实例的 index、name、url 的值发生变更,也会导致 hash 策略发生变化,从而需要 rebalance,如新增 backend 实例、name 变更、url 从 http 协议变成 https 协议等,默认值 idx 会使得一致性哈希更加稳定,从而减少 rebalance
    • v2.4.1 版本及之前没有 hash_key 配置,默认采用 url 哈希策略
    • v2.4.2 开始支持 hash_key,支持 nameurl 可选值,默认值为 url
    • v2.4.4 开始,hash_key 支持 idxnameurl 可选值,默认值为 idx
      • 升级版本务必注意显示配置为 url ,以支持老版本采用的 url 哈希策略
  • vnode_size: 一致性哈希环的虚拟节点数量,默认为 256
  • flush_size: 写数据时缓冲的最大点数,达到设定值时将一次性批量写入到 influxdb 实例,默认为 10000
  • flush_time: 写数据时缓冲的最大时间,达到设定值时即使没有达到 flush_size 也进行一次性批量写入到 influxdb 实例,单位为秒,默认为 1
  • check_interval: 检查 influxdb 后端实例是否存活的间隔时间,默认为 1
  • rewrite_interval: 向 influxdb 后端实例重写缓存失败数据的间隔时间,默认为 10
  • write_timeout: 向 influxdb 后端实例写数据的超时时间,默认为 10
  • idle_timeout: 服务器 keep-alives 的等待时间,默认为 10
  • log_enabled: 是否开启 debug 日志信息用于故障排查,默认为 false
  • username: proxy 的认证用户,若 auth_secure 开启则启用认证加密,空表示不启用认证
  • password: proxy 的认证密码,若 auth_secure 开启则启用认证加密,空表示不启用认证
  • auth_secure: 是否启用认证加密,即用户和密码是否为加密后的字符串,默认为 false
  • https_enabled: 是否启用 https,默认为 false
  • https_cert: ssl 证书路径,https_enabled 开启后有效
  • https_key: ssl 私钥路径,https_enabled 开启后有效

查询语句

不支持语句

  • ALTER
  • GRANT
  • REVOKE
  • KILL
  • SELECT INTO
  • 多个语句,以分号(;)分隔

支持语句

  • select from
  • show from
  • show measurements
  • show series
  • show field keys
  • show tag keys
  • show tag values
  • show retention policies
  • show stats
  • show databases
  • create database
  • drop database
  • delete from
  • drop series from
  • drop measurement
  • on clause,当 http 接口 /query 设置了 db 参数时,db 参数优先级更高

InfluxDB-Java 使用规范

InfluxDB Java 客户端:influxdb-java 2.5+,使用示例如下,兼容 influx-proxy 和 influxdb 查询:

image/java-code.png

涉及 CREATEDELETEDROP 语句,请务必使用 POST 方式,Query 构造函数第三个参数需要设置为 true,否则可能会导致语句执行不成功:

Query(final String command, final String database, final boolean requiresPost)

官方文档:/query HTTP endpoint

方法 查询类型
GET 用于所有以以下子句开头的查询:SELECT (不包括 SELECT INTO), SHOW
POST 用于所有以以下子句开头的查询:ALTER, CREATE, DELETE, DROP, GRANT, KILL, REVOKE, SELECT INTO

部署

以下适用于生产环境

部署方式

  • 架构:
    • 使用负载均衡,部署至少两个 influx proxy,推荐两个 influx proxy 的方案
    • 使用至少两个 circle,推荐两个 circle 的方案
    • 每个 circle 的 influxdb 实例数量根据实际数据情况进行配置,参考硬件资源建议至少三个
  • 存储:
    • 使用网络共享存储,如 NAS、SAN 等,避免服务器故障无法恢复、导致数据丢失的问题
    • 建议 SSD 固态硬盘,提升硬盘读写 IOPS;HDD 机械硬盘会导致 IOPS 降低、性能下降
    • 涉及存储:influxdb 实例持久化数据、influx-proxy 实例写入失败的缓存文件数据

硬件资源

官方指南

官方给出单机单节点 InfluxDB 性能测试数据参考

CPU 内存 IOPS 每秒写入 每秒查询* 唯一series
2-4 核 2-4 GB 500 <5,000 <5 <100000
4-6 核 8-32 GB 500-1000 <250000 <25 <1000000
8+ 核 32+ GB 1000+ >250000 >25 >1000000

* 每秒查询指中等查询,查询对系统的影响差异很大,查询复杂度由以下条件定义:

查询复杂度 标准
简单 很少或没有函数,也没有正则表达式
时间限制为几分钟,几小时或最多24小时
通常在几毫秒到几十毫秒内执行
中等 具有多种函数和一两个正则表达式
也可能有GROUP BY子句或对采样时间范围为几个星期的数据
通常在几百或几千毫秒内执行
复杂 具有多个聚合或转换函数或多个正则表达式
可能会采样时间范围为几个月或几年的数据
通常需要几秒钟才能执行

资源建议

  • 预估每秒写入的总数据量、每秒查询的总请求数,建议单台每秒写入不超过 250000
  • 确定一个合适的单节点每秒写入量,根据每秒写入的总数据量,大致确定单台机器硬件资源配置
  • 计算出每个 circle 大致需要的 influxdb 实例的个数,并增加一定冗余机器

运行方式

  • 二进制:通过 supervisord、systemd、upstart 管理
  • docker/k8s:通过镜像部署,自带自启动、重启管理

InfluxDB 部署

版本要求

  • 支持 InfluxDB 1.2 - 1.8,建议使用 1.6+,支持更好基于磁盘的时序数据索引
  • InfluxDB 2.0 beta,尚未对接和测试

配置建议

binary

reporting-disabled = true         # 禁用报告,默认为 false
[meta]
dir = "/var/lib/influxdb/meta"    # 元信息目录
[data]
dir = "/var/lib/influxdb/data"    # 数据目录
wal-dir = "/var/lib/influxdb/wal" # 预写目录
wal-fsync-delay = "10ms"          # SSD 设置为 0s,非 SSD 推荐设置为 0ms-100ms
index-version = "tsi1"            # tsi1 磁盘索引,inmem 内存索引需要大量内存
query-log-enabled = true          # 查询的日志,默认是 true
[coordinator]
write-timeout = "20s"             # 写入请求超时时间,默认为 10s
[http]
log-enabled = true                # http 请求日志,默认是 true
[logging]
level = "info"                    # 日志等级,error、warn、info(默认)、debug

docker/k8s

INFLUXDB_REPORTING_DISABLED=true
INFLUXDB_META_DIR=/var/lib/influxdb/meta
INFLUXDB_DATA_DIR=/var/lib/influxdb/data
INFLUXDB_DATA_WAL_DIR=/var/lib/influxdb/wal
INFLUXDB_DATA_WAL_FSYNC_DELAY=10ms
INFLUXDB_DATA_INDEX_VERSION=tsi1
INFLUXDB_DATA_QUERY_LOG_ENABLED=true
INFLUXDB_COORDINATOR_WRITE_TIMEOUT=20s
INFLUXDB_HTTP_LOG_ENABLED=true
INFLUXDB_LOGGING_LEVEL=info

监控

采用 grafana:5.2.4 对各个 influxdb 实例进行监控,执行导入仪表盘的脚本,将创建监控仪表盘:

image/grafana-monitor.png

监控指标说明:

  • Memory:Sys、Heap Sys、Heap In Use
    • 分配的堆栈数据总内存、堆内存(包含正在使用和未释放的内存)、正在使用的堆内存
  • HTTP Writes、HTTP Queries
    • 每秒写入、查询的请求数,单位为 ops
  • Write Bytes、Query Bytes
    • 每秒写入、查询的数据字节大小
  • Points Written、HTTP Errors
    • 每秒已写入的点数、错误请求数,单位为 ops
  • Number of Series、Number of Measurements
    • Series 和 Measurements 的个数,其大小会直接影响内存使用大小
    • Series 的个数 (不包括 _internal,其为 influxdb 的内部数据库) 对内存影响最大

版本及升级

最新版本

最新稳定版本为 v2.4.7,适用于生产环境,更新日志见后面章节更新日志

版本升级

v2.0-v2.3 升级到 v2.4

  • -config:命令行启动参数由 -proxy 变更为 -config
  • proxy.json:对应字段修改适配到最新版本
    • circles 配置增加字段 name
    • backends 移除 cpu_core
    • fail_data_dir 变更为 data_dir
    • number_of_replicas 变更为 vnode_size
    • backend_buffer_max_num 变更为 flush_size
    • sync_data_time_out 变更为 flush_time
    • proxy_username 变更为 username
    • proxy_password 变更为 password
    • 新增 mlog_dir,支持 rebalance、recovery 和 resync 的迁移日志目录配置
    • 新增 hash_key,配置说明见配置字段说明
    • 新增 check_interval,支持配置后端实例检查存活的间隔时间
    • 新增 rewrite_interval,支持配置后端实例重写数据的间隔时间
    • 新增 write_timeout,支持配置后端实例写数据的超时时间
    • 新增 idle_timeout,支持配置服务器 keep-alives 等待的超时时间
    • 新增 log_enabled,支持输出 debug 日志信息用于故障排查
    • 新增 auth_secure,支持认证加密配置,不启用则使用明文认证的用户和密码
    • 新增 https_enabledhttps_certhttps_key,支持 https 配置
  • db_list:访问 influxdb 实例,执行 show databases 查看数据库列表,更新到 db_list
  • hash_key:修改为 url,保证老版本兼容性
  • auth_secure:若开启了加密认证,需要修改为 true
  • usernamepassword:若开启了加密认证,需要重新生成新加密的用户和密码
    • 加密方法见后面章节 HTTP 接口 /encrypt 说明

常见问题

分布式

  • 分布式系统的三个指标:CAP 定理的含义
    • Consistency:一致性
    • Availability:可用性
    • Partition tolerance:分区容错
  • CAP 定理:C、A、P 三个指标不可能同时达到,其中 P 总是成立
    • 一致性 和 可用性 只能选择其一
    • 只能实现 CP 或 AP
  • influx proxy 实现了可用性,即达到 AP
    • 时序数据能容忍极少数数据丢失或者不一致
    • 可以定期通过数据同步工具达到数据一致性
  • 官方 influxdb 集群也实现了可用性,定期同步数据以解决 脏读问题 (数据读取不一致)

高性能

基于代理方案,数据处理操作较少

  • 写性能:约等于单个 circle 的所有 influxdb 实例的写入性能总和
  • 读性能:约等于所有 circle 的所有 influxdb 实例的查询性能总和

高可用

  • 架构部署方案:
    • 架构参考前面章节架构部署
    • 同时写入多个 circle,查询一个健康可用的 circle
  • influx proxy 故障:
    • 部署两个 proxy,由于无状态,一个 proxy 死掉不会影响另一个 proxy,具备高可用性
    • 若 proxy 在缓存失败数据时死掉,则 proxy 启动时可以重新读取缓存文件数据,恢复重写,写入数据不会丢失
    • 建议使用网络共享存储,避免机器故障完全坏掉导致缓存失败数据丢失
  • influxdb 故障:
    • 若 influxdb 服务死掉或 influxdb 机器坏掉,则其它 circle 仍然能提供写入和查询服务,具备可用性;本 circle 将变成 只写 (write only) 状态,可以继续写入数据、但不能查询,具备写可用性,直到重新运行后,只写状态解除变成读写可用状态
    • 若 influxdb 服务死掉,则 influx proxy 会缓存失败数据,直到 influxdb 重新运行后进行重写,故写入数据不会丢失
    • 若 influxdb 机器完全坏掉,数据不可恢复,则快速补充新机器,所属 circle 将变成 只写 (write only) 状态,直到 influxdb 重新运行后进行重写,同时后台里从其它健康的 circle 进行数据恢复,直到数据恢复完成后,只写状态解除变成读写可用状态
    • 建议使用网络共享存储,避免机器故障、甚至完全坏掉导致数据丢失,进而需要大量时间恢复丢失数据

扩缩容

当 influxdb 实例无法承载当前数据量时,需要扩充新的 influxdb 实例,或者当前所有 influxdb 实例硬件资源严重过剩,需要缩减 influxdb 实例,则需要进行扩缩容操作:

  • 为了高可用性、不停机,扩缩容时请一个 circle 接一个 circle 进行操作
  • 修改 proxy.json,增删实例,配置为扩缩容后的目标配置,重新启动所有的 influx proxy
  • 根据后面章节 HTTP 接口 /rebalance 进行相关操作
  • 指定的 circle 将变成 只写 (write only) 状态,可以继续写入数据、但不能查询,同时后台里进行重新平衡操作,从而不用停机,直到重新平衡完成后,只写状态解除变成读写可用状态
  • 可以通过后面章节 HTTP 接口 /migrate/stats 查询重新平衡进度统计信息
  • 扩容完成后,建议清除迁移之前的旧数据,参考数据清除
  • 备注:rebalance 操作是在一个 circle 内进行数据重新平衡,跟其它 circle 没有关系
  • 备注:如果客户生产环境允许停机,则所有 circle 都可以同时进行扩缩容及 rebalance 操作
  • 备注:目前 rebalance 操作在面对大量数据时,迁移性能较低,花费时间较长,建议以下方案:
    • 方案一:使用官方 influx_inspect export -out 工具导出所有数据,再使用 influx -import -path 导入到 influx proxy,此方案效率会高于 rebalance 操作
      • 存在问题:此方案是以数据库为单位进行导出,如果只需要导出数据库的部分 measurements 数据,此方案会耗费大量时间,建议使用方案二
    • 方案二:使用 influx-tool -dir 工具导出部分 measurements 数据,再使用 influx -import -path 导入到 influx proxy,此方案效率会高于 rebalance 操作
      • 支持特性:支持指定 measurements 列表或范围导出
        • 支持 -measurements 指定 measurements 列表导出,以英文逗号分隔或者
        • 支持 -range 指定 measurements 起始范围导出,形如 start,end 格式
        • 支持 -float-fields 指定 string 类型的 field 列表,强转为 float 类型
        • 支持 将同时具有 string 和 float 类型的 field 自动转换为 float 类型
      • 存在问题influx-tool 目前还是基于 http 接口进行数据并行查询和写入,需要导出的 measurements 数据量不多时,建议使用此方案,未来 influx-tool 将会直接读取 influxdb 实例的持久化文件,进一步提升导出性能

故障恢复

当出现 influxdb 实例机器故障,甚至无法恢复的情形,需要对故障 circle 的进行数据恢复

  • 确定故障 circle 中需要恢复的 influxdb 实例列表
  • 修改 proxy.json,重新启动所有的 influx proxy
  • 根据后面章节 HTTP 接口 /recovery 进行相关操作
  • 故障恢复过程中,待恢复的 circle 将变成 只写 (write only) 状态,可以继续写入数据、但不能查询,同时后台里进行故障恢复操作,从而不用停机,直到故障恢复完成后,只写状态解除变成读写可用状态
  • 可以通过后面章节 HTTP 接口 /migrate/stats 查询故障恢复进度统计信息
  • 若使用网络共享存储,则不用做故障恢复,只需新 influxdb 实例启动后,等待缓存失败数据重写
  • 备注:recovery 操作是将一个健康 circle 的数据恢复到一个故障 circle 中的部分或全部 influxdb 实例,是 circle 与 circle 之间的单向操作

数据同步

因为网络、磁盘等各种环境原因,可能会有极少概率出现各个 circle 数据不一致的情况、导致脏读问题,因此需要定期做数据同步,以达到数据一致性,实现方案是对所有 circle 的数据进行互相同步

  • 确定需要同步最近数据的时间时长,单位为秒
  • 根据后面章节 HTTP 接口 /resync 进行相关操作
  • 可以通过后面章节 HTTP 接口 /migrate/stats 查询数据同步进度统计信息
  • 备注:resync 操作是所有 circle 直接互相同步数据的操作

数据清除

扩容后,少部分 influxdb 实例还存储着迁移之前的旧数据,由于这些旧数据不应该继续存储在该 influxdb 实例上,在确认无误后建议清除,避免占用内存资源

  • 根据后面章节 HTTP 接口 /clear 进行相关操作
  • 可以通过后面章节 HTTP 接口 /migrate/stats 查询数据清除进度统计信息
  • 备注:clear 操作只针对指定 circle 进行错误数据清除
  • 备注:被缩容移除的机器,在确认无误后直接进行数据文件删除或者回收即可,不适用 clear 操作

更新日志

主要版本

v2.0

  • 2019 年 5 月 31 日发布,具备一致性哈希的基础读写功能,存在着较多 Bug

v2.0.2

  • 2020 年 2 月 4 日开始重新维护、进行完全重构
  • 重构所有代码,优化代码质量,重命名不合理的文件和代码变量
  • 修复写数据时,若 tag 和 field 是带有空格的字符串导致写入失败的问题
  • 修复集群语句查询逻辑和处理问题
  • 配置文件 proxy.json 变更:移除 cpu_core 字段
  • 支持版本信息显示

v2.1

  • 重命名部分代码文件、代码变量
  • 优化认证加密代码
  • 添加数据迁移核心代码
  • 添加 重新平衡 主要代码:rebalance
  • 添加 故障恢复 主要代码:recovery
  • 添加 数据同步 主要代码:resync
  • 支持 http 接口 /status 查询 rebalance、recovery 和 resync 的迁移进度状态
  • 修复不合法的 http 参数导致异常的问题
  • 修复 db 参数解析不正确的问题
  • 支持 http response 显示版本信息

v2.2

  • 修改命令行参数 -proxy-config
  • 支持 http 接口 /ping
  • 配置文件 proxy.json 变更:
    • circles 配置增加字段 name
    • fail_data_dir 变更为 data_dir
    • number_of_replicas 变更为 vnode_size
    • backend_buffer_max_num 变更为 flush_size
    • sync_data_time_out 变更为 flush_time
    • proxy_username 变更为 username
    • proxy_password 变更为 password
  • 重命名 http 接口 /clear_measure/clear
  • 优化 http 返回的错误信息
  • 重构优化 http 返回数据的数据结构,更好地兼容各种类型的数据
  • 修复 influxdb shell 查询部分语句返回失败的问题
  • 修复数据重复写两次的问题
  • 支持集群查询语句:
    • show retention policies
    • show stats
    • show tag values
    • create database
  • 禁止查询语句:select into from
  • 重构优化集群语句查询代码逻辑
  • 修复 measurement 在特殊转义字符情况下识别错误的问题
  • 修复数据包含特殊转义字符的情况下,无法完成这些数据迁移的问题
  • 支持迁移时设置并行处理的 cpu 数量
  • 支持 gzip,并修复写入、查询数据时存在的 gzip 问题
  • 修复 db 检查限制的问题

v2.3

  • 优化日志输出显示
  • 完全重构日志模块,移除 logrus 依赖,缩减 4 个日志句柄为 2 个
  • 优化认证检查逻辑
  • 配置文件 proxy.json 变更:
    • 新增 mlog_dir,支持 rebalance、recovery 和 resync 的迁移日志目录配置
    • 新增 auth_secure,支持认证加密配置,不启用则使用明文认证的用户和密码
    • 新增 https_enabledhttps_certhttps_key,支持 https 配置
  • 支持 influx-proxy 的 https,以及 influxdb 实例的 https 访问
  • 移除 MigrateFlagStatus 相关的冗余代码逻辑
  • 重命名部分 http 查询参数:如 circle_num 改为 circle_id,last_seconds 改为 seconds
  • 修复查询数据时,当所有 circle 都不是健康运行的状态下导致进入死循环的问题
  • 简化 rebalance、recovery 和 resync 相关代码
  • 重构优化错误数据清除代码逻辑: clear
  • 完全重构处理 influxdb 实例涉及数据写入、查询、缓存失败数据重写等代码逻辑
  • 支持部分 influxdb 实例不可用时,返回相应错误信息显示
  • 修复写入数据时,没有带时间戳导致各个 influxdb 实例写入系统时间不一致的问题
  • 丰富 rebalance、recovery 和 resync 的迁移状态信息
  • 支持 rebalance、recovery 和 resync 迁移时使用 gzip 传输数据,提升迁移性能

v2.4

  • 优化启动信息显示,避免 read meta error: EOF 误以为是错误日志
  • 修复缩容时,旧 influxdb 实例有认证导致无法迁移数据的问题
  • 修复错误数据清除 clear 操作代码中匿名函数传参不正确导致不能完整清除数据的问题
  • 修复迁移时可能会有个别数据未迁移的问题
  • 修复删除语句处理不正确的问题:delete fromdrop measurement
  • 优化 json 处理性能
  • 处理数据写入、查询、缓存失败数据重写时,支持更多日志输出
  • 重构缓存失败数据重写代码逻辑
  • 优化 db 检查,db 禁止访问时,输出 db 日志信息
  • 支持写入数据时提前检查不合法的数据,并输出数据日志信息
  • 配置文件 proxy.json 变更:
    • 新增 hash_key,配置说明见配置字段说明
    • 新增 check_interval,支持配置后端实例检查存活的间隔时间
    • 新增 rewrite_interval,支持配置后端实例重写数据的间隔时间
    • 新增 write_timeout,支持配置后端实例写数据的超时时间
    • 新增 idle_timeout,支持配置服务器 keep-alives 等待的超时时间
    • 新增 log_enabled,支持输出 debug 日志信息用于故障排查
  • 支持对 proxy.json 未配置项设置默认值,默认值说明见配置字段说明
  • 支持对 influxdb 实例配置进行检查校验
  • 支持 http 接口 /health 查询所有 influxdb 实例的负载健康状态
  • 支持 http 接口 /replica 查询 db,measurement 对应数据存储的所有 influxdb 实例副本
  • 支持所有 http 接口附带 pretty 参数,以美化的 json 格式输出
  • 重命名 http 接口:
    • 迁移进度统计信息查询接口 /status 变更为 /migrate/stats
    • 设置和查询迁移状态标志接口 /migrating 变更为 /migrate/state
  • 修复多个 influx-proxy 部署时,rebalance、recovery、resync、clear 状态不一致的问题
  • 对所有 http 接口添加认证检查,除了接口 /ping/encrypt/decrypt
  • 优化所有 http 接口 method 和 auth 检查的代码,提升代码复用性
  • 完全优化认证加密代码,修改加密密钥
  • 修复写数据被丢弃的罕见问题:数据没有时间戳、precision 参数不是 ns 的情况
  • 支持查询语句 drop databasedrop series fromon clause
  • 重构 query 代码逻辑,移除正则表达式匹配查询语句的代码,提升查询性能
  • 优化读写请求错误时的错误信息返回,支持 influxdb shell 正确显示错误信息
  • 修复重写老版本缓存的失败数据时导致 index out of range 的问题
  • 支持重启后对已缓存的失败数据进行重写
  • 支持配置文件配置项检查
  • 优化读写请求的日志输出
  • 修复重写缓存失败数据时,db 名称包含转义字符的问题
  • 迁移数据时支持 field 中包含多种数据类型的情况

演进路线

  • v2.3-v2.4 一半工作都是在解决优化 rebalance、recovery、resync 相关代码逻辑
  • v2.4 重新平衡 (rebalance)、故障恢复 (recovery)、数据同步 (resync) 都是基于 http 接口进行数据并行查询和写入,面对大量数据时,迁移性能较低,花费时间较长

v2.5

计划将 influx-proxy 分离为两部分:

  • 核心程序:influx-proxy,基于一致性哈希的高可用集群代理程序,无明显 Bug 且易于维护
  • 配套工具:influx-tool,配套工具,支持高性能的重新平衡 (rebalance)、故障恢复 (recovery)、数据同步 (resync) 操作,与 influx-proxy 解耦

HTTP 接口

全部接口列表

接口 描述
/ping 检查 influx proxy 实例的运行状态及版本信息
/query 查询数据并管理 measurement 数据
/write 写入数据到已存在的数据库中
/health 查询所有 influxdb 实例的负载健康状态
/replica 查询 db,measurement 对应数据存储的所有 influxdb 实例副本
/encrypt 加密明文的用户和密码
/decrypt 解密加密的用户和密码
/migrate/state 查询和设置迁移状态标志
/migrate/stats 查询迁移进度状态统计
/rebalance 对指定的 circle 进行重新平衡
/recovery 将指定 circle 的全量数据恢复到故障的 circle 的全部或部分实例
/resync 所有 circle 互相同步数据
/clear 对指定的 circle 中不该存储在对应实例的错误数据进行清除
/debug/pprof 生成用于性能瓶颈排障定位的采样文件

以下各节假定 influx proxy 实例在 127.0.0.1:7076 上运行,并且未启用 https

接口 /ping

检查 influx proxy 实例的运行状态及版本信息

官方文档

定义

GET http://127.0.0.1:7076/ping
HEAD http://127.0.0.1:7076/ping

示例

$ curl -i http://127.0.0.1:7076/ping

HTTP/1.1 204 No Content
X-Influxdb-Version: 2.4.7
Date: Wed, 01 Apr 2020 09:23:39 GMT

接口 /query

查询数据并管理 measurement 数据

官方文档

定义

GET http://127.0.0.1:7076/query
POST http://127.0.0.1:7076/query

方法

方法 查询类型
GET 用于所有以以下子句开头的查询:SELECT (不包括 SELECT INTO), SHOW
POST 用于所有以以下子句开头的查询:CREATE, DELETE, DROP

查询参数

查询参数 可选/必须 描述
db=<database> 必须 (对于依赖数据库的查询) 设置数据库
q=<query> 必须 InfluxQL 查询语句
epoch=[ns,u,µ,ms,s,m,h] 可选 指定返回时间戳的单位,默认为 RFC3339 格式
pretty=true 可选 以美化的 json 格式输出
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

查询 SELECT 语句

$ curl -G 'http://127.0.0.1:7076/query?db=mydb' --data-urlencode 'q=SELECT * FROM "mymeas"'

{"results":[{"statement_id":0,"series":[{"name":"mymeas","columns":["time","myfield","mytag1","mytag2"],"values":[["2017-03-01T00:16:18Z",33.1,null,null],["2017-03-01T00:17:18Z",12.4,"12","14"]]}]}]}

创建数据库

$ curl -X POST 'http://127.0.0.1:7076/query' --data-urlencode 'q=CREATE DATABASE "mydb"'

{"results":[{"statement_id":0}]}

查询 SELECT 语句、附带认证信息、返回以秒为单位的时间戳

$ curl -G 'http://127.0.0.1:7076/query?db=mydb&epoch=s&u=myuser&p=mypass' --data-urlencode 'q=SELECT * FROM "mymeas"'

{"results":[{"statement_id":0,"series":[{"name":"mymeas","columns":["time","myfield","mytag1","mytag2"],"values":[[1488327378,33.1,null,null],[1488327438,12.4,"12","14"]]}]}]}

接口 /write

写入数据到已存在的数据库中

官方文档

定义

POST http://127.0.0.1:7076/write

查询参数

查询参数 可选/必须 描述
db=<database> 必须 设置数据库
precision=[ns,u,ms,s,m,h] 可选 设置写入数据时间戳的单位,默认为 ns
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

写一个点到数据库,时间戳以秒为单位

$ curl -i -X POST "http://127.0.0.1:7076/write?db=mydb&precision=s" --data-binary 'mymeas,mytag=1 myfield=90 1463683075'

HTTP/1.1 204 No Content
X-Influxdb-Version: 2.4.7
Date: Wed, 01 Apr 2020 09:54:33 GMT

写一个点到数据库,附带认证信息

$ curl -X POST "http://127.0.0.1:7076/write?db=mydb&u=myuser&p=mypass" --data-binary 'mymeas,mytag=1 myfield=91'

HTTP/1.1 204 No Content
X-Influxdb-Version: 2.4.7
Date: Wed, 01 Apr 2020 09:54:57 GMT

从文件写多个点到数据库

$ curl -i -XPOST "http://127.0.0.1:7076/write?db=mydb" --data-binary @data.txt

HTTP/1.1 204 No Content
X-Influxdb-Version: 2.4.7
Date: Wed, 01 Apr 2020 09:59:21 GMT

data.txt 示例数据如下,注意 data.txt 需要满足 Line protocol 语法

mymeas,mytag1=1 value=21 1463689680000000000
mymeas,mytag1=1 value=34 1463689690000000000
mymeas,mytag2=8 value=78 1463689700000000000
mymeas,mytag3=9 value=89 1463689710000000000

Line protocol 语法

<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]

官方文档:Line protocol syntax

接口 /health

查询所有 influxdb 实例的负载健康状态

定义

GET http://127.0.0.1:7076/health

查询参数

查询参数 可选/必须 描述
pretty=true 可选 以美化的 json 格式输出
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

$ curl 'http://127.0.0.1:7076/health?pretty=true'

[
    {
        "backends": [
            {
                "active": true,
                "backlog": false,
                "load": {
                    "db1": {
                        "incorrect": 0,
                        "inplace": 2,
                        "measurements": 2
                    },
                    "db2": {
                        "incorrect": 0,
                        "inplace": 1,
                        "measurements": 1
                    }
                },
                "name": "influxdb-1-1",
                "rewrite": false,
                "url": "http://127.0.0.1:8086"
            }
        ],
        "circle": "circle-1"
    }
]

负载健康状态说明

  • name:influxdb 实例名称
  • url:influxdb 实例 url
  • active:influxdb 实例是否存活
  • backlog:influx-proxy 是否有 influxdb 实例堆积的缓存失败数据
  • rewrite:influx-proxy 是否正在重写缓存失败数据到相应的 influxdb 实例
  • load:influxdb 实例的负载健康状态
    • db:influxdb 实例上的 db 名称
      • incorrect:db 中不应该存储到本 influxdb 实例的 measurement 的数量
        • 导致原因:机器扩缩容、hash_key 发生变更、或 hash_key 对应键的值发生变更等
        • incorrect 为 0 表示健康
      • inplace:db 中正确存储到本 influxdb 实例的 measurement 的数量
        • inplace 和 measurements 相等表示健康
      • measurements:db 中 measurement 的数量
        • measurements = incorrect + inplace
        • 各个 influxdb 实例的 measurements 数量大致相当,表示数据存储负载均衡

接口 /replica

查询 db,measurement 对应数据存储的所有 influxdb 实例副本

定义

GET http://127.0.0.1:7076/replica

查询参数

查询参数 可选/必须 描述
db=<database> 必须 设置 database
meas=<measurement> 必须 设置 measurement
pretty=true 可选 以美化的 json 格式输出
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

$ curl 'http://127.0.0.1:7076/replica?db=db1&meas=cpu1&pretty=true'

[
    {
        "circle": "circle-1",
        "name": "influxdb-1-1",
        "url": "http://127.0.0.1:8086"
    },
    {
        "circle": "circle-2",
        "name": "influxdb-2-2",
        "url": "http://127.0.0.1:8089"
    }
]

接口 /encrypt

加密明文的用户和密码

定义

GET http://127.0.0.1:7076/encrypt

查询参数

查询参数 可选/必须 描述
msg=<message> 必须 需要加密的明文消息

示例

$ curl -G 'http://127.0.0.1:7076/encrypt' --data-urlencode 'msg=admin'

YgvEyuPZlDYAH8sGDkC!Ag

接口 /decrypt

解密加密的用户和密码

定义

GET http://127.0.0.1:7076/decrypt

查询参数

查询参数 可选/必须 描述
key=<key> 必须 用于加解密的密钥,默认是 consistentcipher
msg=<message> 必须 需要解密的加密消息

示例

$ curl 'http://127.0.0.1:7076/decrypt?key=consistentcipher&msg=YgvEyuPZlDYAH8sGDkC!Ag'

admin

接口 /migrate/state

查询和设置迁移状态标志

定义

GET http://127.0.0.1:7076/migrate/state
POST http://127.0.0.1:7076/migrate/state

查询参数

查询参数 可选/必须 描述
resyncing=true 可选 设置 influx proxy 是否正在互相同步数据的状态
circle_id=0 可选 设置 circle 是否正在迁移数据的状态的 circle id,从索引 0 开始
migrating=false 可选 设置指定 circle 是否正在迁移的状态
pretty=true 可选 以美化的 json 格式输出
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

查询迁移状态标志

$ curl 'http://127.0.0.1:7076/migrate/state?pretty=true'

{
    "circles": [
        {
            "circle_id": 0,
            "circle_name": "circle-1",
            "is_migrating": false
        },
        {
            "circle_id": 1,
            "circle_name": "circle-2",
            "is_migrating": false
        }
    ],
    "is_resyncing": false
}

设置 influx proxy 正在互相同步数据

$ curl -X POST 'http://127.0.0.1:7076/migrate/state?resyncing=true&pretty=true'

{
    "resyncing": true
}

设置 circle 0 正在迁移数据

$ curl -X POST 'http://127.0.0.1:7076/migrate/state?circle_id=0&migrating=true&pretty=true'

{
    "circle": {
        "circle_id": 0,
        "circle_name": "circle-1",
        "is_migrating": true
    }
}

接口 /migrate/stats

查询迁移进度统计信息

定义

GET http://127.0.0.1:7076/migrate/stats

查询参数

查询参数 可选/必须 描述
circle_id=0 必须 circle 的 id,从索引 0 开始
type=<type> 必须 状态统计类型,可选值为 rebalance、recovery、resync 或 clear
pretty=true 可选 以美化的 json 格式输出
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

$ curl 'http://127.0.0.1:7076/migrate/stats?circle_id=0&type=rebalance&pretty=true'

{
    "http://127.0.0.1:8086": {
        "database_total": 0,
        "database_done": 0,
        "measurement_total": 0,
        "measurement_done": 0,
        "migrate_count": 0,
        "inplace_count": 0
    },
    "http://127.0.0.1:8087": {
        "database_total": 0,
        "database_done": 0,
        "measurement_total": 0,
        "measurement_done": 0,
        "migrate_count": 0,
        "inplace_count": 0
    }
}

接口 /rebalance

对指定的 circle 进行重新平衡

定义

POST http://127.0.0.1:7076/rebalance

查询参数

查询参数 可选/必须 描述
circle_id=0 必须 circle 的 id,从索引 0 开始
operation=<operation> 必须 操作类型,可选值为 add 或 rm
db=<db_list> 可选 数据库列表,以英文逗号 ',' 分隔,为空时将默认为全部数据库
cpus=1 可选 迁移数据用到的最大 cpu 数,默认为 1
ha_addrs=<ha_addrs> 可选 (若至少有两个正在运行的 influx proxy 实例,此参数必须) 所有正在运行的 influx proxy 实例的高可用地址列表,以英文逗号 ',' 分隔,单实例时此参数将被忽略
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

请求 body

当操作类型 operation 为 rm 时,必须添加被移除的 influxdb 实例的配置信息,以 json 格式放入到请求 body 中

{
    "backends": [
        {
            "name": "influxdb-1-2",
            "url": "http://127.0.0.1:8087",
            "username": "",
            "password": ""
        }
    ]
}

示例

在 circle 0 扩容 influxdb 实例后,进行重新平衡操作,这里假定有两个运行的 influx proxy 实例

$ curl -X POST 'http://127.0.0.1:7076/rebalance?circle_id=0&operation=add&ha_addrs=127.0.0.1:7076,127.0.0.1:7077'

accepted

在 circle 0 移除 url 为 http://127.0.0.1:8087 的 influxdb 实例后,进行重新平衡操作,设定使用 2 个 cpu 进行数据迁移,这里假定只有一个在运行的 influx proxy 实例

$ curl -X POST 'http://127.0.0.1:7076/rebalance?circle_id=0&operation=rm&cpus=2' -H 'Content-Type: application/json' -d \
'{
    "backends": [
        {
            "name": "influxdb-1-2",
            "url": "http://127.0.0.1:8087",
            "username": "",
            "password": ""
        }
    ]
}'

accepted

接口 /recovery

将指定 circle 的全量数据恢复到故障的 circle 的全部或部分实例

定义

POST http://127.0.0.1:7076/recovery

查询参数

查询参数 可选/必须 描述
from_circle_id=0 必须 来源 circle 的 id,从索引 0 开始
to_circle_id=1 必须 待恢复 circle 的 id,从索引 0 开始
backend_urls=<backend_urls> 可选 待恢复的 influxdb 实例 url 列表,以英文逗号 ',' 分隔,为空时将默认为待恢复 circle 的全部 influxdb 实例 url 列表
db=<db_list> 可选 数据库列表,以英文逗号 ',' 分隔,为空时将默认为全部数据库
cpus=1 可选 迁移数据用到的最大 cpu 数,默认为 1
ha_addrs=<ha_addrs> 可选 (若至少有两个正在运行的 influx proxy 实例,此参数必须) 所有正在运行的 influx proxy 实例的高可用地址列表,以英文逗号 ',' 分隔,单实例时此参数将被忽略
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

从 circle 0 恢复所有数据到 circle 1

$ curl -X POST 'http://127.0.0.1:7076/recovery?from_circle_id=0&to_circle_id=1'

accepted

从 circle 0 恢复数据到 circle 1 中 url 为 http://127.0.0.1:8089 的实例

$ curl -X POST 'http://127.0.0.1:7076/recovery?from_circle_id=0&to_circle_id=1&backend_urls=http://127.0.0.1:8089'

accepted

接口 /resync

所有 circle 互相同步数据

定义

POST http://127.0.0.1:7076/resync

查询参数

查询参数 可选/必须 描述
seconds=<seconds> 可选 所有 circle 互相同步最近 <seconds> 秒的数据,默认为 0,表示同步所有历史数据
db=<db_list> 可选 数据库列表,以英文逗号 ',' 分隔,为空时将默认为全部数据库
cpus=1 可选 迁移数据用到的最大 cpu 数,默认为 1
ha_addrs=<ha_addrs> 可选 (若至少有两个正在运行的 influx proxy 实例,此参数必须) 所有正在运行的 influx proxy 实例的高可用地址列表,以英文逗号 ',' 分隔,单实例时此参数将被忽略
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

$ curl -X POST 'http://127.0.0.1:7076/resync?cpus=2'

accepted

接口 /clear

对指定的 circle 中不该存储在对应实例的错误数据进行清除

定义

POST http://127.0.0.1:7076/clear

查询参数

查询参数 可选/必须 描述
circle_id=0 必须 circle 的 id,从索引 0 开始
cpus=1 可选 迁移数据用到的最大 cpu 数,默认为 1
ha_addrs=<ha_addrs> 可选 (若至少有两个正在运行的 influx proxy 实例,此参数必须) 所有正在运行的 influx proxy 实例的高可用地址列表,以英文逗号 ',' 分隔,单实例时此参数将被忽略
u=<username> 可选 (若未启用认证) 设置认证用户,若启用认证
p=<password> 可选 (若未启用认证) 设置认证密码,若启用认证

示例

$ curl -X POST 'http://127.0.0.1:7076/clear?circle_id=0&cpus=2'

accepted

接口 /debug/pprof

生成用于性能瓶颈排障定位的采样文件

官方文档

定义

curl http://127.0.0.1:7076/debug/pprof/

示例

下载 CPU 性能的采样文件

curl -o <path/to/pprof-cpu>  http://127.0.0.1:7076/debug/pprof/profile

下载 Heap 内存的采样文件

curl -o <path/to/pprof-heap> http://127.0.0.1:7076/debug/pprof/heap
Clone this wiki locally