Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

请问 influxdb-proxy 和influxdb-relay 这两个有什么特点和不同点该如何选择? #111

Closed
zhangyang1995 opened this issue Oct 29, 2020 · 27 comments

Comments

@zhangyang1995
Copy link

No description provided.

@shell909090
Copy link
Owner

这俩差异太大,让我从何说起呢...

@zhangyang1995
Copy link
Author

这俩差异太大,让我从何说起呢...

我看文档的理解是influxdb-proxy 后面可以代理多个influxdb的实例,我插入或者查询的话是随机从多个实例查询的,每个influxdb实例是相同的数据,我这样理解正确吗?

@chengshiwen
Copy link

chengshiwen commented Nov 2, 2020

@zhangyang1995 简单讲:

influxdb-relay

  • 官方提供的高可用方案,但只提供简单的写入功能,主要代码4年没有维护了
  • 写入:通过 influxdb-relay 将数据写入到每个 influxdb,多个 influxdb-relay 则需要添加负载均衡(load balancer)
  • 查询:通过负载均衡(load balancer)随机查询其中一个influxdb
  • 特点:高可用、功能简单、没有分片(即每个influxdb数据都完全相同)
    image

influx-proxy

  • 基于 influxdb-relay 改进,支持基于映射规则的分库(即一个数据库划分为多块、分别存到不同 influxdb 实例上),支持更多功能如gzip、写查统一对上层透明、写入influxdb失败时缓存数据并尝试重新等
  • 写入:通过 influx-proxy 将数据写入到映射规则对应的部分 influxdb 中(一个或多个,同时都写入,即这些 influxdb 数据完全相同),映射规则:例如 cpu 的 measurement 写到 [influxdb-1, influxdb-2],以 mem 开头的 measurement 写到 [influxdb-3, influxdb-4] 等,influxdb-1、……、influxdb-4 都可以在配置文件中配置
  • 查询:通过 influx-proxy 顺序查询映射规则对应的部分 influxdb 中的每一个、直到第一个正确返回,例如查 mem 开头的 measurement,则 [influxdb-3, influxdb-4] 顺序查询 influxdb-3、influxdb-4 直到第一个正常返回
  • 特点:高可用、功能丰富、支持分库(根据映射规则自定义分库规则及可用副本),但逻辑上只支持一个数据库
    image

influx-proxy v2

  • 基于 influx-proxy 的进一步改进,支持一致性哈希的分库规则(无须手动设置),支持多个数据库,支持更多配套功能,无 Python 和 Redis 依赖等
  • 写入:同时写入多个 circle(每个 circle 是一份全量数据,即一个副本),其中一个 circle 包含多个 influxdb,每个 influxdb 的数据是一个 circle 的一部分(分库)、根据一致性哈希算法进行分配,即一个 circle 中所有 influxdb 的数据加总刚好是一份全量数据
  • 查询:随机查询一个健康的 circle
  • 特点:高可用、一致性哈希、功能更加丰富、支持多个数据库、支持更多配套功能、无 Python 和 Redis 依赖等
    image

@zhangyang1995
Copy link
Author

zhangyang1995 commented Nov 3, 2020

@chengshiwen 首先感谢您的回答。

BACKENDS = {
'influx51': {
'url': 'http://192.168.0.2:8086',
'db': 'monitor',
'zone':'local'
},
'influx52':{
'url': 'http://192.168.0.1:8086',
'db': 'monitor',
'zone':'local'
}
}
KEYMAPS = {
'collapsar_broker':['influx51,influx52'],
'ePrint-service':['influx51',influx52],
'reports':['influx51,influx51']
}

再请教一下 如果我这个配置两个不同服务器的两个数据数据库 是不是就可以做到数据库的高可用了 挂了一个 还有另一个可以使用?

@chengshiwen
Copy link

chengshiwen commented Nov 4, 2020

@zhangyang1995 是的,KEYMAPS中的每个 key 对应存储的 influxdb 实例个数至少为2时,即至少有2个副本,所以访问该 key 时挂了一个另一个还可以用

@zhangyang1995
Copy link
Author

@zhangyang1995 是的,KEYMAPS中的每个 key 对应存储的 influxdb 实例个数至少为2时,即至少有2个副本,所以访问该 key 时挂了一个另一个还可以用

这里的 'default': ['local']

'_default_': ['local']

可以理解为如果有的表没有在这里配置KEYMAPS 默认是走default中local吗?

@chengshiwen
Copy link

@zhangyang1995 是的,匹配 key 的原则有两个:1、精确匹配、2、前缀匹配,如果两个都不匹配则走 default 的配置

@shell909090
Copy link
Owner

@chengshiwen 感谢你在这个库上做的工作。
关于一致性哈希,我没看你的具体代码。是根据measurement name做的一致性哈希么?
我们当时基于规则的主要理由,是不同数据QoS分离。不同类别归属于不同team。某一类数据炸了不影响其他数据的可用性。
说的难听点,就是某个team瞎用采样数据库的话,只会让这个team自己倒霉。
如果你是根据measurement name做的consistent hash的话,建议将这个部分做成可插拔的。或者可以手工指定规则,override hash algo。

