哪个数据库可以处理数十亿/万亿记录的存储?


75

我们正在研究开发一种捕获和分析Netflow数据的工具,我们从中收集了大量的数据。每天我们都会捕获大约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"
}

我们希望能够在数据集上进行快速搜索(不到10秒),很可能是在很短的时间内(10到30分钟的间隔)。我们还希望对大多数数据点建立索引,以便我们可以快速搜索每个数据点。我们还希望在执行搜索时具有最新的数据视图。留在开源世界中将是很棒的,但是我们并不反对为该项目寻找专有的解决方案。

想法是保留大约一个月的数据,即约432亿条记录。粗略估计,每条记录将包含约480字节的数据,相当于一个月内约18.7 TB的数据,可能是索引的三倍。最终,我们希望提高该系统存储万亿记录的能力。

到目前为止,我们已经(非常基本)评估了长沙发,cassandra和mongodb的候选人,但是每个人都提出了自己的挑战。使用couchbase时,索引是每隔一段时间而不是在数据插入期间完成的,因此视图不是最新的,cassandra的二级索引返回结果的效率不是很高,因为它们通常需要扫描整个集群以获取结果,而mongodb看起来很有希望,但由于它是主/从/分片的,因此似乎很难扩展。我们计划评估的其他一些候选对象是elasticsearch,mysql(不确定这是否适用)和一些面向列的关系数据库。任何建议或现实世界的经验将不胜感激。


评论不作进一步讨论;此对话已转移至聊天
保罗·怀特

Answers:


57

在我工作的一家公司中,我们正在处理相似数量的数据(大约10 TB的实时可搜索数据)。我们用Cassandra解决了这个问题,我想提出几个想法,这些想法将使您可以在多TB的数据库上进行O(1)搜索。但是,这并非特定于Cassandra db,您也可以将其与其他db一起使用。

理论

  • 分片数据。单个服务器无法可靠地现实地保存如此大量的数据。
  • 准备好应对硬件故障和整个节点故障,复制数据。
  • 从一开始就开始使用许多后端服务器。
  • 与高端高性能服务器相比,使用许多便宜的商品服务器。
  • 确保数据在各个分片上平均分配。
  • 花很多时间计划您的查询。从查询中派生API,然后仔细设计表。这是最重要和延长的任务。
  • 在Cassandra中,您可以设计一个复合列键并在O(1)中访问该键。花时间在他们身上。这将用于访问可搜索记录,而不是辅助索引。
  • 利用宽行。它们对于存储带时间戳的事件很有用。
  • 在此卷上,切勿执行全扫描或实际上除O(Log N)以外的任何操作。如果您需要的不是O(Log N),则将此类操作卸载到Map-Reduce算法中。

实践

  • 不要花时间在物理机上构建OS映像或安装服务器。使用基于云的提供商进行快速原型制作。我曾与Amazon EC2一起工作过,并因其简单性,可靠性和原型制作速度而极力推荐它。
  • Windows计算机在启动时趋向于变慢,并且处于空闲状态时会占用大量资源。考虑使用基于Unix的操作系统。就个人而言,我发现Ubuntu服务器是可靠的操作系统,但是Askubuntu上有一个相当不错的社区
  • 考虑网络,理想情况下,节点应彼此靠近,以允许快速闲聊和元数据交换。
  • 请勿进入极端情况:列行非常宽或列族(表)特别长。在合理的范围内可获得最佳性能-如果db 通过设计支持那么多N行,这并不意味着它表现良好。
  • 我们的搜索大约需要3-5秒,这主要归功于UI和数据库之间的中间节点。考虑如何使请求更接近数据库。
  • 使用网络负载平衡器。选择一个已建立的。我们使用HAProxy,这很简单,但是速度很快。从来没有问题。
  • 更喜欢简单而不是复杂的解决方案。
  • 寻找免费的开源解决方案,除非您得到公司规模预算的支持。一旦使用了多台服务器,基础架构的成本可能会很高。

我不在Amazon工作,与HAProxy和Ubuntu团队没有任何关系。这是个人观点,而不是任何形式的宣传。


5
我非常确定,除了极其琐碎/无用的情况之外,O(1)搜索是不可能的。
菲茨西蒙斯

2
请不要冒犯,但请告知Google。经过精心设计,可以在PB规模上进行O(1)搜索。
oleksii

9
@oleksii十亿美元Google预算不是一个合理的比较。
Mark Storey-Smith

4
我可以连接以前的3条评论O(1) search <=> unbounded storage space <=> unlimited supply of cash
ypercubeᵀᴹ

3
O(1)搜索单个记录可以使用线性哈希表完成。。但是,这不会给您顺序搜索(范围)的任何效率。为此,您需要某种BTree结构的变体,对于单个项目,该结构为O(log n)。
ConcernedOfTunbridgeWells

41

如果我打算将其放入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 */
);

这样就得出了单个表的估计总存储需求,而对于43.2个蜂记录,则没有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字段对于每条记录都是唯一的,并允许按记录的顺序对行进行排序(在这种情况下,很可能是一对一地关联到流程事件发生的时间)。


4
我可能会分别使用binary(4)binary(16)。4字节/行乘以1,000,000,000,000会增加很多存储空间。
乔恩·塞格尔

2
端口号的范围是0-65535,因此您可以使用它,SMALLINT但那里也必须有一个转换例程。
ypercubeᵀᴹ

7
@先生,我不同意。仅当您需要HA或大量故障转移之类的东西时,在SQL Server中执行此操作的开销很大。对于真正易于使用的可靠数据存储,SQL Server对此非常有用。如果需要HA,所有系统都会变得非常昂贵(而且很复杂)。
samsmith

2
IMO,SQL Server绝对可以存储数据;我仍然不确定这是否是解决项目分析部分的正确解决方案,主要是因为我对所考虑的其他系统不够熟悉。
乔恩·塞格尔

3
@MrTelly有两个开销:a)磁盘存储(5-8 tb,取决于索引使用的空间)b)RAM(用于支持查询,索引缓存)。通常使用大型RAID10阵列或SAN来单片地执行此操作。但是,请注意,分片当然可以完成,并且可以让您使用应用程序级逻辑来分摊多个SQL Server上的工作负载。这样一来,您可以使用便宜的服务器(每台服务器0.5-2tb),甚至可以使用免费的SQL Server版本。(请注意,分片是一个通用概念,通常在应用程序级别完成,并且适用于任何持久性方法)
samsmith 2013年

5

我会推荐HBase。您可以根据查询的内容将所有原始数据存储在一个或多个HBase表中。HBase可以处理大型数据集,并可以通过区域划分自动进行分片。

此外,如果您设计好行键,即使O(1)查询也可以非常快。请注意,如果要检索大数据集,由于检索数据是O(n)操作,因此速度仍然很慢。

由于您要查询每个字段,因此建议为每个字段创建一个唯一的表。src_address数据的示例具有一个如下表:

1.2.3.4_timestamp1 : { data }
1.2.3.4_timestamp2 : { data }

因此,如果要查询从Mar 27 12:00 AM到Mar 27 12:01 AM开始的1.2.3.4中的所有数据,则可以使用指定的开始行和停止行进行范围扫描。

恕我直言,行键设计是使用HBase的最关键部分-如果设计得当,您将能够进行快速查询并存储大量数据。


3

这样说:

...我们不反对为该项目寻找专有解决方案

我建议考虑使用IBM Informix数据库 + TimeSeries datablade。与某些人所说的相反,Informix还活着并且运行得很好。最新版本于上个月发布(2013年3月,版本12.10)。

TimeSeries就像一个“插件”(免费),能够处理您这样的情况。
您可以将其与免费版本的Informix数据库(版本Innovator-C)一起用于生产中。(当然,由于免费版的资源有限,因此只能评估技术部分)

在这里,您可以检查基准的PDF内容,以作为参考。这里有两个演示文稿,其中包含更多技术示例:傻瓜指南其他技巧

我没有使用TimeSeries的个人经验,所以我无法同意它将是“解决方案”,只是评估的建议。


2

我第二次推荐来看Informix TimeSeries。IBM文献声称TimeSeries可以将这种信息存储在空间的1/5中,并且执行速度是传统关系表的5倍。

额外的好处是可以使TimeSeries数据像传统的关系表一样显示给最终用户(简化应用程序开发,同时仍然获得TimeSeries的好处)的虚拟表接口,带有HDR节点的简单HA(现在支持版本12.1)和将TimeSeries数据集成到Informix Warehouse Accelerator中,可用于加快复杂的数据仓库报告的速度,并能够使用免费的Informix Developer或Innovator-C版本在Informix中对TimeSeries解决方案进行原型设计。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.