V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Livid
V2EX  ›  编程

最近遇到的一个架构问题

  •  
  •   Livid · 2012-09-18 14:46:47 +08:00 · 6794 次点击
    这是一个创建于 4236 天前的主题,其中的信息可能已经有所发展或是发生改变。
    最近朋友那里遇到的一个架构问题,但是我目前正在有一个项目进行中,时间紧迫,所以实在不能分身去做。但是问题本身很有意义,所以就把完整问题发出来,或许会给 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
       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
       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  
       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   ·   我们的愿景   ·   实用小工具   ·   1031 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 30ms · UTC 19:39 · PVG 03:39 · LAX 12:39 · JFK 15:39
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.