@chengshiwen
Copy link

chengshiwen commented Nov 5, 2020

@shell909090 感谢,很好的提议,以前的想法是让用户少做选择,后来的想法是把能力开放出去。基于db+measurement做的hash,之所以没有继续用规则,是考虑到一些场景下用户无法事先预知要设置哪些规则,需要关心规则的设计,设计不合理带来数据负载的不合理,后期维护也会有比较高的成本,想法还是让用户少做选择。

@zhangyang1995
Copy link
Author

@chengshiwen
如果说proxy并发量达不到我现在想要的,那么我可以通过其他东西增加并发量吗?比如nginx下面挂在3个proxy?

@shell909090
Copy link
Owner

汗...proxy做过的压力测试,配置足够的机器上,每个backend能容纳11M recs/s的数据。性能要是还不够的话,强烈建议买企业版...

@zhangyang1995
Copy link
Author

zhangyang1995 commented Nov 5, 2020

汗...proxy做过的压力测试,配置足够的机器上,每个backend能容纳11M recs/s的数据。性能要是还不够的话,强烈建议买企业版...

我是用jemeter-http请求做的 查询测试 同样的sql语句 influxdb数据库和proxy--》influxdb 感觉有点差距 不知道是哪部分限制了http的请求

4286,the client is 192.168.84.1:51394
2020/11/05 17:28:13.639692 http.go:150: query error: dial tcp 192.168.84.137:8086: socket: too many open files,the query is select hostname,value from disk_free where time =1604568385387794286
2020/11/05 17:28:13.639716 http.go:86: query error: dial tcp 192.168.84.137:8086: socket: too many open files,the query is select hostname,value from disk_free where time =1604568385387794286,the client is 192.168.84.1:51395
2020/11/05 17:28:13.645897 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 20ms
2020/11/05 17:28:13.708704 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 40ms
2020/11/05 17:28:13.713644 http.go:150: query error: dial tcp 192.168.84.137:8086: socket: too many open files,the query is select hostname,value from disk_free where time =1604568385387794286
2020/11/05 17:28:13.713691 http.go:86: query error: dial tcp 192.168.84.137:8086: socket: too many open files,the query is select hostname,value from disk_free where time =1604568385387794286,the client is 192.168.84.1:50354
2020/11/05 17:28:13.751456 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 80ms
2020/11/05 17:28:13.851670 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 5ms
2020/11/05 17:28:13.857434 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 10ms
2020/11/05 17:28:13.868942 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 20ms
2020/11/05 17:28:13.892121 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 40ms
2020/11/05 17:28:13.933176 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 5ms
2020/11/05 17:28:13.938317 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 10ms
2020/11/05 17:28:13.978382 server.go:3095: http: Accept error: accept tcp [::]:6666: accept4: too many open files; retrying in 5ms
2020/11/05 17:28:24.388989 file.go:179: write meta: 182
2020/11/05 17:28:24.389174 file.go:179: write meta: 0
2020/11/05 17:28:24.395207 file.go:179: write meta: 0

@chengshiwen
Copy link

@zhangyang1995 你发的错误是因为 influxdb 机器的句柄数open files太少的缘故,需要设置大一些,至少 20w 起步

@zhangyang1995
Copy link
Author

机器的句柄数open files
是这个吗
influxdb1:
[root@localhost ~]# cat /proc/sys/fs/file-max
378886
influxdb2:
[root@localhost ~]# cat /proc/sys/fs/file-max
378886
proxy:
[root@master influx-proxy]# cat /proc/sys/fs/file-max
279571

@chengshiwen
Copy link

chengshiwen commented Nov 5, 2020

看实际进程的 limits 数量,先 ps 找到进程,然后 cat /proc/<pid>/limits 看进程实际的 Max open files 数量
如果是用 systemd 管理 influxdb 的话,传统的通过 ulimit 或者 /etc/security/limits.conf 或者 /etc/sysctl.conf 进行修改句柄数都不生效,需要修改 influxdb.service 文件中的 LimitNOFILE,该文件通常在 /usr/lib/systemd/system/influxdb.service

@chengshiwen
Copy link

经过生产验证,influx-proxy 代理转发,确实会有性能损耗,比直接访问 influxdb 的读、写性能略低一点,例如查询使用正则表达式进行语句匹配多少都需要匹配时间,但是可以忽略不计。
另外,influx-proxy 通常不是性能瓶颈,更多的还是代理的 influxdb 性能瓶颈,例如写数据,基本都是 influxdb cpu 会打满,而 influx-proxy 负载还不到一半,多加 influx-proxy 不会有直接提升,但可以做高可用

@zhangyang1995
Copy link
Author

zhangyang1995 commented Nov 6, 2020

看实际进程的 limits 数量,先 ps 找到进程,然后 cat /proc/<pid>/limits 看进程实际的 Max open files 数量
如果是用 systemd 管理 influxdb 的话,传统的通过 ulimit 或者 /etc/security/limits.conf 或者 /etc/sysctl.conf 进行修改句柄数都不生效,需要修改 influxdb.service 文件中的 LimitNOFILE,该文件通常在 /usr/lib/systemd/system/influxdb.service

