-
Notifications
You must be signed in to change notification settings - Fork 112
Tutorial v2.4.7
Influx Proxy 是一个基于高可用、一致性哈希的 InfluxDB 集群代理服务,实现了 InfluxDB 高可用集群的部署方案,具有动态扩/缩容、故障恢复、数据同步等能力。连接到 Influx Proxy 和连接原生的 InfluxDB Server 没有显著区别 (支持的查询语句列表),对上层客户端是透明的,上层应用可以像使用单机的 InfluxDB 一样使用,Influx Proxy 会处理请求的转发,并对各个 InfluxDB 集群节点进行管理。Influx Proxy 基于饿了么开源的 Influx-Proxy,并进一步开发和优化,支持了更多的特性,移除了 Python、Redis 依赖,解决了需要额外配置 KEYMAPS 、数据负载不均衡的问题。
- 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 中的所有 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,可选值为idx
、name
或url
,分别使用 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,支持
name
或url
可选值,默认值为url
- v2.4.4 开始,hash_key 支持
idx
、name
或url
可选值,默认值为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 2.5+,使用示例如下,兼容 influx-proxy 和 influxdb 查询:
涉及 CREATE
, DELETE
或 DROP
语句,请务必使用 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 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 实例进行监控,执行导入仪表盘的脚本,将创建监控仪表盘:
监控指标说明:
-
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,适用于生产环境,更新日志见后面章节更新日志
-
-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_enabled
、https_cert
、https_key
,支持 https 配置
-
-
db_list
:访问 influxdb 实例,执行show databases
查看数据库列表,更新到 db_list -
hash_key
:修改为url
,保证老版本兼容性 -
auth_secure
:若开启了加密认证,需要修改为true
-
username
和password
:若开启了加密认证,需要重新生成新加密的用户和密码- 加密方法见后面章节 HTTP 接口
/encrypt
说明
- 加密方法见后面章节 HTTP 接口
- 分布式系统的三个指标:CAP 定理的含义
- Consistency:一致性
- Availability:可用性
- Partition tolerance:分区容错
-
CAP 定理:C、A、P 三个指标不可能同时达到,其中 P 总是成立
- 一致性 和 可用性 只能选择其一
- 只能实现 CP 或 AP
-
influx proxy 实现了可用性,即达到 AP
- 时序数据能容忍极少数数据丢失或者不一致
- 可以定期通过数据同步工具达到数据一致性
- 官方 influxdb 集群也实现了可用性,定期同步数据以解决 脏读问题 (数据读取不一致)
基于代理方案,数据处理操作较少
- 写性能:约等于单个 circle 的所有 influxdb 实例的写入性能总和
- 读性能:约等于所有 circle 的所有 influxdb 实例的查询性能总和
- 架构部署方案:
- 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 实例的持久化文件,进一步提升导出性能
-
支持特性:支持指定 measurements 列表或范围导出
-
方案一:使用官方
当出现 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 操作
- 2019 年 5 月 31 日发布,具备一致性哈希的基础读写功能,存在着较多 Bug
- 2020 年 2 月 4 日开始重新维护、进行完全重构
- 重构所有代码,优化代码质量,重命名不合理的文件和代码变量
- 修复写数据时,若 tag 和 field 是带有空格的字符串导致写入失败的问题
- 修复集群语句查询逻辑和处理问题
- 配置文件 proxy.json 变更:移除
cpu_core
字段- 支持版本信息显示
- 重命名部分代码文件、代码变量
- 优化认证加密代码
- 添加数据迁移核心代码
- 添加 重新平衡 主要代码:rebalance
- 添加 故障恢复 主要代码:recovery
- 添加 数据同步 主要代码:resync
- 支持 http 接口
/status
查询 rebalance、recovery 和 resync 的迁移进度状态- 修复不合法的 http 参数导致异常的问题
- 修复 db 参数解析不正确的问题
- 支持 http response 显示版本信息
- 修改命令行参数
-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 检查限制的问题
- 优化日志输出显示
- 完全重构日志模块,移除 logrus 依赖,缩减 4 个日志句柄为 2 个
- 优化认证检查逻辑
- 配置文件 proxy.json 变更:
- 新增
mlog_dir
,支持 rebalance、recovery 和 resync 的迁移日志目录配置- 新增
auth_secure
,支持认证加密配置,不启用则使用明文认证的用户和密码- 新增
https_enabled
、https_cert
、https_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 传输数据,提升迁移性能
- 优化启动信息显示,避免
read meta error: EOF
误以为是错误日志- 修复缩容时,旧 influxdb 实例有认证导致无法迁移数据的问题
- 修复错误数据清除 clear 操作代码中匿名函数传参不正确导致不能完整清除数据的问题
- 修复迁移时可能会有个别数据未迁移的问题
- 修复删除语句处理不正确的问题:
delete from
、drop 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 database
、drop series from
和on clause
- 重构 query 代码逻辑,移除正则表达式匹配查询语句的代码,提升查询性能
- 优化读写请求错误时的错误信息返回,支持 influxdb shell 正确显示错误信息
- 修复重写老版本缓存的失败数据时导致 index out of range 的问题
- 支持重启后对已缓存的失败数据进行重写
- 支持配置文件配置项检查
- 优化读写请求的日志输出
- 修复重写缓存失败数据时,db 名称包含转义字符的问题
- 迁移数据时支持 field 中包含多种数据类型的情况
- v2.3-v2.4 一半工作都是在解决优化 rebalance、recovery、resync 相关代码逻辑
- v2.4 重新平衡 (rebalance)、故障恢复 (recovery)、数据同步 (resync) 都是基于 http 接口进行数据并行查询和写入,面对大量数据时,迁移性能较低,花费时间较长
计划将 influx-proxy 分离为两部分:
- 核心程序:influx-proxy,基于一致性哈希的高可用集群代理程序,无明显 Bug 且易于维护
- 配套工具:influx-tool,配套工具,支持高性能的重新平衡 (rebalance)、故障恢复 (recovery)、数据同步 (resync) 操作,与 influx-proxy 解耦
接口 | 描述 |
---|---|
/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
检查 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
查询数据并管理 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"]]}]}]}
写入数据到已存在的数据库中
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
<measurement>[,<tag_key>=<tag_value>[,<tag_key>=<tag_value>]] <field_key>=<field_value>[,<field_key>=<field_value>] [<timestamp>]
官方文档:Line protocol syntax
查询所有 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 数量大致相当,表示数据存储负载均衡
-
incorrect:db 中不应该存储到本 influxdb 实例的 measurement 的数量
-
db:influxdb 实例上的 db 名称
查询 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"
}
]
加密明文的用户和密码
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
解密加密的用户和密码
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
查询和设置迁移状态标志
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
}
}
查询迁移进度统计信息
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
}
}
对指定的 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> | 可选 (若未启用认证) | 设置认证密码,若启用认证 |
当操作类型 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
将指定 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
所有 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
对指定的 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
生成用于性能瓶颈排障定位的采样文件
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