最近,我的工作重心是搜索项目。我们选用的搜索框架是Elasticsearch,ES从诞生第一天起就是面向分布式而构造的,因此跨服务器的文件同步问题随之而来。 此外,我使用R语言作为主要的脚本语言来配合ES使用(测试搜索效果、生成同义词文件等等),习惯上我会把R项目生成的文件放在R相关的目录下,因此还需要将文件同步到ES相关的目录下,这就产生了本地文件同步的需求。
本地文件同步
通过链接文件可以实现文件同步,链接文件又分为硬链接与软链接,硬链接相当于备份,删除源文件后硬链接文件仍然存在且保留了原有的内容,而软链接相当于快捷方式,源文件删除后软链接文件将链接到一个不存在的文件,这被称为断链。 虽然硬链接只能在同一个分区中做链接,但我希望ES项目中的文件是相对稳定的(不能因为R脚本误操作删除了源文件使得ES中的文件也不存在了),并且我可以把R的目录和ES相关配置文件的目录放在同一个分区,所以我选择了硬链接的方式进行文件同步:
[bash gutter="0"] ln ~/R/csv/bbs_pinyin.txt /etc/elasticsearch/analysis/bbs_pinyin.txt [/bash] 这样就实现了用R脚本写文件到R项目的目录下,并且同步到ES的相关配置目录中。
跨服务器文件同步
跨服务器文件同步可以通过rsync来实现。当然,要使得两台服务器可以同步文件必须保证源文件所在的服务器A可以访问到目标同步服务器B。为了使得命令更简单,我们希望从机器A通过ssh登录到机器B时可以不用输入密码(都是同一个ES集群中的机器),这就需要用到ssh-keygen: [bash gutter="0"] cd ~/.ssh ssh-keygen [/bash] 首先在服务器A上进入用户主目录下的.ssh目录中(如果不存在就新建一下);运行ssh-keygen,根据提示输入文件名(按回车会使用默认文件名id_rsa),然后输入密码(按回车代表不需要密码);这样在~/.ssh目录下会生成两个文件id_rsa(私钥)与id_rsa.pub(公钥)。 然后登录服务器B依然是进入用户主目录下的.ssh目录中,并把刚才在服务器A中生成的id_rsa.pub传到服务器B上,并运行: [bash gutter="0"] cat id_rsa.pub >> ~/.ssh/authorized_keys [/bash] 如果authorized_keys不存在则创建一个空文件再执行上面的命令。最后修改.ssh目录的权限(这与登录服务器息息相关,因此权限自然比较严格:保证 ~/.ssh 以及所有父目录的权限不能大于 711): [bash gutter="0"] chmod 700 -R ~/.ssh [/bash] 现在你应该可以在服务器A上不输入密码就直接ssh登录到B机器上了(假设刚才B机器上的用户名是logos,ssh端口不是标准的22而被修改成了5333,ip是1.1.1.1): [bash gutter="0"] ssh -p 5333 logos@1.1.1.1 # 可以从ssh的配置文件中得到被修改后的端口 vim /etc/ssh/sshd_config [/bash] 终于,我们可以用rsync来跨服务器同步文件了: [bash gutter="0"] rsync -avz -e "ssh -p 5333" /etc/elasticsearch/analysis/bbs_pinyin.txt logos@1.1.1.1:/etc/elasticsearch/analysis/ [/bash] 选项a允许递归地复制文件,且保留软链接、文件权限与用户和用户组以及时间戳,参数v是verbose的缩写,z代表会压缩文件,当想通过ssh来同步且端口不是默认的22时需要用到-e "ssh -p 5333"这样的格式,最后两个参数分别代表本机上要同步的文件,与目标机器上要文件要放的目录。 ssh-keygen部分参考了这篇文章,rsync的语法参考了这里,希望对大家有帮助。