谢谢,我一会尝试一下, 如果我修改了redis的数据 proxy服务需要重启吗?我这里测试是需要重启有没有开关不用重启?

@chengshiwen
Copy link

@zhangyang1995
http api 有个 /reload 接口,可以重新加载 redis 中的配置数据

mux.HandleFunc("/reload", hs.HandlerReload)

@zhangyang1995
Copy link
Author

@zhangyang1995
http api 有个 /reload 接口,可以重新加载 redis 中的配置数据

mux.HandleFunc("/reload", hs.HandlerReload)

十分感谢!

@zhangyang1995
Copy link
Author

zhangyang1995 commented Nov 18, 2020

如果插入的时候不带time字段 infuxdb-proxy是怎么处理的呢?感觉同样的数据(不带时间表)直接插入influxdb有23W条,而通过proxy只有240条 我怀疑是proxy做了处理 如果插入时候不带时间可能会把一批数据归集到一个时间上?@chengshiwen
我使用的wrk测试[root@localhost data]# wrk -t12 -c1000 -d10s -s post.lua http://172.16.0.148:6666/write?db=test
Running 10s test @ http://172.16.0.148:6666/write?db=test
12 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 3.99ms 2.18ms 34.95ms 72.76%
Req/Sec 20.25k 1.70k 25.83k 69.08%
2425570 requests in 10.06s, 205.88MB read
Requests/sec: 241199.82
Transfer/sec: 20.47MB

[root@localhost data]# cat post.lua
wrk.method = "POST"
wrk.body = "weather,altitude=1000,area=北 temperature=11,humidity=-4"
wrk.headers["Content-Type"] = "application/binary"

[root@localhost data]# wrk -t12 -c1000 -d30s -s post.lua http://172.16.0.147:8086/write?db=demo
Running 30s test @ http://172.16.0.147:8086/write?db=demo
12 threads and 1000 connections
Thread Stats Avg Stdev Max +/- Stdev
Latency 25.02ms 12.11ms 221.48ms 70.21%
Req/Sec 3.35k 713.09 6.83k 64.73%
1200908 requests in 30.09s, 284.03MB read
Requests/sec: 39906.62
Transfer/sec: 9.44MB

@chengshiwen
Copy link

@zhangyang1995 不带时间,插入的时间取决于服务器给出的系统时间,如果直接高速插入 influxdb,其实也会出现少量的时间重复,导致数据被覆盖,如果插入 influx-proxy,proxy 会缓存一部分数据(默认是1w行)后再批写到 influxdb,所以会加剧时间重复。
一般非常不建议这样做,如果要这样做,最好也是有 tag 区分,即 时间相同,tag 组合不同的情况下,不会覆盖

@chengshiwen
Copy link

建议使用 influx-stress,或者 tsbs 进行测试

@zhangyang1995
Copy link
Author

@zhangyang1995 不带时间,插入的时间取决于服务器给出的系统时间,如果直接高速插入 influxdb,其实也会出现少量的时间重复,导致数据被覆盖,如果插入 influx-proxy,proxy 会缓存一部分数据(默认是1w行)后再批写到 influxdb,所以会加剧时间重复。
一般非常不建议这样做,如果要这样做,最好也是有 tag 区分,即 时间相同,tag 组合不同的情况下,不会覆盖

请问一下如果我想做读写分离有什么好的方案吗 因为我有一个场景一个inlfuxdb库要一直写入数据,如果在同时查询的话查询效率很低。蟹蟹

@chengshiwen
Copy link

chengshiwen commented Nov 18, 2020

目前没有,各个 influxdb 是完全独立的,属于 Shared-nothing architecture (SN 架构),基于 proxy 的这个方案无法直接做到读写分离。要改造成真正意义上的读写分离,需要改造 proxy 代码(识别哪些 influxdb 是写,哪些 influxdb 是读),而且还需要支持背景里从 influxdb 写库复制到 influxdb 读库,官方有命令支持 online backup,不过只能支持单实例备份到单实例

@shell909090
Copy link
Owner

@zhangyang1995 influx-proxy其实具备了读写分离的基础,可以对某些backend设定write only。但是由于influx-proxy不是集群,backend的两台influx之间没有同步。所以读的那台并不能不写入,因此influx-proxy没有read only选项。如果你有方案能低成本的解决influx之间同步的问题,influx-proxy的改造并不复杂。

@zhangyang1995
Copy link
Author

目前没有,各个 influxdb 是完全独立的,属于 Shared-nothing architecture (SN 架构),基于 proxy 的这个方案无法直接做到读写分离。要改造成真正意义上的读写分离,需要改造 proxy 代码(识别哪些 influxdb 是写,哪些 influxdb 是读),而且还需要支持背景里从 influxdb 写库复制到 influxdb 读库,官方有命令支持 online backup,不过只能支持单实例备份到单实例

这个备份是实时的吗 好像还要我还原备份才能看到数据吧 我刚试了下 远程备份显示8088端口连接不通失败了

@chengshiwen
Copy link

我也有可能记错了 online backup 的功能,或者使用错了,我空了时看看

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants