V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
Distributions
Ubuntu
Fedora
CentOS
中文资源站
网易开源镜像站
Ansen
V2EX  ›  Linux

请教一个 Linux 服务器文件双向实时同步问题

  •  
  •   Ansen · 2015-09-12 12:17:06 +08:00 · 7044 次点击
    这是一个创建于 3121 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现有服务器如下

    • Nginx Server
    • File Server A
    • File Server B

    目前是使用 Nginx Server 反向代理 两台 File Server

    在使用过程中,用户会随机上传文件到其中一台 File Server (主要是静态文件)

    那么要怎么才能让两台 File Server 之前的文件实时保持一致呢?

    文件同步流程如下:
    A =实时=> B
    B <=实时= A

    在此处使用 inotify 貌似会造成无限循环

    考虑过使用 NFS 共享,如果 NFS 宕掉的时候 可能会造成用户文件丢失

    后期我准备让 Nginx 来处理静态文件,减小 tomcat 的压力(这个可以使用 rsync + inotify 和其中一台服务器保持实时同步就行了)

    第 1 条附言  ·  2015-09-12 17:07:04 +08:00
    可能我没有说清楚

    目前是 NGINX 反代 后端两台 tomcat 服务器(也就帖子中提到的两台 file server )


    42 条回复    2016-01-13 12:17:11 +08:00
    ryd994
        1
    ryd994  
       2015-09-12 12:22:52 +08:00 via Android   ❤️ 1
    只上传到其中一台,另一台在找不到文件的时候,尝试拉取
    Ansen
        2
    Ansen  
    OP
       2015-09-12 12:41:28 +08:00
    @ryd994 开发那边实现吗?
    Aliencn
        3
    Aliencn  
       2015-09-12 12:50:24 +08:00   ❤️ 1
    看看能否读写分离,这样只做单项同步就行了
    ansemz
        4
    ansemz  
       2015-09-12 13:00:24 +08:00   ❤️ 1
    用分布式文件系统即可。 glusterfs 比较适用这种场景。
    Ansen
        5
    Ansen  
    OP
       2015-09-12 13:14:31 +08:00
    @Aliencn 主要是写,读我可以配置读 nginx 上面的
    cevincheung
        6
    cevincheung  
       2015-09-12 13:22:49 +08:00   ❤️ 1
    sersync
    ryd994
        7
    ryd994  
       2015-09-12 15:14:52 +08:00   ❤️ 1
    nginx proxy_storage
    这个估计你用得到
    Ansen
        8
    Ansen  
    OP
       2015-09-12 15:19:23 +08:00
    @ansemz 如果用 glusterfs 那是不是 AB 要同时作为 服务端和客户端
    Ansen
        9
    Ansen  
    OP
       2015-09-12 15:20:19 +08:00
    @ryd994 非常感谢,这样我就不需要考虑 nginx 服务器的同步问题了
    fangpeishi
        10
    fangpeishi  
       2015-09-12 16:22:22 +08:00
    btsync ?
    Orzzzz
        11
    Orzzzz  
       2015-09-12 16:44:15 +08:00   ❤️ 1
    我想到的办法是利用现成的 seafile ,在你的两台 fileserver A 和 B 的基础上,再加一台总的 fileserver_C , server_C 作为服务端,而 A 和 B 作为客户端,反正是内网,速度肯定很快的,而且,最重要的, server_C 上的文件都会有时间点备份,就是数据不丢失,缺点是,如果读写过于频繁,那在 server_C 上产生的数据量也是很大的。。

    希望能帮到你。
    wdongxv
        12
    wdongxv  
       2015-09-12 16:44:50 +08:00 via iPhone
    nginx 判断文件是否存在,不存在反向代理到另一台。这里要自定义一个 http 头来防止陷入死循环。
    Ansen
        13
    Ansen  
    OP
       2015-09-12 16:47:43 +08:00
    @wdongxv 这样会增加 nginx 服务器的负担,而且当后端服务器数量较多的时候响应时间太长
    Ansen
        14
    Ansen  
    OP
       2015-09-12 16:48:34 +08:00
    @fangpeishi btsync 是最简单的解决方法了,但是我不知道在生产环境中表现如何
    ab
        15
    ab  
       2015-09-12 16:57:19 +08:00 via iPhone   ❤️ 1
    A 反代 B B 反代 C 文件传到 C 用 proxy storage
    Ansen
        16
    Ansen  
    OP
       2015-09-12 17:07:24 +08:00
    @ab 这样服务器的架构就全乱了
    rrfeng
        17
    rrfeng  
       2015-09-12 17:45:40 +08:00
    发布代码的时候把静态文件 rsync 到 nginx 上一份也不是很难吧!
    Ansen
        18
    Ansen  
    OP
       2015-09-12 18:20:40 +08:00
    @rrfeng 项目引用的倒是简单,但是用户上传的就不好处理了
    9hills
        19
    9hills  
       2015-09-12 18:24:39 +08:00   ❤️ 1
    @Ansen btsync 不一定是最简单的,但一定是最坑爹的。这种双写绝对不能用 sync 架构

    要么就是单写多读,要么就是网络文件系统(有 NFS , iSCSI ,分布式文件系统)

    分布式文件系统不要用 GlusterFS ,此货坑爹
    gamexg
        20
    gamexg  
       2015-09-12 18:26:40 +08:00
    即使能上传到两个上面你也分开到不同的路径啊。
    比如上传到服务器 A 的文件路径是 static.xxx.com/a/filename
    上传到 B 的是 static.xxx.com/b/filename

    这样就变成了单向同步了,难度降低多了。
    ab
        21
    ab  
       2015-09-12 18:31:19 +08:00
    @Ansen 我认为这是最简单也最容易实现的方案,文件也只会拉取一次
    vietor
        22
    vietor  
       2015-09-12 18:42:25 +08:00 via Android   ❤️ 1
    最差也是 NFS
    Ansen
        23
    Ansen  
    OP
       2015-09-12 18:56:33 +08:00
    @9hills 目前我用 NFS 顶着的
    FastDFS 怎么样呢?我朋友说他们生产用的这个

    但是我没有配置过分面式文件系统,不我的情况能适用不

    AB 上有 tomcat 应用,用户通过 tomcat web 上传到服务器本地,在此前提下下载做 分布式 可靠吗?

    主要是目前增加 服务器 不太现实,



    @gamexg
    你提醒了我,如果我再使用 ln 做个软链接,是不是每次去更改 web 应用 的配置文件


    @vietor

    现在只有 用 NFS 顶着了,还好项目刚上线 流量不大
    Ansen
        24
    Ansen  
    OP
       2015-09-12 18:58:20 +08:00
    @gamexg 打漏了
    如果我再使用 ln 做个软链接,是不是不用每次单独去更改 web 应用 的配置文件
    willis
        25
    willis  
       2015-09-12 20:26:45 +08:00   ❤️ 1
    FastDFS 两台 tomcat 在有个 storage 组里,同过 tracker 写入文件时,是 可以同时写两台的
    gamexg
        26
    gamexg  
       2015-09-12 20:52:28 +08:00   ❤️ 1
    @Ansen 不太明白你的意思。

    简单办法:
    上传到两个服务器的文件路径分开。
    比如上传到服务器 A 的文件路径是 static.xxx.com/a/filename ,存放到 /web/a/filename 。
    上传到 B 的是 static.xxx.com/b/filename ,存放到 /web/b/filename 。

    既然前面有 nginx ,那么直接让 nginx 根据路径转发到不同的后端, static.xxx.com/a/filename 到服务器 a , b 的转发到服务器 b 。

    想要备份定时 rsync 单向同步,作为备份。这样即使某台后端掉了,另一台负责全部的请求,可能会丢失部分最新的文件,大部分文件都没问题。

    这是临时的办法,如果预期短时间内服务器不会继续增加可以这样临时解决。虽然继续增加的服务器也可以继续两两一对这么继续用下去,但是还是建议用专门的文件储存。
    Ansen
        27
    Ansen  
    OP
       2015-09-12 22:02:56 +08:00 via iPhone
    @gamexg 仔细想了下 你提供的方案不能用的
    nginx 反代后 前端请求都是一样的
    所以无法通过请求来转发
    还是感谢你热心提供解决方案
    test0x01
        28
    test0x01  
       2015-09-12 22:42:46 +08:00 via Android
    Btsync
    zhuang
        29
    zhuang  
       2015-09-12 22:51:06 +08:00   ❤️ 2
    单纯说需要个解决方案的话可以考虑 csync2 。

    合理的做法是修改应用存储逻辑,重做存储系统的结构。

    根据 CAP 理论( https://en.wikipedia.org/wiki/CAP_theorem ),实时性、一致性和可用性三者只能取其二。
    ansemz
        30
    ansemz  
       2015-09-12 23:33:24 +08:00   ❤️ 1
    @Ansen 抱歉,今天一直在外面。如果用 glusterfs 的话, A , B 同时为服务端和客户端。用双副本模式的 volume 即可,文件通过 glusterfs 客户端写入时,由 glusterfs 本身负责分别存一份在 A 和 B 上。有位 v 友说 glusterfs 坑爹,可能是由于性能的问题。所以如果你的需求对读写性能有很高的要求的话,建议做充分的测试之后才决定是否采用。不过就我个人的经验来说,大部分场景(尤其是冷数据多的时候), glusterfs 还是可以满足的。而且 glusterfs 现在是红帽在开发,质量和文档还是有保证的。
    ryd994
        31
    ryd994  
       2015-09-13 09:56:14 +08:00 via Android
    ryd994
        32
    ryd994  
       2015-09-13 10:01:05 +08:00 via Android   ❤️ 1
    用 proxy_next_upstream http_404 就可以在找不到时尝试下一台
    用 split_clients 做写的分流
    保证没有重复文件的前提下,异步互相拉取
    否则就只能单写,这种时候就优先尝试读不写的服务器,避免负载全堆在一台上
    ryd994
        33
    ryd994  
       2015-09-13 10:05:31 +08:00 via Android
    另外, Nginx 利用 upstream 里的 hash 选项,是可以做到相对稳定的 hash 分流的,@gamexg 的做法也是可行的。而且因为固定分流, proxy_next_upstream http_404 就不需要了,在故障时互为备份而已
    jiakon
        34
    jiakon  
       2015-09-13 21:55:12 +08:00   ❤️ 1
    应用跟数据分离,把后端的存储独立出来,两个 tomcat 都读同一份的存储。
    nekoyaki
        35
    nekoyaki  
       2015-09-14 15:02:21 +08:00   ❤️ 1
    如果你的读文件的操作,没有遍历、列出等操作的话,用 glusterfs 很合适。 glusterfs 的设计决定了,如果已知路径和文件名,读写文件会很快,不会因为存储空间越来越大而降低性能;但是相应地,列出、遍历等事先不知道文件路径的操作就会慢。
    Ansen
        36
    Ansen  
    OP
       2015-09-14 16:17:30 +08:00
    @nekoyaki 不需要遍历,用户上传的图片而已
    nekoyaki
        37
    nekoyaki  
       2015-09-14 16:33:53 +08:00   ❤️ 1
    @Ansen 那 glusterfs 很适合。 glusterfs 是去中心、没有元数据服务器的,因此能够避免单点故障。
    根据具体的配置方式不同,可以配置成类似 RAID0 或 RAID1 的,还可以组合起来。因此配置合理的话,数据比较安全,而且不会有单点故障,性能也过得去。以后扩容也方便,只要把对应的物理卷扩容就行。
    Nitromethane
        38
    Nitromethane  
       2015-11-07 09:28:16 +08:00   ❤️ 1
    我觉得楼主早晚要上 hadoop 的,把在 nginx 上跑一个 NameNode ,后一台跑 dataNode
    alvy
        39
    alvy  
       2016-01-13 11:40:39 +08:00
    此问题到底怎么解决呢?
    Ansen
        40
    Ansen  
    OP
       2016-01-13 11:46:59 +08:00 via iPhone
    @alvy 还是搭了分布式文件服务器
    alvy
        41
    alvy  
       2016-01-13 11:51:34 +08:00
    @Ansen 小白求详解
    Ansen
        42
    Ansen  
    OP
       2016-01-13 12:17:11 +08:00
    @alvy FastDFS 和 glusterfs 这种分布式文件系统
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   我们的愿景   ·   实用小工具   ·   3571 人在线   最高记录 6543   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 04:46 · PVG 12:46 · LAX 21:46 · JFK 00:46
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.