Gre*_*Cat 112 database git database-replication database-performance document-database
我正在做一个处理结构化文档数据库的项目.我有一个类别树(约1000个类别,每个级别最多约50个类别),每个类别包含数千个(最多,比方说,~10000)结构化文档.每个文档都是几千字节的数据,采用某种结构化形式(我更喜欢YAML,但它也可能是JSON或XML).
该系统的用户可以进行多种操作:
当然,传统的解决方案是使用某种文档数据库(例如CouchDB或Mongo)来解决这个问题 - 然而,这个版本控制(历史)的东西诱惑我一个疯狂的想法 - 为什么我不应该使用git存储库作为一个这个应用程序的数据库后端?
乍一看,它可以像这样解决:
这个解决方案还有其他常见的陷阱吗?有没有人试图实现这样的后端(即任何流行的框架 - RoR,node.js,Django,CakePHP)?这个解决方案是否会对性能或可靠性产生任何影响 - 即它是否证明git比传统数据库解决方案慢得多,或者存在任何可扩展性/可靠性缺陷?我认为推送/拉取彼此存储库的这类服务器集群应该相当强大和可靠.
基本上,告诉我,如果这个解决方案将工作和为什么它会或不会做?
Gre*_*Cat 53
回答我自己的问题不是最好的办法,但是,当我最终放弃这个想法时,我想分享一下在我的案例中有用的理由.我想强调的是,这个理由可能不适用于所有情况,因此由建筑师来决定.
一般来说,我的问题遗漏的第一个要点是我正在处理多用户系统并行工作,同时使用我的服务器和瘦客户端(即只是一个Web浏览器).这样,我必须保持所有这些状态.有几种方法可以解决这个问题,但是所有这些方法要么资源太难,要么太复杂而无法实现(因此最终会破坏将所有硬实现内容卸载到git的最初目的):
"Blunt"方法:1 user = 1 state =服务器为用户维护的存储库的完整工作副本.即使我们正在讨论具有~100K用户的相当小的文档数据库(例如,100s MiB),维护所有这些用户的完整存储库克隆也会使磁盘使用在屋顶上运行(即100K用户乘以100MiB~10 TiB) .更糟糕的是,每次克隆100 MiB存储库需要几秒钟的时间,即使是在相当有效的maneer(即不使用git和拆包重新打包的东西)中完成的,这是不可接受的,IMO.更糟糕的是 - 我们应用于主树的每个编辑都应该被拉到每个用户的存储库,这是(1)资源占用,(2)在一般情况下可能导致未解决的编辑冲突.
基本上,就光盘使用而言,它可能与O(编辑数量×数据×用户数量)一样糟糕,并且这种光盘使用自动意味着相当高的CPU使用率.
"仅活动用户"方法:仅为活动用户维护工作副本.这样,您通常不会存储每个用户的完全repo-clone,但是:
因此,在这种情况下,磁盘使用率达到峰值O(编辑数量×数据×活跃用户数量),这通常比总用户数少~100..1000倍,但它使登录/退出更加复杂和缓慢,因为它涉及在每次登录时克隆每用户分支,并在注销或会话到期时将这些更改拉回(应该在事务上完成=>增加了另一层复杂性).在绝对数字中,在我的情况下,它会将10 TiB的光盘使用量降低到10..100 GiB,这可能是可以接受的,但是,我们现在再次讨论相当小的100 MiB数据库.
"稀疏结账"方法:对每个活跃用户进行"稀疏结账"而不是完整的回购克隆并没有多大帮助.它可以节省大约10倍的磁盘空间使用量,但是在历史参与操作中牺牲了更高的CPU /磁盘负载,这种目的就是杀死它.
"工人集中"的方法:我们可能会保留一堆"工人"克隆,而不是每次为活跃的人做完全克隆,准备使用.这样,每次用户登录时,他就会占用一个"工人",从主要仓库拉出他的分支,并且,当他退出时,他释放了"工人",这使得聪明的git硬重置再次变得刚好一个主要的repo克隆,准备好由另一个用户登录使用.对光盘使用没有多大帮助(它仍然相当高 - 每个活动用户只有完全克隆),但至少它使登录/退出速度更快,更复杂.
也就是说,请注意我有意计算了相当小的数据库和用户群的数量:100K用户,1K活跃用户,100 MiBs总数据库+编辑历史,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 ?
Run Code Online (Sandbox Code Playgroud)
显然,对于那些数据/活动,这种方法是完全不可接受的.
一般情况下,如果可以将Web浏览器用作"厚"客户端,即发出git操作并在客户端存储相当多的完整结账,而不是在服务器端,它就会起作用.
我还错过了其他一些观点,但与第一点相比,它们并没有那么糟糕:
所以,底线:它是可能的,但对于大多数当前的用例,它不会接近最佳解决方案.汇总您自己的文档编辑历史到SQL实现或尝试使用任何现有的文档数据库可能是一个更好的选择.
Kom*_*owy 12
一个有趣的方法确实.我想说,如果您需要存储数据,请使用数据库,而不是源代码存储库,它是专为特定任务而设计的.如果您可以使用Git开箱即用,那么它很好,但您可能需要在其上构建文档存储库层.所以你也可以在传统的数据库上构建它,对吗?如果它是您感兴趣的内置版本控件,为什么不使用开源文档存储库工具呢?有很多可供选择.
好吧,如果你决定去Git后端,那么如果你按照描述实现它,基本上它可以满足你的要求.但:
1)你提到"服务器集群互相拉/拉" - 我已经考虑了一段时间,但我仍然不确定.你不能推/拉几个repos作为原子操作.我想知道在并发工作期间是否可能出现一些合并混乱的可能性.
2)也许您不需要它,但是您未列出的文档存储库的明显功能是访问控制.您可以通过子模块限制对某些路径(=类别)的访问,但可能您无法轻松地在文档级别上授予访问权限.
you*_*ngo 11
我的2便士价值.有点渴望,但......我的一个孵化项目有类似的要求.与你的类似,我的关键要求是文档数据库(在我的情况下为xml),文档版本控制.它适用于具有大量协作用例的多用户系统.我倾向于使用支持大多数关键要求的可用开源解决方案.
为了减少追逐,我找不到任何一个提供这两者的产品,其方式足够可扩展(用户数量,使用量,存储和计算资源).我对所有有前途的功能都倾向于git,并且(可能的)解决方案可以制造出来.随着我更多地使用git选项,从单用户角度转向多(毫)用户角度成为一个明显的挑战.不幸的是,我没有像你那样做大量的性能分析.(..懒惰/退出早......对于版本2,口头禅)给你力量!无论如何,我的偏见已经转变为下一个(仍有偏见的)替代方案:在各自的领域,数据库和版本控制中最好的工具网格化.
虽然仍在进行中(......并且稍微忽略了),但变形版本就是这样.
从本质上讲,它相当于向数据库中添加一个版本控制插件,使用一些集成粘合剂,您可能需要开发它,但可能要容易得多.
它(应该)如何工作是主要的多用户界面数据交换是通过数据库.DBMS将处理所有有趣和复杂的问题,如多用户,并发e,原子操作等.在后端,VCS将对一组数据对象执行版本控制(无并发或多用户问题).对于数据库上的每个有效事务,只对已经有效更改的数据记录执行版本控制.
对于接口胶,它将以数据库和VCS之间的简单互通功能的形式出现.在设计方面,简单的方法是事件驱动的接口,数据库中的数据更新触发版本控制程序(提示:假设 使用Mysql,使用触发器和sys_exec() 等等等等).在实现方面复杂性,它将从简单有效(例如脚本)到复杂和精彩(一些编程的连接器接口).一切都取决于你想要用它多疯狂,以及你愿意花多少汗水资金.我认为简单的脚本编写应该是神奇的.并且为了访问最终结果,各种数据版本,一个简单的替代方案是使用VCS中版本标记/ id/hash引用的数据填充数据库的克隆(更多是数据库结构的克隆).再次,这个位将是一个简单的查询/翻译/地图作业的接口.
仍然存在一些挑战和未知因素需要处理,但我认为其中大部分的影响和相关性在很大程度上取决于您的应用程序需求和用例.有些人可能最终会成为非问题.一些问题包括2个关键模块,数据库和VCS之间的性能匹配,用于具有高频数据更新活动的应用程序,git端的资源(存储和处理能力)随时间的缩放作为数据,以及用户成长:稳定,指数或最终高原
在上面的鸡尾酒中,这是我正在酝酿的
一些有趣的事实 - git实际上确实可以清楚地优化存储,例如压缩,以及仅修改对象之间的增量存储 - 是的,git只存储数据对象修订版之间的更改集或增量,它在哪里适用(它知道何时以及如何).参考:packfiles,深入Git内部的内部 - 回顾git的对象存储(内容可寻址的文件系统),显示与noSQL数据库如mongoDB的相似性(从概念角度来看).同样,以牺牲汗水资本为代价,它可能为整合2和性能调整提供更有趣的可能性
如果你到目前为止,如果以上内容可能适用于你的情况,并且假设它会是,那么它将如何与你上一次综合性能分析中的某些方面相提并论
| 归档时间: |
|
| 查看次数: |
18023 次 |
| 最近记录: |