OpenStack_Swift源码分析——ObjectReplicator源码分析(1)

1、ObjectorReplicator的启动

首先运行启动脚本

swift-init object-replicator start

此运行脚本的运行过程和ring运行脚本运行过程差不多,找到swift 源码bin下的swift-object-replicator其代码如下所示

if __name__ == ‘__main__‘:
    parser = OptionParser("%prog CONFIG [options]")
    parser.add_option(‘-d‘, ‘--devices‘,
                      help=‘Replicate only given devices. ‘
                           ‘Comma-separated list‘)
    parser.add_option(‘-p‘, ‘--partitions‘,
                      help=‘Replicate only given partitions. ‘
                           ‘Comma-separated list‘)
    conf_file, options = parse_options(parser=parser, once=True)
    run_daemon(ObjectReplicator, conf_file, **options)

最后一行:

 run_daemon(ObjectReplicator, conf_file, **options)

也就是要执行run_daemon()函数,为其传入的是ObjectReplicator和配置文件参数已经选项参数,下面继续看run_daemon方法,他是swift/daemon.py下Daemon类中的方法,看具体代码实现:

def run_daemon(klass, conf_file, section_name=‘‘, once=False, **kwargs):
    """
    Loads settings from conf, then instantiates daemon "klass" and runs the
    daemon with the specified once kwarg.  The section_name will be derived
    from the daemon "klass" if not provided (e.g. ObjectReplicator =>
    object-replicator).

    :param klass: Class to instantiate, subclass of common.daemon.Daemon
    :param conf_file: Path to configuration file
    :param section_name: Section name from conf file to load config from
    :param once: Passed to daemon run method
    """
    # very often the config section_name is based on the class name
    # the None singleton will be passed through to readconf as is
    if section_name is ‘‘:
        #得到section_name = ojbect-replicator  sub()为正则表达式
        section_name = sub(r‘([a-z])([A-Z])‘, r‘\1-\2‘,
                           klass.__name__).lower()

    conf = utils.readconf(conf_file, section_name,
                          log_name=kwargs.get(‘log_name‘))

    # once on command line (i.e. daemonize=false) will over-ride config
    once = once or not utils.config_true_value(conf.get(‘daemonize‘, ‘true‘))

    # pre-configure logger
    if ‘logger‘ in kwargs:
        logger = kwargs.pop(‘logger‘)
    else:
        logger = utils.get_logger(conf, conf.get(‘log_name‘, section_name),
                                  log_to_console=kwargs.pop(‘verbose‘, False),
                                  log_route=section_name)

    # disable fallocate if desired
    if utils.config_true_value(conf.get(‘disable_fallocate‘, ‘no‘)):
        utils.disable_fallocate()
    # set utils.FALLOCATE_RESERVE if desired
    reserve = int(conf.get(‘fallocate_reserve‘, 0))
    if reserve > 0:
        utils.FALLOCATE_RESERVE = reserve

    # By default, disable eventlet printing stacktraces
    eventlet_debug = utils.config_true_value(conf.get(‘eventlet_debug‘, ‘no‘))
    eventlet.debug.hub_exceptions(eventlet_debug)

    # Ensure TZ environment variable exists to avoid stat(‘/etc/localtime‘) on
    # some platforms. This locks in reported times to the timezone in which
    # the server first starts running in locations that periodically change
    # timezones.
    os.environ[‘TZ‘] = time.strftime("%z", time.gmtime())

    try:
        #开始运行
        klass(conf).run(once=once, **kwargs)
    except KeyboardInterrupt:
        logger.info(‘User quit‘)
    logger.info(‘Exited‘)

因ObjectReplicator继承了Daemon类,代码片段

 klass(conf).run(once=once, **kwargs)

ObjectReplicator执行run方法,主要此时传入的once为False一般once在测试时可以设为True。继续看run方法,在Objector中没有实现run方法,其继承了父类的方法,

    def run(self, once=False, **kwargs):
        """Run the daemon"""
        utils.validate_configuration()
        utils.drop_privileges(self.conf.get(‘user‘, ‘swift‘))
        utils.capture_stdio(self.logger, **kwargs)

        def kill_children(*args):
            #SIGTERM = 15  SIG_IGN = 1L
            signal.signal(signal.SIGTERM, signal.SIG_IGN)
            os.killpg(0, signal.SIGTERM)
            sys.exit()

        signal.signal(signal.SIGTERM, kill_children)
        if once:
            self.run_once(**kwargs)
        else:
            self.run_forever(**kwargs)

因once为False所以执行的是run_forever方法,从方法名字面上就可以看出这是一个永久运行的程序,也就是会成为守护进程。

  def run_forever(self, *args, **kwargs):
        self.logger.info(_("Starting object replicator in daemon mode."))
        # Run the replicator continually
        while True:
            start = time.time()
            self.logger.info(_("Starting object replication pass."))
            # Run the replicator
            #执行replicator 程序
            self.replicate()
            total = (time.time() - start) / 60
            self.logger.info(
                _("Object replication complete. (%.02f minutes)"), total)
            dump_recon_cache({‘object_replication_time‘: total,
                              ‘object_replication_last‘: time.time()},
                             self.rcache, self.logger)
            self.logger.debug(_(‘Replication sleeping for %s seconds.‘),
                              self.run_pause)
            #sleep 一段时间时间自己在部署时自己设定,也可以默认为30秒
            sleep(self.run_pause)

