Total Pageviews

Sunday, 16 March 2014

使用incrond和csync2实现集群文件同步

在翻看CPAN搭建镜像站点 介绍中,CPAN镜像同步程序 的作者在介绍其算法的时候,举例到竞争者csync2, rsync3 (batchmode)。
对这个技术比较感兴趣, 于是google了rsync3的batchmode,发现其实非常不友好,也没有比rsync高级出多少。
再gogole了csync2,发现不少文章,都是介绍使用csync2进行集群文件同步,其中不少是将lscynd和csync2结合起来使用。
于是这几天小小调研了下这几款程序,仔细了解了一下。
通过了解发现lsyncd视乎比较令人满意,可惜我的机器上编译lua后怎么也不被lsyncd的configure程序识别为满意, 故而提了一个issue给作者后,转向使用csync2+incrond来完成任务,于是有了本文。

csync2 介绍

Csync2 类似于unison 是一个学院派的程序,主要解决的目的是进行集群间的文件/目录同步,可以发现/解决冲突,友好的处理删除情况,纤细介绍可以在其官网上了解。
csync2 中的 C 应该是代表cluster,集群的意思,即;它支持的是集群内服务器的文件/目录同步,并不仅仅局限于2台。

csync2特点

  • 使用sqlite(可以编译支持pgsql、mysql等)数据库记录跟踪文件变化,可以查看和diff远端和自己的差别,可以查看哪些文件发生了变化
  • 使用rsync算法进行数据同步,rsync算法是高效的
  • 支持TLS传输数据,提供安全保证(此功能可以关闭,以提高效率)
  • 节点间进行对称加密的认证,同样提供了安全性
  • 支持同步的时候进行备份,防止同步异常造成数据丢失
  • 支持冲突发现,并可以通过配置冲突解决策略来自动解决冲突
  • 支持一台服务器上配置多个组,同步只发生在组内
  • 丰富的客户端命令选项,便于查看同步和手动执行同步

安装

配置

  • csync2 的配置文件在 /etc/csync2.cfg,编辑,修改为自己想要的。配置方法可以查看其文档
  • 生成的使用 对称密钥
    sudo csync2 -k /etc/csync2.key_mygroup
    
  • csync2 的数据库存放于/var/lib/csync2/

启动

csync2的启动方式有3种
  1. inetd/xinetd
    csync2 -i
     通过配置xinetd服务,当连接到来时由xinetd启动csync2,处理完请求,csync2会马上退出。
  2. daemon
    csync2 -ii
    csync2 以daemon方式运行,不停的处理到来的请求。不自动退出,可以通过执行 csync2 -k 让其退出。
  3. 执行一次即退出
    csync2 -iii
    这种模式下,csync2 启动后,处理完一个请求后便退出。

用csync2进行同步

  1. csync2 -x 执行同步,连接group内机器,进行同步,group内机器需要启动或配置好csync2的server模式,以便连接。
  2. csync2 -M 查看dirty的文件,dirty的文件为发生变动的文件,需要被push到远端。
  3. 其它,通过man csync2 可以查到。

incrond 介绍

incrond 是以crontab类似的方式提供的一个工具, 实际上是对Linux内核api的inotify功能的封装。
注意:inotify无法递归监控子目录。
incrond 模仿了crontab,使用习惯与crontab一样:
incrond = crond, incrontab = crontab
incrontab 的格式如下:
# path          mask               action
/path/to/dir EVENTS,EVENTS,EVENTS  /home/admin/tt.sh $%/$#
action 是EVENT发生后执行的程序,可以将一些事件关联的属性传给程序,如上例中的$%/$#
mask中可添加的一个选项 IN_NO_LOOP 用来指定执行程序的过程中不进行事件的触发,即暂时屏蔽了事件,这个特性可以防止多个action实例同时运行。
如果是监控整个目录树的事件,那么需要将 mask 设置为包含 IN_ALL_EVENTS ,以便捕获所有的事件,这是因为intofiy工具是无法递归地对子目录进行监控的,我们只能通过顶层目录的 OPENCLOSE 事件来间接的监控子目录树的事件。

安装

incrond 要求内核支持inotify(内核版本要在2.6.13之上)。因为它实质是对inotify的api的包装。

配置

安装完成后incrond与incrontab两个程序可用,incrond的配置文件位于/etc/incron.conf, 此外/etc/incrond.d/目录下可以存放incrontab配置,类似于crontab的布局。
incron.conf 配置比较简单,其中一项是editor配置,我们需要设置为vi、vim或者emacs,之后才能使用incrontab来编辑incrontab。

启动

sudo incrond
incrond 以daemon进程的形式(类似于crond)存在
如果要添加配置,通过 incrontab -e 来添加

incrond+csync2配置集群同步

搭配原因

csync2 解决了集群内机器将同步问题,但是csync2需要通过手动来触发,它本身是不会自动监控变化的。
 所以我们结合使用incrond来监控文件/目录的变化,然后触发csync2来进行同步,这就是思路。

搭配方法

  • 首先配置好csync2,以xinetd或者daemon方式运行起来。
  • 配置好incrond,运行起来
  • 添加incrontab项,使incrond事件监控和csync2文件同步关联起来
    如:
    /home/admin/resource IN_ALL_EVENTS,IN_NO_LOOP /home/admin/tt.sh $%/$#
    

存在的问题

通过incrond进行触发csync2同步的时候,存在一个问题,那就是csync2进行同步的时候,又会触发incrond的执行(因为incrond监控了 IN_ALL_EVENTS ),所以就会造成无休止的循环和csync2进程被频繁的创建出来,进而导致系统load上升。
解决方法是对incrond触发的脚本,在脚本内通过锁机制保证同一时刻只有一份同步进行在运行,同时在执行同步前后增加一定的暂停时间:
(
  flock -n 100 || exit 
  sleep 1 
  echo [$(date +'%y-%m-%d %h:%M:%S')] "${1:-crontab}" >>/home/admin/logs/resource_sync.log
  /usr/local/sbin/csync2 -vx 2>>/home/admin/logs/csync2.log
  sleep 1
) 100>/tmp/csync.lock
这样一来,可能有的事件因为互斥锁的原因二没有进行同步,所以需要增加一份额外的定时同步(添加于crontab):
#Run script every 15 seconds : 
* * * * * /foo/bar/your_script
* * * * * sleep 15; /foo/bar/your_script
* * * * * sleep 30; /foo/bar/your_script
* * * * * sleep 45; /foo/bar/your_script

其它

除了csync2还有类似的工具,比如:
  • unison
     可以完成两台服务器间目录的同步
  • lsyncd
    lsyncd 是一个很好的方案,对inotify事件进行了聚合,避免事件的爆发式到来。它使用了intofiy进行监控,并可以配置action(默认的是rsync),一个程序便可以搞定。
  • DRBD
    drbd(Distributed Replicated Block Device) 与上面的工具不同的是,它是基于块设备的,处于文件系统之下的块设备,它通过hack内核的方式,为上层文件系统提供了一个逻辑上的块设备,这个块设备其 实是一组镜像: 包括远端与本机。drdb提供了管理工具来进行主备的切换,并提供了同步的方式(同步、异步、内存同步),注意,它的slave设备是不 可读写的。使用的时候mount这个设备即可.