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