可以建议大型关系数据分析器的解决方案吗?

时间:2016-01-18 05:10:52

标签: mysql elasticsearch rdbms apache-spark-sql opentsdb

我正在寻找有关我的要求的一些建议。以下是我的要求说明。如有任何疑问,请随时与我联系。甚至一些关于如何更清楚地描述我的问题的建议也非常感激:)

需求说明

我有一些数据,格式如下: router, interface,timestamp, src_ip, dst_ip, src_port, dst_port, protocol, bits r1, 1, 1453016443, 10.0.0.1, 10.0.0.2, 100, 200, tcp, 108 r2, 1, 1453016448, 10.0.0.3, 10.0.0.8, 200, 200, udp, 100

如您所见,它是一些网络原始数据。我省略了一些列只是为了让它看起来更清晰。数据量非常大。它产生的速度非常快,每5分钟产生10亿行...

我想要的是对这些数据进行实时分析。 例如:

使用时间戳

绘制一条线
  

选择sum(bits),来自raw_data group by router的时间戳,interface = interface = 1,router = r1。

找出哪个3 src_ip为一个界面发送最多数据

  

从raw_data中选择sum(bits),其中router = r1,interface = 2 group by src_ip order by sum(bits)desc limit 3

我已经尝试了一些解决方案,但每个解决方案都不适合它。例如:

RDBMS

除了一些问题外,MySQL似乎很好:

  
      
  1. 数据太大
  2.   
  3. 我的专栏比我在这里描述的要多得多。为了提高我的查询速度,我必须对大多数列进行索引。但我认为在大表上创建索引并且包含太多列的索引不是很好,对吧?
  4.   

openTSDB

OpenTSDB是一个很好的时间序列数据库。但也不适合我的要求。

  

openTSDB有解决TOP N问题的问题。在我的要求“获得发送大多数数据的前3个src_ip”中,openTSDB无法解决这个问题。

火花

  

我知道apache spark可以像RDBMS一样使用。它具有名为spark SQL的功能。我没试过,但我猜性能不应该满足实时分析/查询要求,对吧?毕竟,spark更适合离线计算,对吗?

弹性搜索

  

当我知道这个项目时,我真的非常希望ES。但它也不合适。因为聚合多个列时,必须在elasticsearch中使用所谓的嵌套桶聚合。并且无法对此聚合的结果进行排序。您必须检索所有结果并按自己排序。就我而言,结果太多了。对结果进行排序将非常困难

所以....我被困在这里。请问有人可以提出一些建议吗?

2 个答案:

答案 0 :(得分:1)

我不明白为什么ES无法满足您的要求。我想你误解了这一部分

  

但它也不合适。因为聚合多个列时,必须在elasticsearch中使用所谓的嵌套桶聚合。并且无法对此聚合的结果进行排序。

您的第一个要求使用时间戳绘制一条线可以通过这样的查询/聚合轻松实现:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "interface": 1
          }
        },
        {
          "term": {
            "router": "r1"
          }
        }
      ]
    }
  },
  "aggs": {
    "by_minute": {
      "date_histogram": {
        "field": "timestamp",
        "interval": "1m"
      },
      "aggs": {
        "sum_bits": {
          "sum": {
            "field": "bits"
          }
        }
      }
    }
  }
}

至于你的第二个要求找出哪个3 src_ip为一个接口发送最多的数据,它也可以通过像这样的查询/聚合轻松实现:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "interface": 2
          }
        },
        {
          "term": {
            "router": "r1"
          }
        }
      ]
    }
  },
  "aggs": {
    "by_src_ip": {
      "terms": {
        "field": "src_ip",
        "size": 3,
        "order": {
          "sum_bits": "desc"
        }
      },
      "aggs": {
        "sum_bits": {
          "sum": {
            "field": "bits"
          }
        }
      }
    }
  }
}

更新

根据您的评论,您上面的第二个要求可能会更改为找到src_ip / dst_ip的前3个组合。使用terms代替script聚合,而不是构建src / dest组合并为每对夫妇提供位总和的术语,这是可行的,如下所示:

{
  "query": {
    "bool": {
      "must": [
        {
          "term": {
            "interface": 2
          }
        },
        {
          "term": {
            "router": "r1"
          }
        }
      ]
    }
  },
  "aggs": {
    "by_src_ip": {
      "terms": {
        "script": "[doc.src_ip.value, doc.dst_ip.value].join('-')",
        "size": 3,
        "order": {
          "sum_bits": "desc"
        }
      },
      "aggs": {
        "sum_bits": {
          "sum": {
            "field": "bits"
          }
        }
      }
    }
  }
}

请注意,要运行此最后一个查询,您需要enable dynamic scripting。此外,由于您将拥有数十亿份文档,脚本编写可能不是最佳解决方案,但在进一步深入探讨之前值得尝试一下。另一种可能的解决方案是在索引时添加combination字段(src_ip-dst_ip),以便您可以将其用作术语聚合中的字段,而无需使用脚本。

答案 1 :(得分:1)

您可以尝试Axibase Time Series Database这是非关系型的,但除了类似rest的API之外还支持SQL查询。这是一个前N个查询示例:

SELECT entity, avg(value) FROM cpu_busy 
  WHERE time between now - 1 * hour and now 
  GROUP BY entity 
  ORDER BY avg(value) DESC 
  LIMIT 3

https://axibase.com/docs/atsd/sql/#grouping

ATSD社区版是免费的。

披露:我为Axibase工作