自己在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.流水线模型实战的更多相关文章

  1. .Net中的并行编程-1.路线图(转)

    大神,大神,膜拜膜拜,原文地址:http://www.cnblogs.com/zw369/p/3834559.html 目录 .Net中的并行编程-1.路线图 分析.Net里线程同步机制 .Net中的 ...

  2. .Net中的并行编程-6.常用优化策略

                本文是.Net中的并行编程第六篇,今天就介绍一些我在实际项目中的一些常用优化策略.      一.避免线程之间共享数据 避免线程之间共享数据主要是因为锁的问题,无论什么粒度的锁 ...

  3. .Net中的并行编程-4.实现高性能异步队列

    上文<.Net中的并行编程-3.ConcurrentQueue实现与分析>分析了ConcurrentQueue的实现,本章就基于ConcurrentQueue实现一个高性能的异步队列,该队 ...

  4. .Net中的并行编程-2.ConcurrentStack的实现与分析

    在上篇文章<.net中的并行编程-1.基础知识>中列出了在.net进行多核或并行编程中需要的基础知识,今天就来分析在基础知识树中一个比较简单常用的并发数据结构--.net类库中无锁栈的实现 ...

  5. .Net中的并行编程-3.ConcurrentQueue实现与分析

    在上文<.Net中的并行编程-2.ConcurrentQueue的实现与分析> 中解释了无锁的相关概念,无独有偶BCL提供的ConcurrentQueue也是基于原子操作实现, 由于Con ...

  6. Python中的并行编程速度

    这里主要想记录下今天碰到的一个小知识点:Python中的并行编程速率如何? 我想把AutoTool做一个并行化改造,主要目的当然是想提高多任务的执行速度.第一反应就是想到用多线程执行不同模块任务,但是 ...

  7. .Net中的并行编程-1.路线图

    最近半年一直研究用.net进行并行程序的开发与设计,再研究的过程中颇有收获,所以画了一个图总结了一下并行编程的基础知识点,这些知识点是并行编程的基础,有助于我们编程高性能的程序,里面的某些结构实现机制 ...

  8. .NET Framework 4 中的并行编程9---线程安全集合类

    原文转载自:http://www.cnblogs.com/xray2005/archive/2011/10/11/2206745.html 在.Net 4中,新增System.Collections. ...

  9. .Net中的并行编程-7.基于BlockingCollection实现高性能异步队列

    三年前写过基于ConcurrentQueue的异步队列,今天在整理代码的时候发现当时另外一种实现方式-使用BlockingCollection实现,这种方式目前依然在实际项目中使用.关于Blockin ...

随机推荐

  1. JSP网站开发基础总结《十三》

    继上一篇为大家补充过滤器类后,本篇为大家简单介绍一下如何实现验证码效果.验证码的作用是什么呢?1.防止恶意注册2.防止恶意提交3.防止盗取账户等等,总的来说验证码的存在就是为了,防止非人为的操作,不过 ...

  2. hdu4750Count The Pairs(最小生成树找瓶颈边)

    /* 题意:就是给你一个图,图的每两个点都有多条路径,每一条路径中都有一条最大边, 所有最大边的最小边(也就是瓶颈边)就是这两点之间的val值!然后给你一个值f, 问有多少个顶点对的val>=f ...

  3. Huge Page 是否是拯救性能的万能良药?

    本文将分析是否Huge Page在任何条件下(特别是NUMA架构下)都能带来性能提升. 本博客已经迁移至: http://cenalulu.github.io/ 为了更好的体验,请通过此链接阅读: h ...

  4. PHP的学习--解析URL

    PHP中有两个方法可以用来解析URL,分别是parse_url和parse_str. parse_url 解析 URL,返回其组成部分 mixed parse_url ( string $url [, ...

  5. AngularJS入门心得2——何为双向数据绑定

    前言:谁说Test工作比较轻松,最近在熟悉几个case,差点没疯.最近又是断断续续的看我的AngularJS,总觉得自己还是没有入门,可能是自己欠前端的东西太多了,看不了几行代码就有几个常用函数不熟悉 ...

  6. 别用symbolicatecrash来解析crash Log了

    今天突然发现了一个解析iOS crash log的好方法,忍不住来分享一下. 相信每个做iOS开发的TX都应该不会对symbolicatecrash陌生,我们第一次遇到真机上产生的崩溃日志时,在网上搜 ...

  7. [New Portal]Windows Azure Virtual Machine (14) 在本地制作数据文件VHD并上传至Azure(1)

    <Windows Azure Platform 系列文章目录> 之前的内容里,我介绍了如何将本地的Server 2012中文版 VHD上传至Windows Azure,并创建基于该Serv ...

  8. Elasticsearch聚合 之 Range区间聚合

    Elasticsearch提供了多种聚合方式,能帮助用户快速的进行信息统计与分类,本篇主要讲解下如何使用Range区间聚合. 最简单的例子,想要统计一个班级考试60分以下.60到80分.80到100分 ...

  9. Git学习笔记(二)

    一.创建远程仓库(GitHub) 1.GitHub网站地址:https://github.com/,这个网站就是提供Git仓库托管服务的,所以,只要注册一个GitHub账号,就可以免费获得Git远程仓 ...

  10. 意译:《JVM Internals》

    译者语 为加深对JVM的了解和日后查阅时更方便,于是对原文进行翻译.内容是建立在我对JVM的认识的基础上翻译的,加上本人的英语水平有限,若有纰漏请大家指正,谢谢. 原文地址:http://blog.j ...