博客
关于我
Swift中的Account Server代码解读
阅读量:184 次
发布时间:2019-02-28

本文共 5189 字,大约阅读时间需要 17 分钟。

用户的HTTP请求被AccountController、ContainerController与ObjectController分别转发给存储节点上的Account Server、Container Server和Object Server,这三个服务与Proxy Server一样也是WSGI Server,通过run_wsgi()函数启动,通过Paste Deploy加载对应的WSGI Application
Account Server的Paste配置文件位于/etc/swift/account-server/目录下:
[pipeline:main]pipeline = healthcheck recon account-server[app:account-server]use = egg:swift#account
setup.cfg文件配置如下:
[entry_points]paste.app_factory =    proxy = swift.proxy.server:app_factory    object = swift.obj.server:app_factory    mem_object = swift.obj.mem_server:app_factory    container = swift.container.server:app_factory    account = swift.account.server:app_factory
结合Paste配置文件与setup.cfg文件的设置,Paste Deply最终将使用swift.account.server模块的app_factory()函数加载Account Server的WSGI Application,即swift.account.server. AccountController
#swift/account/server.pyclass AccountController(object):def app_factory(global_conf, **local_conf):    """paste.deploy app factory for creating WSGI account server apps"""    conf = global_conf.copy()    conf.update(local_conf)return AccountController(conf)
这里的Controller与上述swift/proxy/controllers目录下的Controller不同,后者的作用是将用户的HTTP请求转发给Account Server,而前者则是对该请求的最终处理。
以PUT操作为例,针对Account的PUT操作有两种语义:
1 创建一个Account
2 创建Account中的Container。它们的区别在于路径参数是否包含Container的信息。
#swift/account/server.pyclass AccountController(object):    """WSGI controller for the account server."""    def PUT(self, req):        """Handle HTTP PUT request."""        #从请求参数req里面获取drive, part, account, container信息        drive, part, account, container = split_and_validate_path(req, 3, 4)        if self.mount_check and not check_mount(self.root, drive):            return HTTPInsufficientStorage(drive=drive, request=req)        #如果container的信息不为空,则视该请求为创建某个account的container        if container: # put account container            if 'x-timestamp' not in req.headers:                timestamp = Timestamp(time.time())            else:                timestamp = valid_timestamp(req)            pending_timeout = None            container_policy_index = \                req.headers.get('X-Backend-Storage-Policy-Index', 0)            if 'x-trans-id' in req.headers:                pending_timeout = 3            #构建并返回一个AccountBroker类的实例。AccountBroker类继承于            #DatabaseBroker类,其内部包括了针对account数据库文件的操作函数。            #可以把partition理解为一个目录,每一个partition中的accout数据是以这个目录            #中的数据库文件形式存在的。            #该partition中的每一个account都对应一个数据库文件。            #AccountBroker这个类将操作account数据库文件的函数加以封装,            #作为其成员函数来使用            broker = self._get_account_broker(drive, part, account,                                              pending_timeout=pending_timeout)            if account.startswith(self.auto_create_account_prefix) and \                    not os.path.exists(broker.db_file):                try:                    #如果该account的数据库文件尚未存在,则调用AccountBroker类的                    #initialize()函数创建该数据文件。                    broker.initialize(timestamp.internal)                except DatabaseAlreadyExists:                    pass            if req.headers.get('x-account-override-deleted', 'no').lower() != \                    'yes' and broker.is_deleted():                return HTTPNotFound(request=req)            #通过调用AccountBroker中的put_container()函数将container的信息            #写入该account的数据库文件中去。            broker.put_container(container, req.headers['x-put-timestamp'],                                 req.headers['x-delete-timestamp'],                                 req.headers['x-object-count'],                                 req.headers['x-bytes-used'],                                 container_policy_index)            if req.headers['x-delete-timestamp'] > \                    req.headers['x-put-timestamp']:                return HTTPNoContent(request=req)            else:                return HTTPCreated(request=req)        #如果container的信息为空,则视该请求为创建account        else: # put account            timestamp = valid_timestamp(req)            #获取一个AccountBroker的实例            broker = self._get_account_broker(drive, part, account)            #如果该account的数据库文件未存在则创建            if not os.path.exists(broker.db_file):                try:                    broker.initialize(timestamp.internal)                    created = True                except DatabaseAlreadyExists:                    created = False            elif broker.is_status_deleted():                return self._deleted_response(broker, req, HTTPForbidden,                                              body='Recently deleted')            else:                created = broker.is_deleted()                broker.update_put_timestamp(timestamp.internal)                if broker.is_deleted():                    return HTTPConflict(request=req)            metadata = {}            metadata.update((key, (value, timestamp.internal))                            for key, value in req.headers.iteritems()                            if is_sys_or_user_meta('account', key))            if metadata:                 #更新元数据                broker.update_metadata(metadata, validate_metadata=True)            if created:                return HTTPCreated(request=req)            else:                return HTTPAccepted(request=req)

