进程迁移是集群中关键性技术,计算迁移的概念继承自进程迁移,但为单一世界架构量身定制,同样,他也是单一世界架构的核心技术之一。首先,我们先界定下计算迁移的概念:某个计算过程离开原来的计算环境,在另外一个计算环境中继续完成。这里涉及到2个子概念,什么计算,什么迁移。我们来研究下计算的历史,分为几个阶段: 1、函数,这是很核心的基础概念,原来基于汇编指令的计算,没有实际意义,就不再探讨。函数过程,最基本是根据输入参数,按照某个算法,输出结果。参数-->算法-->结果是通用的结果。对于函数的调用,函数地址是最基础的标识,函数名称是助记符号,函数序号也是一种,比如动态库中。 2、报文,报文的应用是在网络中,比函数更进一步。RPC远程过程调用,实际是将函数从单机包装到网络中。在调用方式上也有所进化,首先是地址,不再是一个常数,而是一个网络地址,其实参数不再是特定类型的,而是一个报。报文的方式其实也可以看作输入参数在栈上的整体封装。但和函数参数很不同的是,这里没有指针传递,而只有值传递了。而输出,和输入类型,从原来的指针或者值方式,变成完全的值方式,指针在这里失去了意义。依然保持和指针类似功能是偏移量。 3、协议,HTTP以及其他协议,实际上是在报文的基础上进一步扩展,不同的是,这种协议有更严格的规范,但基本上没有脱离关于报文的计算含义。 4、SOA等,基于协议,又扩展了更多复杂的技术。但依然没有参数-->算法-->结果这个框架。只是算法的定义需要做扩展,以及参数和结果的格式需要做出变更。 我们在上面做计算的历史做了归纳,可以将一个计算过程分解为2个要素,一个是计算过程的构成要素:参数-->算法-->结果;另外一个是算法的地址,不论是内存地址还是网络还是URL。那么迁移,也是基于2个要素进行迁移。但很多情况下,算法是被完成分布于所有的计算环境,这种情况很多,比如FTP镜像,或者HTTP,任何一个节点都知道相同的算法,某个文件某个偏移是什么内容,完全一样的。那么,这种情况下,计算的迁移只要参数进行迁移就可以了。但另外一种情况就比较特殊,新的计算环境并不知道该计算的算法,于是,算法同样也需要被迁移,一个典型的例子就是java类。java的理想是一次编译任何地方都能运行,于是算法就必须跟随着参数跑了。 但是,关于计算迁移和进程迁移一样,有个很致命的问题,就是计算环境中的上下文。很显然,如果一个函数需要依赖于全局变量,那么迁移将会变得困难,因为全局变量迁移将会导致一致性问题和迁移的数据量问题。于是上下文无关,或者可重入的函数是必须的。任何允许迁移的计算都尽量是上下文无关的,当然,也不是必须,如果环境也能够被迁移,是可以接受的,不过,从理论上来看,这必须被避免的。 计算迁移是核心技术,他比肩于局部性原理,是单一世界的核心基础。由于单一世界架构是我们自己构造的,有一定的专用性,所以我们完全可以做更多的约定,比如算法,必须全部分布于所有计算环境,当然,也可以采用高级点的技术,比如动态更新等。