`
gaopenghigh
  • 浏览: 246216 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

inotifyrsync -- 用inotify和rsync实现多机文件实时同步

阅读更多
对于热备的机器,需要实时把文件目录的修改从master同步到slave上。用crontab加rsync的方式能够实现几分种延迟内的同步,但用对于文件数目很大的情况,每次rsync都会有很多计算,比较耗费CPU资源。下面的脚本用inotify和rsync实现实时同步。为了保险起见,最好还是设置一个crontab来定时跑整个目录的rsync,不过定时间隔可以稍微长一点,以免占用太多系统资源。

github上的链接:https://github.com/gaopenghigh/inotifyrsync

直接上代码:

README
Use rsync and inotify to sync files and directories from one host to other hosts
  
  Include 2 files:
  sync.sh
  do_sync.py
  
  RUN:
  0. Make sure source host can ssh into destination hosts without password
  1. Do some setting in file do_sync.py
  2. run sync.sh


sync.sh
#!/bin/bash
  
  LOG=`cat $(dirname $0)/do_sync.py | grep "LOG_FILE = " | head -n 1 | awk '{print $3}' | tr -d \'`
  BASE_DIR=`cat $(dirname $0)/do_sync.py | grep "BASE_DIR = " | head -n 1 | awk '{print $3}' | tr -d \'`
  tester=`/bin/ps aux | grep -v grep | grep do_sync.py`
  if [[ ! -z $tester ]];then
      echo "sync.sh already running"
  else
      echo "/usr/bin/inotifywait -mrq --format '%w%f' -e modify,delete,create,move $BASE_DIR | $(dirname $0)/do_sync.py > $LOG &"
      /usr/bin/inotifywait -mrq --format '%w%f' -e modify,delete,create,move $BASE_DIR | $(dirname $0)/do_sync.py > $LOG &
  fi


do_sync.py
  #!/usr/bin/python
  # -*- coding: utf-8 -*-
  # Author: gaopenghigh@gmail.com
  
  import sys
  import os
  import commands
  import threading
  import time
  
  ### CONFIGS, YOU CAN CHANGE SETTINGS HERE ###
  THREAD_NUM = 2                # how many threads do the rsync job
  SLEEP_TIME = 3                # if nothing to sync, just sleep, second
  MERGE_NUM = 25                # try to sync dirs instead of files in the same dir
  BASE_DIR = '/home/admin/run'  # root dir you want to sync, anything out of this dir will not sync
  LOG_FILE = '/home/admin/out/sync.log'  # log file, set to '/dev/null' if no log file needed
  DESTS = [                     # Destination Hosts
          'hz-wsbuyblog-web1',
          'hz-wsbuyblog-web2',
          'hz-ws-buyblog-web3'
          ]
  DESTS = ['hz-wsbuyblog-web1',]
  ### END OF CONFIGS ###
  
  
  class WorkThread(threading.Thread):
      ''' working thread in thread pool'''
      def __init__(self, work_set, **kwargs):
          threading.Thread.__init__(self, kwargs=kwargs)
          self.work_set = work_set
          self.setDaemon(True)
          self.start()
  
      def run(self):
          '''always trying to get rsync job, if nothing to sync, sleep SLEEP_TIME seconds'''
          while True:
              try:
                  # if too many files need to sync, try rsync dir of these files
                  set_size = len(self.work_set)
                  while set_size > MERGE_NUM:
                      last_size = set_size
                      merge(self.work_set)
                      set_size = len(self.work_set)
                      # Can not merge any more
                      if last_size == set_size:
                          break
                  f = self.work_set.pop()
                  if not f.startswith(BASE_DIR):
                      continue
                  if os.path.isdir(f):
                      dest_file = os.path.dirname(f)
                  else:
                      dest_file = f
                  for d in DESTS:
                      cmd = '/usr/bin/rsync -az --delete %s %s:%s' % (f, d, dest_file)
                      res = commands.getstatusoutput(cmd)
                      if res[0] != 0:
                          flag = 'FAIL'
                      else:
                          flag = 'OK'
                      print '[%s] [WAITING:%s] [%s] %s ---> %s:%s' % (time.strftime('%Y-%m-%d_%H:%M:%S'), len(self.work_set), flag, f, d, dest_file)
              except KeyError:
                  time.sleep(SLEEP_TIME)
              except:
                  print sys.exc_info()
                  raise
  
  
  class ThreadPool:
      # thread pool
      def __init__(self, work_set, thread_num = 10):
          self.work_set = work_set
          self.threads = []
          self.thread_num = thread_num
          self._create_thread_pool()
  
      def _create_thread_pool(self):
          self.threads = []
          for i in range(self.thread_num):
              t = WorkThread(self.work_set)
              self.threads.append(t)
  
  
  def merge(file_set):
      '''
      if more thanfiles in the same dir, use dir instead of these files to make file_set smaller
      '''
      print '### MERGE %s' % len(file_set),
      tmp_set = file_set.copy()
      dir_dic = {}
      for f in tmp_set:
          dir = '/'.join(f.split('/')[:-1])
          if dir in dir_dic:
              dir_dic[dir] += [f,]
          else:
              dir_dic[dir] = [f,]
      for d, fs in dir_dic.items():
          if len(fs) > 1:
              for f in fs:
                  file_set.remove(f)
              file_set.add(d)
      print '---> %s' % len(file_set)
  
  
  def review(file_set):
      '''delete unnecessary files'''
      all_files = file_set.copy()
      for f in all_files:
          # added dir
          if os.path.isdir(f):
              # do not need rsync files in the dir
              tmp_set = file_set.copy()
              for xf in tmp_set:
                  if xf.startswith(f) and xf != f:
                      file_set.remove(xf)
      all_files = file_set.copy()
      for f in all_files:
          # deleted file or dir
          if not os.path.isfile(f) and not os.path.isdir(f):
              file_set.remove(f)
              father = '/'.join(f.split('/')[:-1])
              while not os.path.isdir(father):
                  father = '/'.join(father.split('/')[:-1])
              file_set.add(father)
              tmp_set = file_set.copy()
              for xf in tmp_set:
                  if xf.startswith(father) and xf != father:
                      file_set.remove(xf)
  
  
  def main():
      file_set = set([])
      tp = ThreadPool(file_set, THREAD_NUM)
      if not tp:
          print "create thread pool failed"
          return False
      while True:
          line = sys.stdin.readline()
          ignore = False
          if not line:
              break
          line = line.strip()
          file_set_tmp = file_set.copy()
          for exist_file in file_set_tmp:
              if line.startswith(exist_file) and line != exist_file:
                  ignore = True
                  break
          if ignore:
              continue
          file_set.add(line)
          review(file_set)
  
  
  if __name__ == '__main__':
      main()
