最近遇到的一个架构问题 - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Livid
141.11D
531.92D
V2EX    编程

最近遇到的一个架构问题

  •  
  •   Livid
    PRO
    2012-09-18 14:46:47 +08:00 7572 次点击
    这是一个创建于 4796 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近朋友那里遇到的一个架构问题,但是我目前正在有一个项目进行中,时间紧迫,所以实在不能分身去做。但是问题本身很有意义,所以就把完整问题发出来,或许会给 V2EX 的同学带来一些灵感。

    一台服务器上用 nfcapd 每 5 分钟记录下一个文件,netflow 格式。netflow 是一种流量日志,里面的每条记录是类似这样的:

    Date flow start Duration Proto Src IP Addr:Port Dst IP Addr:Port Packets Bytes Flows
    2005-08-30 06:59:52.338 0.001 UDP 36.249.80.226:3040 -> 92.98.219.116:1434 1 404 1

    关于 nfdump 的更多资料: http://nfdump.sourceforge.net/

    每 5 分钟生成的 nfdump 文件中,差不多有 15 - 25 万条这样的记录。也就是说,一天的数据量会超过 5000 万条。

    现在需要这样的一个系统:

    - 索引大概一到两个月的数据量(每天都会有新数据写入)
    - 输入起始 IP 地址,结束 IP 地址(能够支持子网掩码更好),并选择一段时间(比如一天、一周),然后计算出在这段时间内的流量,并生成流量图表
    - 也可以只输入起始或结束 IP 地址,选择时间段后,生成这个 IP 上的所有流入或是流出的流量

    我自己做了一些试验,假如用把这些数据导入 MySQL 的方式来实现的话(列类型全部是 unsigned int),每 5 分钟的数据差不多会占用 8M 左右的空间,并占用大概 3M 左右的索引空间。这样的话,一天的数据量差不多就是 2.5G,索引差不多就是 800M 左右。

    这是一个很有意思的问题。

    如果你来实现这个系统,你会怎么做呢?包括后端的语言和数据库选择,及前端和绘图组件的选择?
    18 条回复    1970-01-01 08:00:00 +08:00
    Livid
        1
    Livid  
    MOD
    OP
    PRO
       2012-09-18 14:49:16 +08:00   1
    另外就是,nfsen 能够搞定这种量级的数据么?希望能够有用过的同学分享一些心得。谢谢。
    virushuo
        2
    virushuo  
       2012-09-18 14:53:55 +08:00
    用map reduce。

    我没弄过5000这么多,但是500万还是弄过的,而且要做的分析比这个复杂。
    aveline
        3
    aveline  
       2012-09-18 14:57:56 +08:00
    是 C3 那的么 ...

    其实 ... 觉得这么详细的数据并没有必要 ...
    Radeon
        4
    Radeon  
       2012-09-18 14:58:08 +08:00
    这是一个很典型的OLAP问题,建议用专门的OLAP工具(如SQL Server SSAS)建Hypercube来做。自己用MySQL建静态表的方式很不灵活。
    helldragon
        5
    helldragon  
       2012-09-18 14:58:56 +08:00
    唔。。日志分析系统么?直接做查询的话是不是数据量太大了?既然是插入查询不修改的话,用数据仓库的思想去做比较好吧,做一些数据预处理。绘图的话要求不太高的话,HighChart之类的都可以吧
    Livid
        6
    Livid  
    MOD
    OP
    PRO
       2012-09-18 15:00:03 +08:00
    @aveline 香港某数据中心的流量。
    aveline
        7
    aveline  
       2012-09-18 15:00:42 +08:00
    之前 LibVZ 采用的方案是这样 ... 有点落后但是嗯还算能用

    每个 IP 每 5 分钟采样一次流量数据计入 Node 上的 Sqlite,这个 Sqlite 每个月清空一次。

    主控获取数据的时候通过 API 读取 Sqlite 做 SUM 等操作

    然后中心数据库只保存按小时的每个IP的流量数据,绘图的话 rrdtool 就可以了。

    就是这样 ...
    ftao
        8
    ftao  
       2012-09-18 15:28:59 +08:00
    如果IP数目是可控的吧。互联网上客户端的IP应该不需要区分统计流量吧。 

    首先聚合成 (ts 的精度5分钟)
    ts src_ip, dst_ip , recv_bytes, send_bytes
    如果IP数目是可控的,那这个数量级不会很大吧?

    为了保证查询速度, 可以每小时再聚合一次,另存一份。

    如果一天的数据量不超过500M了, 或者不在意花钱。。
    可以考虑像 http://splunk.com 这样的工具。

    我们有一些工具是自己做好聚合, 然后丢给 splunk 做展示。
    clowwindy
        9
    clowwindy  
       2012-09-18 15:34:51 +08:00
    HBase + MapReduce + rrdtool 搞定这个问题应该很轻松。
    naoki
        10
    naoki  
       2012-09-18 15:56:20 +08:00
    rrdtool +1
    diamondtin
        11
    diamondtin  
       2012-09-18 16:00:06 +08:00
    这样的数据如果查询的时间单位是按天的话,是适合做一下map-reduce的。这样数据量会小很多(按照上面样例数据会小几个数量级)。处理过的每个ip的流入流出流量按日期计入数据库,这样mysql或postgres保存两个月的应该没啥问题,而且查询网段的时候比较容易实现。

    如果查询的时间单位比较细的话,那么每条数据尽量都要保存,那么存在面向列的数据库里面比较合适,HBase是比较常见的选择。这样需要选择好每个属性的排序规则,但是我还是觉得查询起来肯定很慢。最好配合另外一个批处理的服务(MR)生成常查询数据的每日汇总结果,应付绝大多数的查询。
    adieu
        12
    adieu  
       2012-09-18 16:00:28 +08:00
    如果只统计某ip产生的流入和流出的流量,我觉得在处理这些数据的时候可以设计数据老化的方案,可以把数据精确度分几个级别,比如:

    - 1天之内的数据保存5分钟采样的数据
    - 2周之内发生的数据保存1小时采样的数据
    - 3个月到2周之内的数据保存1天采样的数据
    - 3个月以上保存1周采样的数据

    对于这种会老化的时间序列数据,如果用关系型数据库来保存,就不是那么方便了,这里推荐使用Graphite http://graphite.wikidot.com/

    另外这里 http://www.aosabook.org/en/graphite.html 有一篇介绍Graphite的文章,可以喵一眼

    通过引入数据老化,需要保存的数据量会大大下降,而且每个ip需要占用的磁盘空间基本上是固定的,如果会采集到的ip个数是比较固定的话,那么磁盘的使用会相对平稳,可以保证长时间运行而不需要一直去维护。另外Graphite本身是支持cluster的,如果一台服务器装不下所有数据,可以用多台服务器组成cluster来提供服务。

    后端的话使用Graphite自带的whisper和carbon就行,前端的话Graphite的前端做的不太好,可以自己开发一个。我是用 Cubism.js http://square.github.com/cubism/ 以及 Rickshaw http://code.shutterstock.com/rickshaw/ 分别实现了实时和分非实时的Graphite数据展示界面,可以参考。

    后面的事情就比较简单了,输入ip地址段以及时间,程序读取这个段里面的ip地址所对应的数据文件,进行一个过滤以及加总,放到前端去展示就可以了。

    不过这个方案仅仅对流量统计有效,对于 @Livid 提出的第二个需求,输入ip地址段以及时间,生成所有的流入和流出流量,没办法用Graphite直接实现,因为Graphite不能直接保存多个维度的数据。如果要用Graphite来做,可能要设计一个组合key的方案,有一定的复杂度,我还没法一时想清楚,在这里就不继续深入了。
    cabinw
        13
    cabinw  
       2012-09-18 17:14:13 +08:00
    搬板凳,学习
    qiuai
        14
    qiuai  
    PRO
       2012-09-18 17:17:35 +08:00
    @livid 求推荐数据中心.看能不能合作.
    Email: [email protected]
    Q: 39831817
    summic
        15
    summic  
       2012-09-18 17:54:11 +08:00
    我这有个案例,每天新增日志50亿条左右。
    用简单的架构实现了海量数据实时查询。

    这层窗户纸就是基于sphinx搜索引擎。sphinx本身支持分布式搜索。
    forest520
        16
    forest520  
       2012-09-18 18:15:08 +08:00
    看看pentaho吧,存储查询报表,什么都有了
    jamiesun
        17
    jamiesun  
       2012-09-24 16:06:38 +08:00
    我做过的一个系统和这个很相似,就是一个dns日志分析系统,一台DNS服务器,8核cpu8G内存1T硬盘,每日解析量4000W,大概每天8G-10G的数据文件,最多保存2个月日志,

    需求:

    1,需要提供详细日志查询,根据客户IP或域名查询,这个查询压力很大,在单台服务器上,我只能做到按小时查询(几百万的量过得去),当然这个查询其实做到小时查询已经足够,相关管理员也就是想查查某个ip在某个时间点的活动情况。

    2,需要单日ip在24小时的解析量趋势图
    3,需要单日活跃ip top 10 -- 100统计图
    4,需要单日单个域名在24小时的解析量趋势图
    5,需要单日活跃域名top10 -- 100统计图


    资源有限,只有两台服务器(主/备),所以神马分布式就别想了。服务器日志每小时统计一次,统计方法很简单,python+awk,统计后生成文本,每天的日志文件也切割重命名,对所有文件生成索引文件。

    索引文件也不小,通过mmap映射后提供查询,实时统计表生成,cherrypy做的管理界面,目前运行还算稳定,不过我也不是很满意,在文件索引上耗费了大量功夫。感觉就是在设计一个数据库。

    别提mysql了,超过200G后怎么优化都不顶用。别用啥数据库了,用的话也就是存储汇总数据。


    如果有充足的服务器资源的话,我倒是建议对数据按特征切分然后分发处理,也就是map/reduce了

    不过单机牛B我觉得没什么干不了的,我用过24核64G的机器处理几千万的数据,眼睛眨巴下就完成了。
    iwinux
        18
    iwinux  
       2012-09-24 17:58:09 +08:00
    “每 5 分钟生成的 nfdump 文件中,差不多有 15 - 25 万条这样的记录。”

    这个要怎样获得有效的测试数据呢
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2398 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 28ms UTC 00:02 PVG 08:02 LAX 16:02 JFK 19:02
    Do have faith in what you're doing.
    ubao msn 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