考虑这种情况。在负载均衡的环境中,我在3个不同的物理服务器上运行3个独立的CMS实例。这三个独立运行的应用程序实例共享同一个数据库。
在每台服务器上,CMS都有一个/ media文件夹,其中包含所有媒体子文件夹和文件。我的问题是我如何在Golang中实现/编码文件复制服务/功能,因此当在其中一个服务器上添加/更改/删除子文件夹或文件时,它将被复制/复制/删除在所有其他服务器上?
我需要查看哪些软件包,或者您可能有一个小代码片段来帮助我开始使用?那太棒了。
编辑: 此问题已标记为"重复",但事实并非如此。但是,它是设置共享网络文件系统的替代方法。我认为在所有服务器上保留同一文件的副本,同步并保持更新可能比共享它们更好。
答案 0 :(得分:3)
你可能不应该这样做。使用分布式文件系统,对象存储(ala S3或GCS)或同步程序(如btsync或syncthing)。
如果您仍想自己做这件事,那将是一项挑战。您基本上是在构建分布式数据库,但很难做到正确。
乍一看,您可以查看etcd或raft之类的内容,但不幸的是,etcd对大文件效果不佳。
您可以在上传时使用ssh将文件复制到其他所有服务器。但是当服务器出现故障时会发生什么?或者当两个人同时更新同一个文件时会发生什么?
也许你可以设计它,使得每个文件都获得一个唯一的id(可能基于其内容的哈希值,因此你可以安全地重复删除),并且这些文件永远不会被更新或删除,只能添加。这将解决同步更新问题,但您仍然遇到停机问题。
一种方法是每个服务器在添加文件时维护仅附加版本日志:
VERSION | FILE HASH
1 | abcd123
2 | efgh456
3 | ijkl789
通过它,您可以从服务器提取每个文件,只需一个数字即可知道何时添加文件。 (例如,如果您认为服务器A是第5版,并且您收到通知,它现在是版本7,您知道需要同步2个文件)
您可以使用数据库表执行此操作:
ID | LOCAL_SERVER_ID | REMOTE_SERVER_ID | VERSION | FILE HASH
您可以定期轮询并通过机器之间的ssh或http进行同步。如果服务器关闭,您可以重试,直到它工作。
或者,如果您不想为此设置集中式数据库,则可以使用memberlist之类的库。每个节点的本地元数据可以是其版本。
无论哪种方式,文件上传到单个服务器之间都会有一些延迟,并且在所有服务器上都可用。处理好这很难,这就是为什么你可能不应该这样做。