.Net中的并行编程-5.流水线模型实战
自己在Excel整理了很多想写的话题,但苦于最近比较忙(其实这是借口)。。。。
上篇文章《.Net中的并行编程-4.实现高性能异步队列》介绍了异步队列的实现,本篇文章介绍我实际工作者遇到了处理多线程问题及基于异步队列底层数据结构的解决方案。
需求如下:1.提供数据服写入服务供上层应用调用,数据写入服务处理的吞吐量要达到60w/s每秒,也就是用户每秒发送60w的数据然后通过数据写入服务写到数据库中(数据库为公司自主研发的实时数据库)。
2.尽量简化上层应用调用服务的复杂度。
一、分析性能瓶颈
1.实时数据库要求传入的数据需要带有ID(类似于关系库中的自增主键),但用户只传Name,需要根据Name去实时数据找到对应的数据ID,所以该地方频繁的与数据库交互是最大的瓶颈。
2.由于数据库原始的.Net API是基于底层C++ API 进行的二次开发,需要.Net和C++编程模型之间的转换(比如.Ne中存数数据用的是List,C++是数组,所以要把.Net中的List对象 转换为c++中的数组对象),而这个转换耗时相当大,所以数据转换操作也是性能瓶颈之一。
二 、解决方案
1.对于性能瓶颈1可以使用本地缓存,本地缓存维护了name和数据库ID直接的映射关系,所以查找id时,只要去本地缓存查找即可。由于该缓存读远远大于写,所以缓存部分使用了普通的Dictionary加上读写锁,读取数据时只要获取读锁,跟新数据时加上写锁,所以设计出以下流程。

2.对于性能瓶颈2可以采用并行的方式解决,我们并行模型主要分为三种:数据并行,任务并行,和流水线并行,关于这三种模型的基本介绍可以参照《Intel Threading Building Blocks 编程指南》第二章 并行思维。有的以上基础理论的支持,所以设计出以下模型。

