连续异步地将本地文件夹同步到s3存储桶

mobius3的Python项目详细描述


mobius3circleci测试覆盖率

连续和异步地将本地文件夹同步到s3存储桶。这是一个python应用程序,适用于

  • 不能使用保险丝,例如在AWS Fargate;
  • 高性能本地访问比同步保存到s3更重要;
  • 单个客户端监视的同一个文件可能会频繁修改;
  • 不同客户机对同一文件的并发修改并不频繁;
  • 任何程序都可以更改本地文件;
  • 最多有~10K个文件要同步;
  • S3存储桶中的更改可以直接执行,即不使用MOBIUS3。

这些属性使mobius3类似于dropbox或google drive客户端。在引擎盖下,使用了inotify,因此只支持Linux。

< Buff行情>

早期版本。请考虑在s3 bucket上启用版本控制,以避免数据丢失。

安装

pip install mobius3

用法

mobius3可以作为独立的命令行应用程序使用

mobius3 /local/folder https://remote-bucket.s3-eu-west-2.amazonaws.com/ eu-west-2 --prefix folder/

或来自Docker

docker run --rm -it \
    -v /local/folder:/home/mobius3/data \
    -e AWS_ACCESS_KEY_ID \
    -e AWS_SECRET_ACCESS_KEY \
    quay.io/uktrade/mobius3:v0.0.22 \
    mobius3 \
        /home/mobius3/data \
        https://remote-bucket.s3-eu-west-2.amazonaws.com/ \
        eu-west-2 \
        --prefix my-prefix/

或来自Asyncio Python

frommobius3importSyncerstart,stop=Syncer('/local/folder','https://remote-bucket.s3-eu-west-2.amazonaws.com/','eu-west-2',prefix='folder/')# Will copy the contents of the bucket to the local folder,# raise exceptions on error, and then continue to sync in the backgroundawaitstart()# Will complete any remaining uploadsawaitstop()

在上述情况下,aws凭证取自aws_access_key_idaws_secret_access_key环境变量。要使用ecs提供的credentials/iam角色,可以将--credentials source ecs container endpoint作为命令行选项传递。在ecs任务定义中,如下所示

{"command":["mobius3","/home/mobius3/data","https://remote-bucket.s3-eu-west-2.amazonaws.com/","eu-west-2","--prefix","my-prefix/""--credentials-source","ecs-container-endpoint"]}

如果使用mobius3同步多个容器访问的卷中的数据,则可能需要创建自己的dockerfile,该dockerfile在与其他容器中的用户具有相同ID的用户下运行mobius3。

在发动机罩和限制下

上传到s3

当文件关闭时,将启动向s3的上载。

从s3下载

一个简单的轮询机制用于检查s3中的更改:因此对于大量的文件/对象,mobius3可能无法执行。如果文件已被本地进程更新或删除,则在文件上传到s3后120秒之前,不会通过轮询将其更新到s3。这是一个最大的尝试,以减少由于s3的最终一致性模型而导致旧版本覆盖新版本的可能性。

重命名文件和文件夹

在s3中,重命名文件或文件夹映射到没有原子操作,并且没有显式的冲突解决方法,因此冲突由s3自己解决:最后一次写入将获胜。这意味着,如果不同客户端同时修改或删除同一文件或文件夹,则可能会丢失数据,并且目录布局可能会损坏。

响应并发文件修改

在上载过程中,文件可以由本地进程修改,因此在这种情况下,损坏的文件可以上载到s3。为了减少这种移动,3对每次上传使用以下算法。

  • 接收到文件的in_close_write事件,然后开始上载。
  • 就在上传结束之前,文件的最后字节从磁盘读取。
  • 一个虚拟的"flush"文件被写入相关目录。
  • 等待此文件的in_create事件。这样可以确保最后读取的字节也已收到。
  • 如果我们收到该文件的in_modify事件,则该文件已被修改,并且我们不会上载最后的字节。由于收到in_modify,一旦文件关闭,我们将收到in_close_write,然后重新上载文件。如果没有收到此类事件,我们将完成上载。

除此之外,还可以使用文件系统锁定机制。然而

  • 其他进程可能不尊重建议锁定;
  • 文件系统可能不支持强制锁定;
  • 我们不希望由于在上载时锁定文件而阻止其他进程的进展:这将部分消除同步的异步特性带来的好处。

保持对同一文件的http请求的顺序

支持对s3的多个并发请求。但是,这可能会带来额外的竞争条件:以给定顺序启动的请求可能不会被s3以该顺序接收。这意味着较新版本的文件可以被较旧的文件覆盖。S3保证"最新时间戳赢"对同一密钥的并发放入不提供保护。

因此,为了防止出现这种情况,在输入和删除任何键的过程中,每个文件周围都会使用一个fifo互斥锁。

与目录具有相同键的对象

s3是键、值存储而不是文件系统:没有将所有可能的键完美地映射到目录结构,例如,它可以存储键aa/b的对象,但是文件系统不能有路径/a/a/b的文件。在这种情况下,mobius3通常将a视为一个文件,而忽略a/b。但是,如果在mobius3运行并在本地同步时创建了a/b,则不会在本地创建a


在将来的版本中,上述某些行为可能会发生变化。

运行测试

docker-compose build &&\
docker-compose run --rm test python3 setup.py test

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
java如何使用Ibatis在插入时返回ID(使用返回关键字)   java(org.hibernate.TransactionException)org。冬眠TransactionException:事务未成功启动   java小程序jwindow始终位于JNLP顶部   在Java中重新解析JSON对象?   java单击后将ListView数据移动到新屏幕   Mule ESB中的java WSA寻址特性   Java,对象编程:获取返回0值的方法   hibernate的Java通用问题,如何处理T get(K id)   java在使用超级CSV读取CSV时忽略引用   ssh使用Java远程运行命令   java如何向具体用户发送websocket消息?   在JAVA中,我可以在不指定的情况下使用条件运算符吗?