技术解析

请教一个 Linux 服务器文件双向实时同步问题
0
2021-07-08 13:42:45
idczone

现有服务器如下

  • 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 和其中一台服务器保持实时同步就行了)


只上传到其中一台,另一台在找不到文件的时候,尝试拉取

开发那边实现吗?

看看能否读写分离,这样只做单项同步就行了

用分布式文件系统即可。 glusterfs 比较适用这种场景。

主要是写,读我可以配置读 nginx 上面的

sersync

nginx proxy_storage
这个估计你用得到

如果用 glusterfs 那是不是 AB 要同时作为 服务端和客户端

非常感谢,这样我就不需要考虑 nginx 服务器的同步问题了

btsync ?

我想到的办法是利用现成的 seafile ,在你的两台 fileserver A 和 B 的基础上,再加一台总的 fileserver_C , server_C 作为服务端,而 A 和 B 作为客户端,反正是内网,速度肯定很快的,而且,最重要的, server_C 上的文件都会有时间点备份,就是数据不丢失,缺点是,如果读写过于频繁,那在 server_C 上产生的数据量也是很大的。。
希望能帮到你。

nginx 判断文件是否存在,不存在反向代理到另一台。这里要自定义一个 http 头来防止陷入死循环。

这样会增加 nginx 服务器的负担,而且当后端服务器数量较多的时候响应时间太长

btsync 是最简单的解决方法了,但是我不知道在生产环境中表现如何

A 反代 B B 反代 C 文件传到 C 用 proxy storage

这样服务器的架构就全乱了

发布代码的时候把静态文件 rsync 到 nginx 上一份也不是很难吧!

项目引用的倒是简单,但是用户上传的就不好处理了

btsync 不一定是最简单的,但一定是最坑爹的。这种双写绝对不能用 sync 架构
要么就是单写多读,要么就是网络文件系统(有 NFS , iSCSI ,分布式文件系统)
分布式文件系统不要用 GlusterFS ,此货坑爹

即使能上传到两个上面你也分开到不同的路径啊。
比如上传到服务器 A 的文件路径是 static.xxx.com/a/filename
上传到 B 的是 static.xxx.com/b/filename
这样就变成了单向同步了,难度降低多了。

我认为这是最简单也最容易实现的方案,文件也只会拉取一次

最差也是 NFS

目前我用 NFS 顶着的
FastDFS 怎么样呢?我朋友说他们生产用的这个
但是我没有配置过分面式文件系统,不我的情况能适用不
AB 上有 tomcat 应用,用户通过 tomcat web 上传到服务器本地,在此前提下下载做 分布式 可靠吗?
主要是目前增加 服务器 不太现实,


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


现在只有 用 NFS 顶着了,还好项目刚上线 流量不大

打漏了
如果我再使用 ln 做个软链接,是不是不用每次单独去更改 web 应用 的配置文件

FastDFS 两台 tomcat 在有个 storage 组里,同过 tracker 写入文件时,是 可以同时写两台的

不太明白你的意思。
简单办法:
上传到两个服务器的文件路径分开。
比如上传到服务器 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 单向同步,作为备份。这样即使某台后端掉了,另一台负责全部的请求,可能会丢失部分最新的文件,大部分文件都没问题。
这是临时的办法,如果预期短时间内服务器不会继续增加可以这样临时解决。虽然继续增加的服务器也可以继续两两一对这么继续用下去,但是还是建议用专门的文件储存。

仔细想了下 你提供的方案不能用的
nginx 反代后 前端请求都是一样的
所以无法通过请求来转发
还是感谢你热心提供解决方案

Btsync

单纯说需要个解决方案的话可以考虑 csync2 。
合理的做法是修改应用存储逻辑,重做存储系统的结构。
根据 CAP 理论( https://en.wikipedia.org/wiki/CAP_theorem ),实时性、一致性和可用性三者只能取其二。

抱歉,今天一直在外面。如果用 glusterfs 的话, A , B 同时为服务端和客户端。用双副本模式的 volume 即可,文件通过 glusterfs 客户端写入时,由 glusterfs 本身负责分别存一份在 A 和 B 上。有位 v 友说 glusterfs 坑爹,可能是由于性能的问题。所以如果你的需求对读写性能有很高的要求的话,建议做充分的测试之后才决定是否采用。不过就我个人的经验来说,大部分场景(尤其是冷数据多的时候), glusterfs 还是可以满足的。而且 glusterfs 现在是红帽在开发,质量和文档还是有保证的。

http://nginx.org/en/docs/http/ngx_http_proxy_module.html#proxy_next_upstream

用 proxy_next_upstream http_404 就可以在找不到时尝试下一台
用 split_clients 做写的分流
保证没有重复文件的前提下,异步互相拉取
否则就只能单写,这种时候就优先尝试读不写的服务器,避免负载全堆在一台上

另外, Nginx 利用 upstream 里的 hash 选项,是可以做到相对稳定的 hash 分流的,@gamexg 的做法也是可行的。而且因为固定分流, proxy_next_upstream http_404 就不需要了,在故障时互为备份而已

应用跟数据分离,把后端的存储独立出来,两个 tomcat 都读同一份的存储。

如果你的读文件的操作,没有遍历、列出等操作的话,用 glusterfs 很合适。 glusterfs 的设计决定了,如果已知路径和文件名,读写文件会很快,不会因为存储空间越来越大而降低性能;但是相应地,列出、遍历等事先不知道文件路径的操作就会慢。

不需要遍历,用户上传的图片而已

那 glusterfs 很适合。 glusterfs 是去中心、没有元数据服务器的,因此能够避免单点故障。
根据具体的配置方式不同,可以配置成类似 RAID0 或 RAID1 的,还可以组合起来。因此配置合理的话,数据比较安全,而且不会有单点故障,性能也过得去。以后扩容也方便,只要把对应的物理卷扩容就行。

我觉得楼主早晚要上 hadoop 的,把在 nginx 上跑一个 NameNode ,后一台跑 dataNode

此问题到底怎么解决呢?

还是搭了分布式文件服务器

小白求详解

FastDFS 和 glusterfs 这种分布式文件系统

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服