回答我自己的问题不是最好的做法,但是,当我最终放弃这个 idea 时,我想分享一下在我的 case 中起作用的理由.我想强调的是,这一基本原理可能并不适用于所有情况,因此应由架构师决定.
一般来说,我的问题忽略的第一个要点是,我正在处理multi-user system个并行、并行工作的问题,使用我的服务器和瘦客户机(即仅一个web浏览器).这样的话,我必须为所有的人保持state.有几种方法可以实现这一点,但它们要么对资源要求太高,要么太复杂而无法实现(因此,首先要把所有难以实现的东西都转移到git上,这有点扼杀了最初的目的):
"钝"方法:1个用户=1个状态=1个服务器为用户维护的存储库的完整工作副本.即使我们谈论的是相当小的文档数据库(例如,100s MIB),用户数量约为100K,为所有用户维护完整的存储库克隆也会使光盘的使用量激增(即100K用户乘以100MB~10TIB).更糟糕的是,每次克隆100个MiB存储库都需要几秒钟的时间,即使是以相当有效的方式完成(即git不使用和解包重新打包的内容),这是不可接受的,我认为.更糟糕的是,我们应用于主树的每一次编辑都应该被拉到每个用户的存储库,这是(1)资源占用,(2)在一般情况下可能会导致未解决的编辑冲突.
Basically, it might be as bad as O(number of edits × data × number of users) in terms of disc usage, and such disc usage automatically means pretty high CPU usage.
"仅限活动用户"方法:仅为活动用户维护工作副本.这样,您通常不会按用户存储完整的repo-clone-,而是:
- 用户登录时,可以克隆存储库.每个活动用户需要几秒钟和大约100 MiB的磁盘空间.
- 当用户继续在站点上工作时,他将使用给定的工作副本.
- 当用户注销时,他的存储库克隆会作为一个分支复制回主存储库,因此只存储他的"未应用的更改"(如果有),这相当节省空间.
Thus, disc usage in this case peaks at O(number of edits × data × number of active users), which is usually ~100..1000 times less than number of total users, but it makes logging in/out more complicated and slower, as it involves cloning of a per-user branch on every login and pulling these changes back on logout or session expiration (which should be done transactionally => adds another layer of complexity). In absolute numbers, it drops 10 TiBs of disc usage down to 10..100 GiBs in my case, that might be acceptable, but, yet again, we're now talking about fairly small database of 100 MiBs.
"稀疏签出"方法:对每个活动用户进行"稀疏签出"而不是全面的回购克隆并没有多大帮助.它可能会节省约10倍的磁盘空间使用,但代价是在涉及操作的历史记录上,CPU/磁盘的负载要高得多,这就扼杀了它的用途.
"工作人员池"方法:我们可能会保留一个"工作人员"克隆池,以备使用,而不是每次都为活动人员进行全面克隆.这样,每次用户登录时,他都会占用一个"worker",将其分支从主repo拉到那里,然后在他注销时释放"worker",这会使git进行巧妙的硬重置,再次成为一个主repo克隆,供另一个登录用户使用.这对光盘使用没有多大帮助(它仍然很高——每个活动用户只能进行完整克隆),但至少它可以加快登录/注销速度,从而降低复杂性.
也就是说,请注意,我特意计算了相当小的数据库和用户群的数量:10万个用户,1万个活动用户,100个MIB总数据库+编辑历史,10个MIB的工作副本.如果你看看更著名的众包项目,其中的数字要高得多:
│ │ Users │ Active users │ DB+edits │ DB only │
├──────────────┼───────┼──────────────┼──────────┼─────────┤
│ MusicBrainz │ 1.2M │ 1K/week │ 30 GiB │ 20 GiB │
│ en.wikipedia │ 21.5M │ 133K/month │ 3 TiB │ 44 GiB │
│ OSM │ 1.7M │ 21K/month │ 726 GiB │ 480 GiB │
显然,对于如此大量的数据/活动,这种方法是完全不可接受的.
一般来说,如果你能把网络浏览器当作一个"胖"客户端使用,也就是说,发出git操作并在客户端(而不是在服务器端)存储几乎全部的 checkout 记录,那么这种方法是可行的.
我还漏掉了其他几点,但与第一点相比,它们并没有那么糟糕:
- 就普通ORM(如ActiveRecord、Hibernate、DataMapper、Tower等)而言,具有"密集"用户编辑状态的模式本身是有争议的.
- 在我搜索的范围内,现有的免费代码库是零,可以从流行的框架中使用这种方法来实现git.
- 至少有一个服务能以某种方式高效地做到这一点--显然是github个--但是,唉,他们的代码库是封闭源代码的,我强烈怀疑他们没有在内部使用普通的git服务器/repo存储技术,也就是说,他们基本上实现了替代的" Big Data "git.
所以,bottom line:is是可能的,但对于大多数当前用例来说,它不会接近最佳解决方案.将自己的文档编辑历史记录汇总到SQL实现中,或者try 使用任何现有的文档数据库,可能是更好的 Select .