实时大数据设计策略



1、流水模式
       所谓的流水模式就是,当一个线程搞不定一个业务的时候,就将这个业务分为几个过程,前一个过程处理到某种程度,就交给后一个处理过程,形成并行处理机制,我将这样的机制称之为流水模式,其实这就是多线程多核并行处理。


       这里我有两点体会与大家分享:
       1) 线程颗粒度
           决定线程颗粒度的一般有以下几个因素:
           1、线程粒度与任务粒度;
                当一个线程足以把这个业务搞定,而不形成性能瓶颈的时候,使用一个线程就够了;但如果搞不过来,则需要将这个业务分成多个线程,每个线程只承担自己能够承担的起的任务过程。就好比有10个人,100斤的东西,需要搬运100里地,那么最好是每10公里安排一个站点一个人值守,这个人每次挑10斤,到下一站他就放下来,由下一站的人继续搬运至下下一站,这样做的好处就是这个人只要不疲劳(软件我可以认为它是无损耗的),就可以一直这么干下去,而不会出现抱怨。但如果你让一个人每次都挑100斤的东西,走10里地,这可能远远超出他的负荷能力,可能走2里地就趴下了(我们的数据就会overflow)。

            2、线程间的耦合度与任务的耦合度;
                线程颗粒度不但光取决于任务粒度的大小,还取决于任务的耦合度。在《敏捷设计模式》一书中提到的各种设计原则,我对单一原则感触颇深。在设计的过程中,划分线程时,也许某一个线程的任务很简单,只是一些逻辑运算,它不会消耗很多资源,也不会对性能造成瓶颈,有很多闲暇时间,那么这样的任务单独作为一个线程是否合适呢?我的经验是,如果后续任务是IO,如果后续任务和当前任务有很大的耦合度,那么请将这个任务作为一个独立的线程。这样做的好处就是不会产生性能瓶颈,预留了资源空间和时间,增强系统的可维护性性和扩展性。
   
          2) 线程间的解耦与数据的颗粒度
              为了避免线程间的资源竞争,我往往将系统设计成一个生产者和一个消费者模式,使用FIFO来作为线程间的数据耦合。
              为了减少数据拷贝,线程间只产生唯一的一次拷贝。线程1处理完的数据Data_1直接push进FIFO_A,线程2从FIFO_B中pop出Data_1,直接加工处理成Data_2,此过程只产生一次拷贝,即线程1处理完成后push进FIFO时产生一次拷贝。需要注意的是,Data_1必须是能满足线程2直接处理的数据粒度,不然线程2又必须对这个数据进行加工,而产生再次拷贝。   


2、分治模式与数据分解模式
             我这里所说的分治,和网络上其他人所说的分治算法还是有本质区别的。人家所说的分治算法“就是把一个复杂的问题分成两个或更多的相同或相似的子问题,再把子问题分成更小的子问题……直到最后子问题可以简单的直接求解,原问题的解即子问题的解的合并”。而我所说的分治,是为了充分利用目前计算机的多核多线程的方式,充分发挥其资源使用效率,以求达到并行工作的目的。比如前端有100MB的流量过来,如果后续处理流程跟不过来的话,则需要分流,即多个后续处理过程并行工作。至于分多少个,则需要根据后端处理能力来决定,我一般采用预先配置的方式。
              曾在一家公司工作,由于后端处理过程效率低下,造成前端只好为了适应后端,降低入口流量,我认为这样的思路不好,应该是后端满足前端。后来问其原因,才知道他们是因为数据耦合度太大,无法进行分流造成的。所谓的分流,实质是数据分解。 至于如何分流,这个有很多策略。在Gof的设计模式中,有一个策略模式,它为我们提供了一个很好的思维方式。数据肯定是根据不同路径、不同方式汇聚过来的,那么我们就一定能找到其切分点,根据其特性进行分流,以达到分治的目的。这里顺便说个小故事,在开始提出分流这个想法后,对于电信的GN口可以按照BSCIP进行分流,GB口可以按照UserIP进行分流,可WLAN他们似乎就找不到这些特性了,因为GB/GN都是数据源不同,而WLan就找不到这样的特性,于是乎他们就对我的分流产生质疑。由于我对电信业务也不了解,当时也是急了,就仔细体会策略模式的作用背景,小心翼翼地提出,是否可以按照协议类型进行分流,如是乎这个问题就顺利得到解决。后来我的体会是,会不会写设计模式的代码并不重要,而是是否真正体会其思想更重要。
               这里似乎写的比较乱,再稍微总结下:
               1、分治:在架构设计时,就需要考虑并行处理过程,以满足前后处理过程的协调统一;
               2、分流:将数据按照一定的策略进行解耦,以满足分治的数据要求;
               3、数据分解:数据分解实质是分流的一个表现,即降低数据耦合度,将数据保护在一个流程中,外界不能访问。在这里顺便提下我的观点,尽量使用C++的方式,面向对象的编程模式,这样数据比较容易受保护,不要使用C那种方式,因为我看很多以前的代码申请数据空间时,都使用的是g_Data[N],我对这样的数据总感觉不太好!当然啦,C是经典的编程方式,至今很多牛人程序都是用C写的,高效稳定。我怀疑他们是不是用C更习惯,呵呵!不过我习惯C++,感觉干净利落。


4、任务并行模式
             我这里说的并行,是指强并行,即任务间没有数据交互与通信,一条道走到黑。
             关于任务的定义(独门偏方啊),即使用几个线程组成的一个进程,这个进程为完成某一个较大流程业务而存在。
             关于线程和进程,我想说的是,线程间可以共享整个进程的数据空间,而进程间则需要数据通讯,除非你使用进程间数据共享技术。但是线程会存在一个巨大隐患,那就是如果某一个线程出现crush,整个进程全完蛋,数据就会出现大面积的损失。
              所以我的选择一般是这样的,数据经过一级分流后,后续就会由多个进程形成强并行作业,进程里有多个线程,流水式完成各个核心处理任务。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值