高并发( 6M/s)日志数据如何准实时入库( MySQL) - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
请不要在回答技术问题时复制粘贴 AI 生成的内容
iyaozhen
V2EX    程序员

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

  • nbsp;
  •   iyaozhen
    iyaozhen 2016-03-03 13:55:42 +08:00 18724 次点击
    这是一个创建于 3509 天前的主题,其中的信息可能已经有所发展或是发生改变。

    目前已经使用 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 ,用于定位问题)。

    60 条回复    2019-02-20 15:51:07 +08:00
    fds
        1
    fds  
       2016-03-03 14:14:17 +08:00
    有必要写入数据库么? logstash 做些统计,把结果数据发送到 influxdb 什么的记录下来,显示在监控里就好了吧?非得存原始数据入库?
    jimrok
        2
    jimrok  
       2016-03-03 14:22:04 +08:00
    让数据库直接 load 数据会快很多,没有事务的保护。
    iyaozhen
        3
    iyaozhen  
    OP
       2016-03-03 14:24:31 +08:00
    @fds 额,确实需要原始数据做查询,用于定位问题。还要至少存一周
    swolf119
        4
    swolf119  
       2016-03-03 14:25:11 +08:00
    同感觉没必要入库,从上文来看,感觉入库的需求就是为了数据统计
    那么数据统计是直接读的 mysql 分析的吗
    iyaozhen
        5
    iyaozhen  
    OP
       2016-03-03 14:28:10 +08:00
    @jimrok 这个我也想过。但是还是数据量太大暂存的文件太多(应为分库分表了, load 的时候需要按库和表把文件生成好),会把磁盘的 inode 用完。
    kier
        6
    kier  
       2016-03-03 14:29:16 +08:00
    对 elk 不了解,我们是吧数据存入 mongodb 的,然后脚本定时统计结果,将结果数据入 mysql, 然后定期将 mongo 中的老的日志数据导出备份;
    iyaozhen
        7
    iyaozhen  
    OP
       2016-03-03 14:29:16 +08:00
    @swolf119 不只是数据统计,主要还是用于定位问题。
    lxf1992521
        8
    lxf1992521  
       2016-03-03 14:30:09 +08:00
    根据我的经验,可以使用 graylog+elasticsearch 试试;
    性能数据可以直接通过 graylog 的 RestAPI 获取,对应日志可以直接从 ES 文档数据库中获取;
    yahoo21cn
        9
    yahoo21cn  
       2016-03-03 14:30:30 +08:00
    数据库改成事务,弄一个 redis 队列存插入数据,单独一个进程每秒读取该进程一次写入数据库。
    iyaozhen
        10
    iyaozhen  
    OP
       2016-03-03 14:30:33 +08:00
    @kier 谢谢,我看看 mongodb ,对这个不是太了解。估计可行
    iyaozhen
        11
    iyaozhen  
    OP
       2016-03-03 14:32:40 +08:00
    @lxf1992521 非常感谢,已经在看 elasticsearch 了,其实我也是用的 ELK 这一套,只是因为一些历史原因,只用了一部分。 graylog 这还没接触过,我看看。
    iyaozhen
        12
    iyaozhen  
    OP
       2016-03-03 14:35:55 +08:00
    @yahoo21cn 用 myisam 存储的原因我已经说了, innodb 也试过,主要还是数据占用磁盘空间大,统计慢。「单独一个进程每秒读取该进程一次写入数据库。」我现在就是这样,已经 300+的进程在跑, redis 还是爆了。我不光是要入库,还要做一些实时聚合。
    lynnworld
        13
    lynnworld  
       2016-03-03 14:38:38 +08:00
    你的 insert 是批量 insert 的么,现在是解析耗时还是存入耗时多?
    kier
        14
    kier  
       2016-03-03 14:41:00 +08:00
    对了,你们的日志是 nginx 或者 webapp 的请求处理日志,还是业务的埋点数据?
    tabris17
        15
    tabris17  
       2016-03-03 14:41:12 +08:00
    看来你需要的是 spark
    fds
        16
    fds  
       2016-03-03 14:42:14 +08:00
    定位问题的话直接用 lnav 扫 log 不就行了?真的有必要数据库查询吗?
    elasticsearch 比较吃配置哦。
    有钱的话,直接上 http://www.splunk.com/

    其实你想用到数据库的什么功能呢?一些查询除非预先 index ,否则和直接遍历文本相比没有特别的优势呀。
    iyaozhen
        17
    iyaozhen  
    OP
       2016-03-03 14:43:14 +08:00
    @lynnworld 是批量的。两者都比较多。抱歉,这里没做具体的统计。
    因为是批量解析 10w 条日志,还要分库分表。其实单次 insert 还比较快,但并发高,数据库会锁表,有些请求就等待了。
    iyaozhen
        18
    iyaozhen  
    OP
       2016-03-03 14:44:15 +08:00
    @kier 业务埋点数据,一个用户请求会过服务器很多模块,每个模块都会打日志,所以量比较大。
    iyaozhen
        19
    iyaozhen  
    OP
       2016-03-03 14:45:06 +08:00
    @tabris17 这东西听说过,我研究下。
    iyaozhen
        20
    iyaozhen  
    OP
       2016-03-03 14:48:50 +08:00
    @fds 线上几十上百台机器,还在不同机房,每个机器还有 10+的模块,还是比较蛋疼,而且还要其它一些需求,比如定位查询结果可视化等。
    zhicheng
        21
    zhicheng  
       2016-03-03 14:54:30 +08:00
    1. 优化写入,优化一下 MySQL 的参数,甚至极端一些关掉日志等。
    2. 优化计算,聚合计算和数据存储分开,保存聚合计算的结果,在这个结果之后做增量计算。
    3. 精度换速度,自己实现聚合函数,提供几个关键词, bloomfilter, hyperhyperlog 。
    lynnworld
        22
    lynnworld  
       2016-03-03 15:17:59 +08:00
    话说 6m 是 6 百万条日志嘛?那一天不都有上千亿日志了。平均日志大小是多少啊?
    kier
        23
    kier  
       2016-03-03 15:36:14 +08:00
    6 兆吧,一条日志就算有 200 字节,那么大概 3W 条每秒?
    solu
        24
    solu  
       2016-03-03 15:39:29 +08:00
    /dev/shm , load data infile 不知道能扛多少
    iyaozhen
        25
    iyaozhen  
    OP
       2016-03-03 15:50:08 +08:00
    @lynnworld 流量, 6MB/s (高峰)。一天差不多快 10 亿条日志了。
    zeeler
        26
    zeeler  
       2016-03-03 16:00:43 +08:00
    日志建议用 mongodb 之类的 nosql 数据库
    realpg
        27
    realpg  
    PRO
       2016-03-03 16:09:44 +08:00
    @iyaozhen
    有没有试过 insert delayed into
    wweir
        28
    wweir  
       2016-03-03 16:13:56 +08:00 via Android
    MySQL 有一个存储引擎是专门干日志这些个破事的。叫 Archive ,可以尝试一下。
    话说存这些个死的数据,直接压缩一下放那多好。非要存数据库,还非要要关系型数据库。
    vus520
        29
    vus520  
       2016-03-03 16:19:56 +08:00
    elk ,生产中 10 台服务器,两个 logstash 可以做到 4k 左右的写入速度
    ango
        30
    ango  
       2016-03-03 16:26:53 +08:00
    多级(如: IP/date/module/……)划分目录,直接同步到一台日志文件服务器(硬盘大、内存大),不管你是要定位或者清洗什么数据,直接 python 或者 shell 脚本定制,这样的处理挺快的,后期将定制基本集中起来做个管理化系统。

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

    https://github.com/haipome/logdb

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

    用的 ELK

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

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

    现在系统没啥压力.

    不够话说性能指标相关的,完全可以 metrics+influxdata+grafana 来做,可以大大减少数据量的存储
    iyaozhen
        35
    iyaozhen  
    OP
       2016-03-03 16:31:42 +08:00
    @ango 嗯嗯,日志转存这个其它地方也在做。主要是现在还有对数据流监控的需求。
    realpg
        36
    realpg  
    PRO
       2016-03-03 16:31:56 +08:00
    @iyaozhen
    你数据库服务器存储的 IO 性能如何?
    我这边的这种密集清一色带缓存混合阵列,写数据库速度飞快。
    因为日志这种, SSD 实在玩不起……
    iyaozhen
        37
    iyaozhen  
    OP
       2016-03-03 16:41:11 +08:00
    @yuankui 嗯,谢谢。应该实现多看看业界是怎么搞的。不能自己瞎搞,关键是自己还很菜。
    iyaozhen
        38
    iyaozhen  
    OP
       2016-03-03 16:42:23 +08:00
    @realpg 线上机器的话应该是 16/32 核, 128 内存。但硬盘不是 SSD 的。。。
    realpg
        39
    realpg  
    PRO
       2016-03-03 16:43:41 +08:00
    @iyaozhen
    我说的就是你的磁盘,读写性能如何。
    你说的 MYSQL 死了应该不是 CPU 爆了,就是卡 IO 了,明显 IO 瓶颈了啊。
    lynnworld
        40
    lynnworld  
       2016-03-03 16:55:27 +08:00
    "
    因为数据聚合处理使用的是 Redis 的 hash 数据结构做计数器,需要和 Redis 有几次交互,单个脚本的处理速度为 0.03M/s (已经优化过了),开 200+ 个进程数据聚合这块应该是抗的住的
    "
    假设 3w 记录 /s , redis 估计也要 10w+的 qps 了。看能不能优化计算流程。
    hanwujibaby
        41
    hanwujibaby  
       2016-03-03 17:44:34 +08:00
    redis 在内存占用率比较高的情况下不太稳定,切到 kafka 之类的,数据的聚合可以在内存中算,不用放到数据库中再聚合。看下 spark 或者 storm 吧。
    9
        42
    9  
       2016-03-03 19:13:36 +08:00
    数据入 es ,用 es 的 api 做统计,统计后的数据入回 mysql ,不要直接入库到 mysql ,这是坑啊
    publicAdmin
        43
    publicAdmin  
       2016-03-03 19:20:48 +08:00
    对的。楼上 @9 的方案和我们之前处理方式一样。 用户打点数据,个人觉得你直接丢 mysql 无形中在给你自己增加压力,入库读库都存在风险,何不如丢类似于 es / hdfs/ influxdb 之类的天生自带索引查询的。
    wusuopuBUPT
        44
    wusuopuBUPT  
       2016-03-03 19:38:15 +08:00
    这种场景已经不适合 mysql 了,我们的数据处理流程是:
    flume 采集->kafka 队列->ETL 清洗->HDFS 存储->Hive 查询->BI 系统
    wusuopuBUPT
        45
    wusuopuBUPT  
       2016-03-03 19:39:57 +08:00
    上面是离线(非实时)的方案, 实时系统也在调研,一般会在 kafka 后面接入 storm/spark 做流式实时计算
    a591826944
        46
    a591826944  
       2016-03-03 19:47:07 +08:00
    之前做过类似的。不过不是日志。。就是用户的点击数据。
    因为是 http 请求。 php 接收 -> rabbitMQ -> storm -> mysql
    每天 3 亿左右 。。没达到你那么高。。。
    RangerWolf
        47
    RangerWolf  
       2016-03-03 21:09:52 +08:00   1
    我这边的解决方案是 Cassandra 集群~ 一开始不熟悉的话在设计表结构上是个大坑
    熟悉之后,还需要配上 Spark 集群来进行计算。 当然两边的配合又是一个大坑
    在搜索的时候,还需要让 Cassandra 加上 lucene 插件,不是官方推荐的 Solr

    想简单可以试试 Cassandra 官网推广的 DSE 。 初创企业(年利润 300M 美刀以内)没有 license 的问题~

    最高试过 3.9W 写请求 /s

    不知道你说的 6M/s 是大小 6MB 还是 600W 的写请求~ 如果是后者,爱莫能助啦~
    chendahui007
        48
    chendahui007  
       2016-03-03 21:31:30 +08:00
    以前搞过 ELK , 之前用 mongo ,也用过 mysql ,都不合适,建议 E 。 E 够强大,适合存储日志,如果用上 kafka ,还可以订阅日志
    tabris17
        49
    tabris17  
       2016-03-03 21:36:03 +08:00
    其实我在想,用 zmq 自己写一个分布式日志处理程序也不是太复杂
    lujiajing1126
        50
    lujiajing1126  
       2016-03-03 21:51:18 +08:00 via iPhone
    elk 。。队列可以选 kafka 。事实查询用 e 。同步写到 hbase 也可以做离线分析。。似乎用 storm 的也有
    xhat
        51
    xhat  
       2016-03-03 23:32:07 +08:00
    为什么没人提到 leveldb ?
    msg7086
        52
    msg7086  
       2016-03-04 02:00:14 +08:00
    1) 换 innodb ,切换成单表单文件模式
    2) 改掉刷日志模式 https://wiki.phoenixlzx.com/page/MySQL
    3) 考虑上混合 SSD 阵列,或者直接上 SSD 。
    zuo
        53
    zuo  
       2016-03-04 02:59:14 +08:00
    既然用上了 logstash 为什么不一步到位 输出到 Elasticsearch ,可以满足你后期的日志查询。做分析可以顺便把日志输出到 hdfs ,然后在结合 spark 或者 hadoop
    cobopanda
        54
    cobopanda  
       2016-03-04 09:27:29 +08:00
    用 ES 试试吧
    firefox12
        55
    firefox12  
       2016-03-04 11:15:51 +08:00
    如果数据库本身不是问题的话, 插入是美问题的。
    但是你 6M/s 按照你的量

    6*3600*24 /1024 每天 500G, 数据库会迅速垮掉 ,完全是个错误的设计。

    如果是在线查 log 的话, es 会好一点。 这种应用用 mysql 去做 并不好,统计应该靠应用去做。
    gushan
        56
    gushan  
       2016-03-08 14:39:47 +08:00
    日志数据直接存储 MySQL 在后期扩展还是有问题的,可以考虑下阿里云日志服务。
    1 )提供了简单接入客户端( https://yq.aliyun.com/articles/3228?spm=5176.team4.teamshow1.37.faH93Z
    2 )日志收集到服务端后提供多种消费方式:数据通道(类 Kafka )/数据投递( ODPS 、 OSS-组合 E-MapReduce Spark )/实时搜索( https://help.aliyun.com/document_detail/sls/user-guide/overview.html
    wujunze
        57
    wujunze  
       2016-06-09 21:06:01 +08:00
    Spark 你值得拥有!
    sumonian
        58
    sumonian  
       2017-12-01 14:09:40 +08:00
    elk 值得你拥有
    jemygraw
        59
    jemygraw  
       2018-07-11 18:51:39 +08:00
    你前端不应该用 redis,应该用 kafka。或者直接用七牛日志平台吧。
    PoetAndPoem
        60
    PoetAndPoem  
       2019-02-20 15:51:07 +08:00
    @xgdyhaiyang 你好,那轮子中文介绍打不开,不知道怎么使用
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2589 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 29ms UTC 05:09 PVG 13:09 LAX 22:09 JFK 01:09
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86