-
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开启后有效
ALTERGRANTREVOKEKILLSELECT INTO-
多个语句,以分号(;)分隔
select fromshow fromshow measurementsshow seriesshow field keysshow tag keysshow tag valuesshow retention policiesshow statsshow databasescreate databasedrop databasedelete fromdrop series fromdrop 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配置增加字段namefail_data_dir变更为data_dirnumber_of_replicas变更为vnode_sizebackend_buffer_max_num变更为flush_sizesync_data_time_out变更为flush_timeproxy_username变更为usernameproxy_password变更为password- 重命名 http 接口
/clear_measure为/clear- 优化 http 返回的错误信息
- 重构优化 http 返回数据的数据结构,更好地兼容各种类型的数据
- 修复 influxdb shell 查询部分语句返回失败的问题
- 修复数据重复写两次的问题
- 支持集群查询语句:
show retention policiesshow statsshow tag valuescreate 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 GMTdata.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