1
0
分享到:
评论

相关推荐

    rsync+inotify实现服务器之间文件实时同步

    可以实现触发式的文件同步,但使用crontab守护进程方式进行触发同步的数据和实际数据会有差异,而inotify可以监控文件系统的各种变化,当文件有任何变动时,就触发rsync同步,这样刚好解决了同步数据的实时性问题。...

    Inotify+Rsync实现linux文件实时同步(网上copy他人文章)

    **Inotify+Rsync实现文件同步** 结合Inotify和Rsync,我们可以构建一个实时文件同步系统。当Inotify检测到文件变化时,会触发Rsync进行同步操作。以下是实现步骤: 1. **安装Inotify-tools和Rsync** 在Linux系统中...

    inotify和rsync实现文件同步.zip

    本文将深入探讨如何使用`inotify-tools`和`rsync`这两个工具来实现文件的实时同步,以及如何结合`shell`脚本来自动化这一过程。 `inotify-tools`是一个用于Linux内核`inotify`接口的用户空间工具集。`inotify`提供...

    inotify + rsync实现linux文件实时同步.doc

    下面我们将详细探讨 `inotify` 的功能特性、`inotify-tools` 的安装与使用,以及如何与 `rsync` 配合实现文件实时同步。 一、inotify 介绍 `inotify` 是 Linux 内核提供的一种文件系统事件监控机制,相比于早期的 ...

    CentOS下用rsync+inotify实现实时同步

    CentOS 7下用rsync+inotify实现实时同步可以实现文件之间的同步备份。下面是相关知识点的详细解释: 1. rsync简介 rsync是一种快速、可靠、安全的文件同步工具。它可以在本地或远程主机之间同步文件,具有高效、...

    linux下Rsync+sersync实现文件数据实时同步

    在Linux环境中,文件数据的实时同步是系统管理中的重要任务,尤其对于分布式系统和多服务器环境。`Rsync`和`sersync`是两个常用的工具,它们能够有效地帮助我们完成这个任务。本文将深入探讨这两个工具的工作原理、...

    rsync+inotify实现服务器之间目录文件实时同步

    结合 rsync 使用 inotify 可以实现实时监控文件系统变化,并在变化发生时立即启动 rsync 同步任务,从而提高数据同步的实时性和一致性。 #### 需求分析与实现步骤 **需求背景**:假设有一家公司的业务需求,需要...

    rsync+inotify 实时远程同步

    使用 Rsync + inotify 实现实时远程同步 Rsync 是一个功能强大且广泛使用的文件同步工具,它可以快速、安全、可靠地同步文件。在服务器之间同步文件时,Rsync 是一个不二之选。Inotify 是一个 Linux 内核提供的文件...

    inotify+rsync实时远程同步包

    本文将深入探讨inotify和rsync这两个工具,以及它们如何协同工作实现文件系统的实时远程同步。 首先,让我们了解inotify。inotify是Linux内核提供的一种文件系统事件监控机制,能够实时跟踪文件系统的变化。它允许...

    两台linux服务器目录实时同步(Rsync+Inotify)

    ### 实时同步技术详解:利用Rsync与Inotify在Linux环境下构建高效同步方案 #### 一、概述 在现代IT环境中,数据同步是一项至关重要的任务,尤其是在多服务器架构下,保持数据的一致性和实时性对于业务连续性至关...

    inotify-tools+rsync同步使用方法介绍

    结合`inotify-tools` 和 `rsync`,我们可以在文件系统发生改变时立即触发`rsync`进行同步,实现近乎实时的数据同步。以下是在CentOS系统上配置和使用这两者的步骤: 1. **安装**: - 安装`inotify-tools`:在...

    Ubuntu 下Rsync+Inotify-tools实现数据实时同步

    Ubuntu结合Rsync和Inotify-tools和脚本实现数据的实时同步

    inotify+rsync实现实时同步的方法

    结合inotify和rsync,可以在检测到源目录有任何变动时,立即触发rsync同步操作,将更新推送到目标目录,实现近乎实时的数据同步。具体实现方法是通过编写脚本,当inotify监控到文件或目录变化时,执行rsync命令进行...

    4-rsync+inotify实时上行同步.docx

    为了实现实时上行同步,即将客户端的文件变化同步到服务器端,可以利用inotify监控客户端文件系统的变动,并通过rsync来同步这些变化。 1. **服务器端配置**: - **修改配置文件**: - 设置用户权限(`uid` 和 `...

Global site tag (gtag.js) - Google Analytics