som*_*ike 78 nosql rdbms mongodb sql-server cassandra
我们正在研究开发一种工具来捕获和分析我们收集的大量网络流量数据。每天我们捕获大约 14 亿条流记录,它们的 json 格式如下所示:
{
"tcp_flags": "0",
"src_as": "54321",
"nexthop": "1.2.3.4",
"unix_secs": "1352234521",
"src_mask": "23",
"tos": "0",
"prot": "6",
"input": "105",
"doctets": "186",
"engine_type": "0",
"exaddr": "2.3.4.5",
"engine_id": "2",
"srcaddr": "9.8.7.6",
"dst_as": "12345",
"unix_nsecs": "752265174",
"sysuptime": "2943529544",
"dst_mask": "24",
"dstport": "80",
"last": "2943523241",
"srcport": "52672",
"dpkts": "4",
"output": "111",
"dstaddr": "6.5.4.3",
"first": "2943517993"
}
Run Code Online (Sandbox Code Playgroud)
我们希望能够对数据集进行快速搜索(少于 10 秒),最有可能在很短的时间内(10 - 30 分钟间隔)。我们还希望索引大部分数据点,以便我们可以快速搜索每个数据点。我们还希望在执行搜索时拥有最新的数据视图。留在开源世界会很棒,但我们不反对为这个项目寻找专有解决方案。
这个想法是保留大约一个月的数据,这将是大约 432 亿条记录。粗略估计,每条记录将包含大约 480 字节的数据,相当于一个月内约 18.7 TB 的数据,可能是索引的三倍。最终,我们希望增加该系统存储数万亿条记录的能力。
我们已经(非常基本地)评估了 couchbase、cassandra 和 mongodb 作为这个项目的可能候选者,但是每个人都提出了自己的挑战。使用 couchbase,索引是每隔一段时间完成的,而不是在插入数据期间完成,因此视图不是最新的,cassandra 的二级索引在返回结果方面效率不高,因为它们通常需要扫描整个集群以获取结果,而 mongodb 看起来很有希望但是由于它是主/从/分片,因此扩展似乎要困难得多。我们计划评估的其他一些候选者是 elasticsearch、mysql(不确定这是否适用)和一些面向列的关系数据库。任何建议或现实世界的经验将不胜感激。
ole*_*sii 61
在我工作的一家公司,我们正在处理类似数量的数据(大约 10 TB 的实时可搜索数据)。我们使用 Cassandra 解决了这个问题,我想提几个想法,它们可以让您在多 TB 数据库上进行 O(1) 搜索。不过,这并非特定于 Cassandra db,您也可以将它与其他 db 一起使用。
我不为亚马逊工作,与 HAProxy 和 Ubuntu 团队没有关系。这是个人意见,而不是任何形式的宣传。
Han*_*non 43
如果我打算把它放到 SQL Server 中,我会建议一个类似的表:
CREATE TABLE tcp_traffic
(
tcp_traffic_id bigint constraint PK_tcp_traffic primary key clustered IDENTITY(1,1)
, tcp_flags smallint /* at most 9 bits in TCP, so use SMALLINT */
, src_as int /* Since there are less than 2 billion A.S.'s possible, use INT */
, netxhop bigint /* use a big integer for the IP address instead of storing
it as dotted-decimal */
, unix_secs bigint
, src_mask int /* an assumption */
, tos tinyint /* values are 0-255, see RFC 791 */
, prot tinyint /* values are 0-255, see RFC 790 */
, input int /* an assumption */
, doctets int /* an assumption */
, engine_type int /* an assumption */
, exaddr bigint /* use a big integer for the IP address instead of storing
it as dotted-decimal */
, engine_id int /* an assumption */
, srcaddr bigint /* use a big integer for the IP address instead of storing
it as dotted-decimal */
, dst_as int /* Since there are less than 2 billion A.S.'s possible, use INT */
, unix_nsecs bigint /* an assumption */
, sysuptime bigint /* an assumption */
, dst_mask int /* an assumption */
, dstport smallint /* ports can be in the range of 0 - 32767 */
, [last] bigint /* an assumption */
, srcport smallint /* ports can be in the range of 0 - 32767 */
, dpkts int /* an assumption */
, output int /* an assumption */
, dstaddr bigint /* use a big integer for the IP address instead of storing
it as dotted-decimal */
, [first] bigint /* an assumption */
);
Run Code Online (Sandbox Code Playgroud)
这导致单个表的总估计存储需求,对于 43.2 beeellion 记录(您指定的需求)没有 5.5 TB 的进一步索引。这计算为数据本身的 130 个字节,加上每行开销 7 个字节,加上每页开销 96 个字节。SQL Server 将数据存储在 8KB 页中,允许每页 59 行。这相当于一个月的数据有 732,203,390 页。
SQL Server 喜欢以 8 页块 (64KB) 的形式写入磁盘,这相当于每个物理 I/O 472 行。由于每秒生成 16,203 条流记录,因此您需要保证每秒 34 次 IOps 的最低 I/O 速率。虽然这本身并不是一个巨大的数量,但系统中的其他 I/O(SQL Server 和其他)需要永远不会侵犯这个必要的 IOps 速率。因此,您需要设计一个至少能够提供一个数量级的 IOps 或 340 个持续 IOps 的系统——我倾向于估计您需要 2 个数量级的更可持续的 IOps 来保证吞吐量。
您会注意到我没有以点分十进制形式存储 IP 地址。这节省了大量存储空间(每个地址 7 个字节),并且还使索引、检索、排序和比较 IP 地址的效率大大提高。这里的缺点是您需要在存储之前将点分十进制 IP 转换为 8 字节整数,然后再转换回点分十进制 IP 以进行显示。执行此操作的代码很简单,但是您的行速率会为正在处理的每个流行增加大量处理开销 - 您可能希望在物理上与 SQL Server 不同的计算机上执行此转换过程。
讨论您需要的索引是完全不同的事情,因为您没有列出任何具体要求。该表的设计将按照 SQL Server 接收到的物理顺序存储流行,该tcp_traffic_id字段对于每条记录都是唯一的,并允许按记录的顺序对行进行排序(在这种情况下很可能是一对一相关的)到流事件的时间)。
我会推荐HBase。您可以将所有原始数据存储在一个或多个 HBase 表中,具体取决于您需要查询的内容。HBase 可以处理大型数据集并通过区域拆分进行自动分片。
此外,如果你设计好行键,你可以获得极快的速度,甚至 O(1) 查询。请注意,如果您正在检索大型数据集,那仍然会很慢,因为检索数据是一个 O(n) 操作。
由于您想跨每个字段进行查询,我建议为每个字段创建一个唯一的表。src_address 数据的示例,有一个如下所示的表:
1.2.3.4_timestamp1 : { data }
1.2.3.4_timestamp2 : { data }
Run Code Online (Sandbox Code Playgroud)
因此,如果您想查询从 3 月 27 日凌晨 12:00 到 3 月 27 日凌晨 12:01 之间 1.2.3.4 的所有数据,您可以使用指定的开始和停止行进行范围扫描。
恕我直言,行键设计是使用 HBase 最关键的部分——如果你设计得好,你将能够进行快速查询并存储大量数据。