有效地实时处理数据并在C中推送数据库

时间:2013-12-04 20:59:24

标签: c linux multithreading file

我解决了我遇到的一个问题,需要帮助进一步调整以获得性能。

将有一个apache模块通过http协议接收请求并在几毫秒内响应。它处理输入参数并将其作为JSON记录放入缓存层。 (目前文本文件用作缓存)。

另一个异步模块读取JSON记录,烹饪它们并将它们推送到MongoDB中。这可以避免由于MongoDB性能下降而可能添加的http响应延迟。

在Load Balancer下将有多台计算机(目前为12台),并且预计每天会有100 M个请求,当JSON记录写入文本文件时,这些请求的大小约为10-15 GB。

基本上我正在寻找更好的数据提取解决方案。

关于在生产者消费者架构中使用ZeroMQ或RabbitMQ,

  1. 消息队列在内存队列中,可能无法在内存中消耗这么多数据。

  2. MongoDB中消耗的数据是重要的数据,如果消息队列由于某种原因导致消息队列崩溃/崩溃,我们就不会失去它。

  3. 请建议。

3 个答案:

答案 0 :(得分:1)

在这两种情况下看起来每个线程都与其他模块中的匹配线程耦合(通过固定文件或偏移量) - 这意味着如果其中一个模块本身比另一个模块慢,则仍会遇到瓶颈,如更快的模块的线程将未充分利用。

相反,您可以使用任务队列(或多个生产者的类似解决方案 - 多个消费者问题),并让每个线程在任何可用任务获得免费后从中选择。这样可以更加自由地平衡每个模块中的线程数。如果前端http模块用于例如比后端处理快2倍,你可以产生2倍以上的后端线程。

“价格”是你需要安全地维护共享队列(锁定等等)并确保它有效地完成并且没有死锁。

答案 1 :(得分:1)

你可以使用像RabbitMQ或ZeroMQ这样的东西,并将批量数据插入数据库,或根据需要扩展到其他服务器。

答案 2 :(得分:0)

您创建HTTP接收器线程以接收要记录的数据,将传入的数据推送到内存中的接收队列。您创建一个单独的数据库编写器线程,除了将所有接收到的数据排在内存中(通过接收器线程),将它们转换为具有多行的单个数据库INSERT,在单个事务中发送它们,并在事务完成后创建它们,它返回到另一批接收数据的队列(队列在前一个事务正在进行时收集数据)。将多个INSERT事务并行发送到单个数据库表只会在特殊情况下产生更高的吞吐量,这就是为什么单个编写器线程通常是一个不错的选择。将多个INSERT捆绑到一个事务中可以更好地利用HDD的有限I / O功能。