Linux服务器程序--大数据量高并发系统设计

     在Linux服务器程序中,让系统能够提供以更少的资源提供更多的并发和响应效率决定了程序设计价值!怎样去实现这个目标,它其实是这么多年以来一直追逐的东西。最开始写代码时候,省去一个条件语句、用更好的算法使程序时间\空间复杂度降低;到后来为了让数据结构更简单方便的完成数据操作而无意中使用的数据库3范式。这一系列的小细节都有欣慰,今天我在这里的需求是:如何让一个单进程去并发完成多任务?
     单进程并发完成多任务?不能呀,我们并不能要求单进程同时完成不同的任务,因为单进程只能同时拥有一个core!
     我们把进程的任务分割成出来,让各个任务的子任务片逐个轮流在cpu里面执行,那么当子任务片足够细致的话,CPU每段时间都会处理很多子任务,进程又确实在处理很多个不同的任务。所以在这种情况下,总体感知上就能体会到进程在不停的处理多个任务。
     为何要把任务拆分?搞这么复杂又有什么好处,为何不能一个任务一个任务的接下去处理呢?
     回忆下大学时候的操作系统,CPU时间片、状态机、就绪队列、多任务系统这些名词,就会发现通常情况下程序运行过程中会存在一些开销比较大的片段,在这个时间里面如果CPU还继续出来这个程序,就会很多的浪费资源。所以,这个时候操作系统把那些阻塞的程序切换出内核,再把那些就绪状态的任务换入继续处理。
     实际上在大型的服务器系统中,一个单任务可能会经过接口转换、业务鉴权、数据更新等等多个步骤,也很可能经历读写文件、读写数据库、等待外部输入等多种耗时量非常大的工作。这些单任务的组织可以完全参照Linux系统对进程调度的理论来更好的实现,其关键就在于怎样实现对单任务的切割和任务调度。任务的切割和系统的业务绑定非常之紧密,一般会把设计文件操作、数据库操作、等待消息和外部驱动等操作的程序片切割出来。
     任务管理器则实现对任务调度管理工作,它主要根据任务的状态机来实现对任务的调度,提供虚拟接口来实现统一的调度窗口。
          任务单元:一个内存块class\struct,包含该任务的头部信息,如任务编号、当前状态、指向任务内存块的指针等等一系列公共信息。
          任务池:由任务单元数组,进程每个处理的任务都在任务池里面分配一个节点
          任务管理器:完成任务池的统一管理、实现快速索引,任务管理基于几个HashList实现。包括空闲任务队列、超时控制任务队列数组、已超时任务数组等。
     基于以上分析,那么新设计出来的系统就会变成一个这样的机器模型:一个不停接收外部处理,然后把任务切割成多个小块,分别释放到不同服务进程进行处理,最后把小任务处理结果进行归并的任务管理进程。这个是不是有点那啥的影子,其实现阶段系统最终演化出来都具体他们共同的一组特性,即:把系统拆分成数据接口、任务管理、业务提供这三类子系统。也许是自己所见太少,但是最少我接触到的系统都具有这种共同特性,而且它们所在的关键就在于怎么去更好的组织管理具体的任务,hadoop成功就在于此。
                                   
     上面就是我所涉及的一个数据系统,由于数据资料庞大,每张表的数据量要求达到亿级,查询流程需要非常高的性能保证,而更新需要保证数据准确性和一致性。我们在设计系统基础结构的时候,首先考虑采用的是分库及多点并发,但是这样就必须存在多个备份点而且需要高度的数据一致性,加上主机成本因数。最终采用的是PC机+多点备份的模型,通过增加总线控制模块来实现多点备份的数据一致性和高可用性,总线模块即基于上述任务管理器理念设计,它将一个数据更新拆分成多个小任务,分发到多个子业务节点处理,然后再根据各个节点处理结果进行合并,如果失败则进行数据回滚,如果成功则把其它备份节点一并发到备份的兄弟节点去。它将一个查询拆根据备份节点业务量负载到不同备份节点进行出来,以多节点同步处理的方式进行并发。
posted @ 2013-10-15 15:42  一介莽夫  阅读(786)  评论(0编辑  收藏  举报