上图中,每个操作都是在单独的线程中进行的,操作与操作之间采用队列进行解耦。由于流水线模型是典型的空间换时间,每个操作之间累积了大量数据,所以一旦程序出现崩溃,那么导致队列内的数据全部丢失,所以还要保证系统的高容错,由于采用了上篇文章中的队列而且在开始编码的时候已经考虑到了系统异常处理的细节,所以异常处理和多线程编程的复杂度也大大降低,并且每个操作处理的线程数也可动态适配(其实最理想的情况是根据每个操作的处理能力以及CPU利用率等进行动态负载均衡,由于配置的线程数已尽满足了需求所以动态负载均衡没有进行开发)。
三、关于扩展性
如果未来数据量要增加,那么相应的处理能力也要增加。那么最简单的方案就是动态增加每个处理操作的线程数,由于操作之间采用队列进行通信,那必然会设计到锁的问题,而且同时的进行多线程入队和多线程出队会造成频繁的上下文切换并造成性能下降,所以为了避免这种多线程竞争了情况,可采用多流水线,每个流水线的流程都跟上图一样,对于流水线直之间的负载均衡可以采用加权平均轮训,哈希求余等算法。
补充:
流水线模型的总体时间取决于最耗时的操作环节,所以再采用流水线模型时要尽量减少最耗时操作环节的时间,如在本案例中最耗时的环节是写入数据库部分,所以在进行编码和设计时对该部分进行了重点优化。
.Net中的并行编程-5.流水线模型实战的更多相关文章
- .Net中的并行编程-1.路线图(转)
大神,大神,膜拜膜拜,原文地址:http://www.cnblogs.com/zw369/p/3834559.html 目录 .Net中的并行编程-1.路线图 分析.Net里线程同步机制 .Net中的 ...
- .Net中的并行编程-6.常用优化策略
本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略. 一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁 ...
- .Net中的并行编程-4.实现高性能异步队列
上文<.Net中的并行编程-3.ConcurrentQueue实现与分析>分析了ConcurrentQueue的实现,本章就基于ConcurrentQueue实现一个高性能的异步队列,该队 ...
- .Net中的并行编程-2.ConcurrentStack的实现与分析
在上篇文章<.net中的并行编程-1.基础知识>中列出了在.net进行多核或并行编程中需要的基础知识,今天就来分析在基础知识树中一个比较简单常用的并发数据结构--.net类库中无锁栈的实现 ...
- .Net中的并行编程-3.ConcurrentQueue实现与分析
在上文<.Net中的并行编程-2.ConcurrentQueue的实现与分析> 中解释了无锁的相关概念,无独有偶BCL提供的ConcurrentQueue也是基于原子操作实现, 由于Con ...
- Python中的并行编程速度
这里主要想记录下今天碰到的一个小知识点:Python中的并行编程速率如何? 我想把AutoTool做一个并行化改造,主要目的当然是想提高多任务的执行速度.第一反应就是想到用多线程执行不同模块任务,但是 ...
- .Net中的并行编程-1.路线图
最近半年一直研究用.net进行并行程序的开发与设计,再研究的过程中颇有收获,所以画了一个图总结了一下并行编程的基础知识点,这些知识点是并行编程的基础,有助于我们编程高性能的程序,里面的某些结构实现机制 ...
- .NET Framework 4 中的并行编程9---线程安全集合类
原文转载自:http://www.cnblogs.com/xray2005/archive/2011/10/11/2206745.html 在.Net 4中,新增System.Collections. ...
- .Net中的并行编程-7.基于BlockingCollection实现高性能异步队列
三年前写过基于ConcurrentQueue的异步队列,今天在整理代码的时候发现当时另外一种实现方式-使用BlockingCollection实现,这种方式目前依然在实际项目中使用.关于Blockin ...
随机推荐
- Vector和Stack源码分析/List集合的总结
序言 这篇文章算是在这list接口下的集合的最后一篇了,前面ArrayList.LinkedList都已经讲解完了,剩下就Vector和Vector的子类Stack啦.继续努力.一步一个脚印, --W ...
- 引入CSS文件的@import与link的权重分析
我很少在CSS用到@import这个标签,最近看到一句话“link方式的样式的权重 高于@import的权重”,感觉不太对,@import只是一个引入外部文件而已,怎么会有高于link的权重呢?于是我 ...
- 仿SGI STL的traits技法
首先是iterator traits,这个是用来萃取迭代器的特性的 #ifndef _STL_ITERATOR_H_ #define _STL_ITERATOR_H_ #include <cst ...
- javascript运算符——位运算符
× 目录 [1]二进制 [2]非 [3]与[4]或[5]异或[6]左移[7]右移[8]>>>[9]应用 前面的话 位运算符是非常底层的运算,由于其很不直观,所以并不常用.但是,其速度 ...
- BOM之navigator、history、screen对象
navigator对象 [定义] navigator已经成为识别客户端浏览器的事实标准.下表中列出存在于所有浏览器的属性和方法 [检测插件] 检测浏览器插件是一种最常见的检测例程. [1]对于非IE浏 ...
- CSS3入门之边框与背景
CSS3入门之边框与背景 *:first-child { margin-top: 0 !important; } body>*:last-child { margin-bottom: 0 !im ...
- Floyd算法(一)之 C语言详解
本章介绍弗洛伊德算法.和以往一样,本文会先对弗洛伊德算法的理论论知识进行介绍,然后给出C语言的实现.后续再分别给出C++和Java版本的实现. 目录 1. 弗洛伊德算法介绍 2. 弗洛伊德算法图解 3 ...
- 【Android】Android Camera原始帧格式转换 —— 获取Camera图像(一)
概述: 做过Android Camera图像采集和处理的朋友们应该都知道,Android手机相机采集的原始帧(RawFrame)默认是横屏格式的,而官方API有没有提供一个设置Camera采集图像的 ...
- 在Android中实现service动态更新UI界面
之前曾介绍过Android的UI设计与后台线程交互,据Android API的介绍,service一般是在后台运行的,没有界面的.那么如何实现service动态更新UI界面呢?案例:通过service ...
- linux下core dump【总结】
1.前言 一直在从事linux下后台开发,经常与core文件打交道.还记得刚开始从事linux下开发时,程序突然崩溃了,也没有任何日志.我不知所措,同事叫我看看core,我却问什么是core,怎么看. ...