在run_forever方法中会执行replicate()方法。下一节介绍replicate方法的具体实现

OpenStack_Swift源码分析——ObjectReplicator源码分析(1)

时间: 2024-10-21 14:13:50

OpenStack_Swift源码分析——ObjectReplicator源码分析(1)的相关文章

OpenStack_Swift源码分析——ObjectReplicator源码分析(2)

1.Replicator执行代码详细分析 上篇问中介绍了启动Replicator的具体过程,下面讲解Replicator的执行代码的具体实现,首先看replicate方法: def replicate(self, override_devices=None, override_partitions=None): """Run a replication pass""" self.start = time.time() self.suffix_co

OpenStack_Swift源码分析——Object-auditor源码分析(1)

1 Object-auditor 的启动 Object-auditor的启动和object-replicator的启动过程是一样的,首先是执行启动脚本 swift-init object-auditor start 启动脚本会运行swift源码bin目录下的swift-ojbect-auditor if __name__ == '__main__': parser = OptionParser("%prog CONFIG [options]") parser.add_option('-

OpenStack_Swift源码分析——Object-auditor源码分析(2)

1 Object-aduitor审计具体分析 上一篇文章中,讲解了Object-aduitor的启动,其中审计的具体执行是AuditorWorker实现的,在run_audit中实例化了AuditorWorker类,并调用audit_all_objects方法,下面看此方法的具体代码实现: def audit_all_objects(self, mode='once', device_dirs=None): #run_forever传过来的mode 为forever description =

HBase1.0.0源码分析之请求处理流程分析以Put操作为例(二)

HBase1.0.0源码分析之请求处理流程分析以Put操作为例(二) 1.通过mutate(put)操作,将单个put操作添加到缓冲操作中,这些缓冲操作其实就是Put的父类的一个List的集合.如下: private List<Row> writeAsyncBuffer = new LinkedList<>(); writeAsyncBuffer.add(m); 当writeAsyncBuffer满了之后或者是人为的调用backgroundFlushCommits操作促使缓冲池中的

nginx源码分析--从源码看nginx框架总结

nginx源码总结: 1)代码中没有特别绕特别别扭的编码实现,从变量的定义调用函数的实现封装,都非常恰当,比如从函数命名或者变量命名就可以看出来定义的大体意义,函数的基本功能,再好的架构实现在编码习惯差的人实现也会黯然失色,如果透彻理解代码的实现,领悟架构的设计初衷,觉得每块代码就想经过耐心雕琢一样,不仅仅实现了基本的功能给你,为其他人阅读也会提供很好的支持.细致恰当的命名规则就可以看出作者的功力. 2)更好更高的软件性能体现在架构设计上,好的架构会让软件更加稳定.容易维护.便于扩展.从核心模块

kafka源码分析之一server启动分析

1. 分析kafka源码的目的 深入掌握kafka的内部原理 深入掌握scala运用 2. server的启动 如下所示(本来准备用时序图的,但感觉时序图没有思维图更能反映,故采用了思维图): 2.1 启动入口Kafka.scala 从上面的思维导图,可以看到Kafka的启动入口是Kafka.scala的main()函数: def main(args: Array[String]): Unit = { try { val serverProps = getPropsFromArgs(args)

老李推荐:第6章5节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-事件

老李推荐:第6章5节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-事件 从网络过来的命令字串需要解析翻译出来,有些命令会在翻译好后直接执行然后返回,但有一大部分命令在翻译后需要转换成对应的事件,然后放入到命令队列里面等待执行.Monkey在取出一个事件执行的时候主要是执行其injectEvent方法来注入事件,而注入事件根据是否需要往系统注入事件分为两种: 需要通过系统服务往系统注入事件:如MonkeyKeyEvent事件会通过系统的InputManager往系

老李推荐:第6章3节《MonkeyRunner源码剖析》Monkey原理分析-事件源-事件源概览-命令翻译类

老李推荐:第6章3节<MonkeyRunner源码剖析>Monkey原理分析-事件源-事件源概览-命令翻译类 每个来自网络的字串命令都需要进行解析执行,只是有些是在解析的过程中直接执行了事,而有些是需要在解析后创建相应的事件类实例并添加到命令队列里面排队执行.负责这部分工作的就是命令翻译类.那么我们往下还是继续在MonkeySourceNetwork这个范畴中MonkeyCommand类是怎么一回事: 图6-3-1 MonkeyCommand族谱 图中间的MonkeyCommand是一个接口,

[ASP.NET]分析MVC5源码,并实现一个ASP.MVC

本节内容不是MVC入门教程,主要讲MVC原理,实现一个和ASP.NET MVC类似基本原理的项目. MVC原理是依赖于ASP.NET管道事件基础之上的.对于这块,可阅读上节内容 [ASP.NET]谈谈IIS与ASP.NET管道 本节目录: MVC简介 MVC5源码 实现一个MVC MVC简介 随着技术的发展,现在已经将MVC模式等同于三层模式. 如果要严格区分的话,UI层指View和Controller,BLL,DAL层和模型层都属于Model中. 在建立MVC项目的时候,选择空的项目,会建立一