概述
最近在做一个web项目,要求做成群集形式。方案是nginx+tomcat+memcached_session_manager,部署环境是Ubuntu 10.04 Server LTS。项目快完成时发现自己忽略了文件同步问题,于是立即开动google,满世界寻找解决方案。
这个项目有很多需要用户上传的文件,比如用户的形象照片,视频文件等。在群集中,用户上传的文件往往被某个节点的服务器保存在该物理服务器的某个目录下。那么其它节点的服务器如何访问这些文件呢?一般来说,有两种解决方案,一是NFS,即设立专门的网络文件服务器;二是同步远程服务器的文件目录,使其保持一致。
NFS方案比较简单,但访问速度会相对比较慢,而且所有的文件通过网络来存取,个人感觉效率太低下。另外,为了保证单台NFS失效时网站的正常运行,我们还需要将NFS配置成多台群集的模式,增加了成本和复杂性。
第二种方案可以很好地兼顾成本和效率,是可以接受的方式。但笔者以前没有在Ubuntu上实现过远程文件同步的经验,因此查找资料和摸索配置,寻找最优方案的工作整整进行了两天。郁闷啊!
最后选定的方案如下:
Unison: 实现双向同步
Inotify tools: 监控文件系统
OpenSSH: 远程主机间的文件传输
软件介绍
OpenSSH
OpenSSH 是 SSH (Secure SHell) 协议的免费开源实现。
它用安全、加密的网络连接工具代替了 telnet、ftp、 rlogin、rsh 和 rcp 工具。OpenSSH 支持 SSH 协议的版本 1.3、1.5、和 2。自从 OpenSSH 的版本2.9以来,默认的协议是版本2,该协议默认使用 RSA 钥匙。
OpenSSH的项目地址如下:http://www.openssh.com/
Unison
Unison是一款跨平台的文件同步工具,不仅支持本地对本地同步,也支持通过SSH、RSH和Socket等网络协议进行同步。更棒的是,Unison支持双向同步操作,你既可以从A同步到B,也可以从B同步到A,这些都不需要额外的设定。
Unison的项目地址:http://www.cis.upenn.edu/~bcpierce/unison/
Inotify tools
Inotify是一种文件变化通知机制,Linux内核从2.6.13开始引入。在BSD和Mac OS系统中比较有名的是kqueue,它可以高效地实时跟踪Linux文件系统的变化。近些年来,以fsnotify作为后端,几乎所有的主流Linux发行版都支持Inotify机制。
inotify-tools 是为linux下inotify文件监控工具提供的一套c的开发接口库函数,同时还提供了一系列的命令行工具,这些工具可以用来监控文件系统的事件。 inotify-tools是用c编写的,除了要求内核支持inotify外,不依赖于其他。
Inotify-tools的项目地址:http://sourceforge.net/projects/inotify-tools/
软件安装
准备工作
安装操作系统Ubuntu 10.04 Server LTS,32位或者64位。假设我们有3台安装了Ubuntu 10.04 Server LTS的Web服务器,分别为:
server1 192.168.0.101
server2 192.168.0.102
server3 192.168.0.103
server4 192.168.0.104
其默认用户名分别为user1、user2、user3、user4。
需要同步的目录均为:/var/www/html
安装OpenSSH
在各台服务器上安装OpenSSH,使用如下命令:
sudo apt-get install openssh
该命令在你的机器上同时安装了SSH Server和SSH Client。
安装Unison
在各个需要同步的服务器上执行以下命令安装unison:
sudo apt-get install unison
安装Inotify tools
在各个需要同步的服务器上执行以下命令安装inotify-tools:
apt-get install inotify-tools
配置
多机同步的拓扑结构
在web群集中,同步在多机之间进行,而unison的同步功能仅支持双机。因此我们设计了一个星型的拓扑结构,来实现多机的同步。其设计思想就是利用unison的双向同步功能,指定一台服务器为星型结构的主服务器(server1),剩余服务器与其进行双向同步。这样,任何一台服务器上的文件变化都可以通过这个结构扩散,从而达到多机同步的目的。
这一结构的缺点是一旦server1当机失效,同步就会失败。因此,有必要的话,可以组成双主服务器的星型结构来弥补。
配置双机信任(ssh key)
Unison通过SSH来进行文件同步时,需要用户手工输入远程主机的登录密码。而我们试图通过开机自启动的脚本来实现自动的同步功能。因此,我们需要为SSH配置双机信任,使双方在使用ssh时不需要再输入密码。
使用 ssh-keygen和ssh-copy-id配置一下就可以无需输入密码直接登录服务器了。
ssh-keygen 创建公钥和密钥。ssh-copy-id 把本地主机的公钥复制到远程主机的authorized_keys文件上。
ssh-copy-id 也会给远程主机的用户主目录(home)和~/.ssh, 和~/.ssh/authorized_keys设置合适的权限