高并发( 6M/s)日志数据如何准实时入库( MySQL)

2016-03-03 13:55:42 +08:00
 iyaozhen

目前已经使用 filebeat+logstash 将线上的实时请求日志推送到了 Redis ( list 数据结构做队列) 中。但现在的处理瓶颈卡在了从 Redis 里面取数据做聚合然后入库这步了。

因为数据聚合处理使用的是 Redis 的 hash 数据结构做计数器,需要和 Redis 有几次交互,单个脚本的处理速度为 0.03M/s (已经优化过了),开 200+ 个进程数据聚合这块应该是抗的住的。

一开始使用的方案是每个脚本缓存数据然后达到一定数量(比如 10w 行)后批量解析然后 insert 入库,但因为用的是myisam存储结构(这里有两个原因: 1.机器磁盘不大节省空间 2.数据需要做统计 count(*)等操作用的比较多),写入数据时会锁表,后来又分库( 4 个库)分表( 100 个表)。这个解决方案抗了一段时间后数据量增长又不行了( redis 队列里面的数据处理没有增加快)。

后来想想批量解析和入库这里比较耗时间会阻塞脚本继续读取 Redis 中的数据。就想把解析入库的操作异步出来,这时想了一个办法是把 10w 行日志写文件,然后把文件的路径放到另一个队列里面去,起一些脚本解析文件入库。但我还是想得太简单了,数据量太大了,写的文件太多直接把测试虚拟机的 inode 用完了,机器直接蒙逼了。当然可以 50w 、 100w 行写一次文件,但这感觉不是根本的解决之道,还会带来其它问题(比如单个脚内存消耗过大)。

我感觉我这些解决方法还是太落后了,不知道大神们有没有什么解决方案。

PS :脚本是用的 PHP , Python 、 Go 都可以,不过我感觉这个问题应该不是语言的问题。
为了防止我跑偏,说一下核心需求:准实时根据请求参数等聚合统计数据(用于了解线上实时情况做监控),较低延迟( 30min 内)将这些数据入库(每个日志都带有 logid ,用于定位问题)。

18743 次点击
所在节点    程序员
60 条回复
zhicheng
2016-03-03 14:54:30 +08:00
1. 优化写入,优化一下 MySQL 的参数,甚至极端一些关掉日志等。
2. 优化计算,聚合计算和数据存储分开,保存聚合计算的结果,在这个结果之后做增量计算。
3. 精度换速度,自己实现聚合函数,提供几个关键词, bloomfilter, hyperhyperlog 。
lynnworld
2016-03-03 15:17:59 +08:00
话说 6m 是 6 百万条日志嘛?那一天不都有上千亿日志了。平均日志大小是多少啊?
kier
2016-03-03 15:36:14 +08:00
6 兆吧,一条日志就算有 200 字节,那么大概 3W 条每秒?
solu
2016-03-03 15:39:29 +08:00
/dev/shm , load data infile 不知道能扛多少
iyaozhen
2016-03-03 15:50:08 +08:00
@lynnworld 流量, 6MB/s (高峰)。一天差不多快 10 亿条日志了。
zeeler
2016-03-03 16:00:43 +08:00
日志建议用 mongodb 之类的 nosql 数据库
realpg
2016-03-03 16:09:44 +08:00
@iyaozhen
有没有试过 insert delayed into
wweir
2016-03-03 16:13:56 +08:00
MySQL 有一个存储引擎是专门干日志这些个破事的。叫 Archive ,可以尝试一下。
话说存这些个死的数据,直接压缩一下放那多好。非要存数据库,还非要要关系型数据库。
vus520
2016-03-03 16:19:56 +08:00
elk ,生产中 10 台服务器,两个 logstash 可以做到 4k 左右的写入速度
ango
2016-03-03 16:26:53 +08:00
多级(如: IP/date/module/……)划分目录,直接同步到一台日志文件服务器(硬盘大、内存大),不管你是要定位或者清洗什么数据,直接 python 或者 shell 脚本定制,这样的处理挺快的,后期将定制基本集中起来做个管理化系统。

目前对于上百台服务器程序输出的日志,这样使用还没发现什么不方便或者大问题。
iyaozhen
2016-03-03 16:27:21 +08:00
@zeeler 谢谢,正在调研。 mongodb 没怎么实际用过,主要是怕从一个坑跳到另一个坑中。
iyaozhen
2016-03-03 16:27:51 +08:00
@realpg 试过,然后数据库扛不住了。 233333
xgdyhaiyang
2016-03-03 16:27:59 +08:00
之前用 C 写过一个专门往 MYSQL 写日志的系统,支持自定义配置字段,支持自动分表和按自然时间切换表,支持缓存批量入库,支持队列抵御高峰。,支持删除过期数据。

https://github.com/haipome/logdb

之前测试过 MYSQL 用 myisam 存储引擎,每秒中写几万条没有问题的,一天 10 亿应该也扛得住。
yuankui
2016-03-03 16:28:56 +08:00
我们的日志规模,现在是每秒 4 万条

用的 ELK

消息队列用的是 kafka,redis 不靠谱!

后来 logstash 出现了严重的性能问题,cpu 占用超过应用本身,我们又用 Java 语言重写了 logstash(没用实现 DSL),性能提高了 10 倍.

现在系统没啥压力.

不够话说性能指标相关的,完全可以 metrics+influxdata+grafana 来做,可以大大减少数据量的存储
iyaozhen
2016-03-03 16:31:42 +08:00
@ango 嗯嗯,日志转存这个其它地方也在做。主要是现在还有对数据流监控的需求。
realpg
2016-03-03 16:31:56 +08:00
@iyaozhen
你数据库服务器存储的 IO 性能如何?
我这边的这种密集清一色带缓存混合阵列,写数据库速度飞快。
因为日志这种, SSD 实在玩不起……
iyaozhen
2016-03-03 16:41:11 +08:00
@yuankui 嗯,谢谢。应该实现多看看业界是怎么搞的。不能自己瞎搞,关键是自己还很菜。
iyaozhen
2016-03-03 16:42:23 +08:00
@realpg 线上机器的话应该是 16/32 核, 128 内存。但硬盘不是 SSD 的。。。
realpg
2016-03-03 16:43:41 +08:00
@iyaozhen
我说的就是你的磁盘,读写性能如何。
你说的 MYSQL 死了应该不是 CPU 爆了,就是卡 IO 了,明显 IO 瓶颈了啊。
lynnworld
2016-03-03 16:55:27 +08:00
"
因为数据聚合处理使用的是 Redis 的 hash 数据结构做计数器,需要和 Redis 有几次交互,单个脚本的处理速度为 0.03M/s (已经优化过了),开 200+ 个进程数据聚合这块应该是抗的住的
"
假设 3w 记录 /s , redis 估计也要 10w+的 qps 了。看能不能优化计算流程。

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/260806

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX