数据包捕获到数据库?

时间:2009-05-29 23:22:50

标签: c# .net database

我是数据库/ PC应用程序的完全新手请原谅我的无知。

我想实时捕获数据包到数据库,以便多个应用程序能够监视通过PLC的udp数据包返回的物理I / O数据,我有几个问题。

从长远来看,它需要跨平台,但目前我在Windows中使用C#数据包捕获库。有关数据库类型MySQL vs SQlite的任何建议吗?

每秒大约1500个200字节的数据包,每秒插入1500个数据包是否可行?我已经读过SQlite在concurency方面有一些问题,如果我有一个应用程序查询数据库中的数据包数据〜在25-50ms延迟时间内每秒10次 - 这是可行的吗?

我希望“只”需要在任何时候在数据库中存储20MB左右的数据。是否可以强制数据库仅在内存中运行?在写分组数据时,数据包(字节数组)可以写在一个语句中而不是迭代地插入每个字节/字吗?我想我可以把它变成一个字符串,但我希望这几乎不可能以任何速度查询。在我简要介绍的任何数据库中,我都没有看到任何类似“字节数组类型”的内容。 FWIW所有数据都来自静态IP上的专用NIC。数据包是顺序的(我知道它不能保证UDP,但我从来没有看到过一个乱序)如果数据库支持数组类型,我可以轻松地跨越数据。 - 这是好的,没有随机搜索?

感谢您花时间阅读本文。

鲍勃

3 个答案:

答案 0 :(得分:2)

您在关系数据库中寻找的优势是什么?既然你说你对数据库的了解不多,这里简要说明为什么SQL是一个选项,也许它可以帮助你澄清你的要求和你的选择:

  1. 查询能力。如果要公开 rich 搜索的数据,其中包括筛选记录,排序结果,聚合计算的选项,那么SQL数据库确实提供了这样的功能。他们不是免费来的。为了加快搜索速度,数据库引擎必须将部分数据复制到多个索引中,这会增加插入/更新时间,因为必须维护所有这些索引。
  2. 可恢复性。数据库可以确保数据在发生崩溃时保持一致状态。使用预写日志或版本化更新,他们以一种方式编写更改,而不是确保客户端在他的语句返回给他时所做的更改是持久的(为简单起见,我省略了一堆细节)。
  3. 一致性。通过隔离用户之间的更改,直到他们显式提交一组相关操作,数据库始终向查看器公开一致状态。为实现此目的,数据库必须部署锁定或版本控制。
  4. 可扩展性。数据库可以负责维护非常大的数据集,远大于流程可行的地址空间。他们将使用缓冲池来保持热页面的缓存,并管理底层文件 - 偏移 - 内存 - 地址映射以及从磁盘读取和写回更改所需的所有I / O.它们还会将多个文件显示为统一存储区域,从而超出操作系统文件大小限制(如果有)。
  5. 互操作性。其他进程可以使用标准库(即ODBC,ADO等)和语言(SQL)来操作数据,因此无需开发自定义库/访问API。
  6. 现在,你的场景需要这些吗?还有什么我省略了吗?我问这些问题,因为你想要达到的目标并非微不足道。您可以相对轻松地实现每秒1500次插入,但更难以实现提供良好的读取性能。此外,关系数据库提供的大部分内容(一致性,可恢复性,可伸缩性)似乎都不是您的目标。有许多产品专门针对内存中的利基进行了调整,这些产品比从典型的面向磁盘的关系数据库中获得的产品快得多。

答案 1 :(得分:0)

编辑:我忘了你在C#工作。

首先,您打算从多台计算机查询数据库吗?如果是这样,你会想要使用MySQL。否则,SQLite可能是一个不错的选择。但请注意,MySQL可能是多个C#应用程序和内存数据库所必需的。如果选择MySQL,请使用MySQL Connector/NET。对于SQLite,有System.Data.SQLite(我已经用于WinForms应用程序,可以推荐)。

你说你需要每个语句做1500个200字节的插入语句。 SQLite reports每秒可以做到50,000次。关键的警告是,这是指原始插入,而不是事务。提交事务会减慢您的速度,因为这通常意味着刷新到磁盘。

SQLite(请参阅他们的In-Memory Databases)和MySQL(请参阅他们的MEMORY (HEAP) Storage Engine)都可以使用内存数据库。但是,对于SQLite,这可能会破坏让“多个应用程序”访问它的目标。使用SQLite,您可以共享内存数据库(例如,使用共享内存),这是一种未记录的(并且“无法保证在将来的SQLite版本中工作”)。它在prior SO question中进行了讨论;另请参阅SQLite主要作者的linked mail message。请注意,如果您坚持使用托管代码,则可能无法共享SQLite内存数据库。您绝对可以在多个客户端之间共享MySQL内存数据库。

使用C#客户端,您应该能够使用DbParameter(即SQLiteParameter或MySqlParameter)在一行中插入整个数据包。请特别注意Value和Size属性。

我认为你不需要任何“数组类型”。您可以简单地使用递增主键(INTEGER PRIMARY KEY)列和数据包内容列(BLOB或TEXT)。我不确定哪个BLOB或TEXT会为SQLite提供最佳性能。您的SQLite架构可能看起来像

CREATE TABLE packets ( id INTEGER PRIMARY KEY, packet BLOB);

然后,您可以轻松选择例如一定范围的主键内的数据包。当然,您可以添加日期时间列,但这需要索引。对于MySQL,它将类似于:

CREATE TABLE packets ( id INTEGER PRIMARY KEY, packet VARCHAR(200)) ENGINE=MEMORY;

我希望这会有所帮助。请记住,分析是确保哪种方法适用于您的应用的最佳方式。

答案 2 :(得分:-2)

libpcap,wireshark循环文件

环顾四周,与wireshark一起玩,看看它是如何实现类似结果的。

相关问题