转载地址:http://flej.baihongyu.com/

你可能感兴趣的文章
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_增加修改实时同步_使用JsonPath及自定义Python脚本_03---大数据之Nifi工作笔记0055
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表多表增量同步_插入修改删除增量数据实时同步_通过分页解决变更记录过大问题_01----大数据之Nifi工作笔记0053
查看>>
NIFI1.21.0通过Postgresql11的CDC逻辑复制槽实现_指定表或全表增量同步_实现指定整库同步_或指定数据表同步配置_04---大数据之Nifi工作笔记0056
查看>>
NIFI1.23.2_最新版_性能优化通用_技巧积累_使用NIFI表达式过滤表_随时更新---大数据之Nifi工作笔记0063
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现update数据实时同步_实际操作05---大数据之Nifi工作笔记0044
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_根据binlog实现数据实时delete同步_实际操作04---大数据之Nifi工作笔记0043
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置binlog_使用处理器抓取binlog数据_实际操作01---大数据之Nifi工作笔记0040
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_实现数据插入数据到目标数据库_实际操作03---大数据之Nifi工作笔记0042
查看>>
NIFI从MySql中增量同步数据_通过Mysql的binlog功能_实时同步mysql数据_配置数据路由_生成插入Sql语句_实际操作02---大数据之Nifi工作笔记0041
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_03_来吧用NIFI实现_数据分页获取功能---大数据之Nifi工作笔记0038
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_不带分页处理_01_QueryDatabaseTable获取数据_原0036---大数据之Nifi工作笔记0064
查看>>
NIFI从MySql中离线读取数据再导入到MySql中_无分页功能_02_转换数据_分割数据_提取JSON数据_替换拼接SQL_添加分页---大数据之Nifi工作笔记0037
查看>>
NIFI从Oracle11G同步数据到Mysql_亲测可用_解决数据重复_数据跟源表不一致的问题---大数据之Nifi工作笔记0065
查看>>
NIFI从PostGresql中离线读取数据再导入到MySql中_带有数据分页获取功能_不带分页不能用_NIFI资料太少了---大数据之Nifi工作笔记0039
查看>>
nifi使用过程-常见问题-以及入门总结---大数据之Nifi工作笔记0012
查看>>
NIFI分页获取Mysql数据_导入到Hbase中_并可通过phoenix客户端查询_含金量很高的一篇_搞了好久_实际操作05---大数据之Nifi工作笔记0045
查看>>
NIFI分页获取Postgresql数据到Hbase中_实际操作---大数据之Nifi工作笔记0049
查看>>
NIFI同步MySql数据_到SqlServer_错误_驱动程序无法通过使用安全套接字层(SSL)加密与SQL Server_Navicat连接SqlServer---大数据之Nifi工作笔记0047
查看>>
NIFI同步MySql数据源数据_到原始库hbase_同时对数据进行实时分析处理_同步到清洗库_实际操作06---大数据之Nifi工作笔记0046
查看>>
Nifi同步过程中报错create_time字段找不到_实际目标表和源表中没有这个字段---大数据之Nifi工作笔记0066
查看>>