【主备倒换】进程间的数据同步

来源:互联网 发布:红帽子linux 编辑:程序博客网 时间:2024/06/07 07:17

接着上一篇文章讨论,如何进行进程间的数据同步。之前我们提到,有两种方式进行进程间的数据同步,一种是将需要同步的数据临时保存在第三方介质中,其中第三方介质可以是文件系统,数据库或者进程地址空间。另外一种方式是同步的数据直接在两个应用程序进程之间传递。我们首先来比较一下这两中解决方案各自的特点,然后,再给出我们的实现方案。第一种方案:需要同步的数据是通过暂存与第三方介质中来实现的。这种方式首先是向和从介质进行I/O会不会成为整个系统的性能瓶颈,这点需要仔细评估。比如如果你采用数据库,在高并发系统中,数据库I/O毫无疑问会成为系统的性能瓶颈,往往在这点采用内存数据库来优化或者自行根据应用特性设计缓存。假如你将数据保存在内存中,那更不合适,你要向应用程序提供高可靠的保证,内存本来就是不保险的。同样存在磁盘也会成为I/O性能问题,也许有些设备根本不会提供磁盘这种存储介质。有些应用程序对实时性要求比较高,需要在最短的时间内将数据同步到standby的进程中去,这时,这种模型肯定是不适合的,因为数据同步需要通过第三方进行中转。有这样一种场景,假如应用程序由于某种原因crash了,这时,应用程序被重启后,可以从第三方介质中获取之前的数据拷贝,这样就可以恢复到crash之前的状态,能保证数据不会丢失。但是这种高可靠是有代价的,是通过牺牲内存来满足这种高可靠的需求。在一些内存受限的系统中,这种模型也是不适合的。第二种方案:需要同步的数据直接在两个进程之间进行传递。这种情况,又可以分为两种方案:A方案:当active进程在处理用户会话的时候,同时,将会话数据同步到standby进程,一旦active进程死掉后,standby进程可以立即接过active进程的活,同时不会影响到用户的体验,也就是说,这种切换对于用户来讲是感知不到的。我们可以类比为软切换。链路先建立,再断开原来的链路。方案B:虽然也可以达到这种效果,不过对于整个系统代价较高,要求两个进程都处于活跃状态。当网关收到接入网的请求后,同时将请求转发给两个进程,让两个进程同时处理业务逻辑,这样,就保证了,一旦一个进程死掉,另一个进程也拥有用户会话数据,可以接着处理业务逻辑。当然,我们更倾向于方案A。方案A对于备板的进程只需要接受主板同步过来的数据,而对于方案B,则需要处理整个会话逻辑,从整个系统来讲,workload较方案A大。 接下来说说方案二的具体实现。所有应用程序运行于cluster环境下,数据同步可以由一个active的进程或者多个active的进程同步到1个standby进程中,首先,active进程需要同standby进程进行配对。Active如何找到对应的standby呢?我们分成几个层次,应用、service group,service unit和component。一个应用可以包含多个service group,一个service group可以包含多个service unit,一个service unit可以包含多个component。如果一个应用进行配对,那么application id必须相等,如果service group进行配对,那么application id和service group id必须相等,以此类推。一般情况下,我们的配对一半在component级别,也就是对应一个进程。进程启动时,通过向cluster中所有component组播,来告知cluster中所有component自己已经加入到cluster环境中。如果正好是配对的component收到组播消息,那么他就会和该component建立数据通路,用于数据同步。应用程序可以自定义多个check point,数据同步就会发生在这些check point上,当程序执行到这些check point,就会立即调用用户自定义的回调函数,用户可以在回调函数中,对自己的数据进行处理,比如加密等等。之后框架会将这些经过用户处理过的数据传送到对端,同样,在对端框架也会调用用户自定义的回调函数,将收到的数据交由应用程序处理,比如解密等等。这样数据会实时的在应用程序之间传递,到达数据快速备份的作用。对于多个active向一个standby进行数据同步的情况,在standby端,需要维护一个表,用来映射active和standby。底层的IPC采用了开源实现TIPC。这个数据同步框架是以库的形式提供给应用程序调用的,他是运行在应用程序的地址空间中的。因此应用程序需要合理的安排调度。在应用程序刚启动的时候,active会向standby批量地同步数据,之后,在运行过程中,应用程序可以通过调用框架提供的API增量地向standby同步数据。