极端分片:每个用户一个SQLite数据库

时间:2020-03-06 14:40:48  来源:igfitidea点击:

我正在开发一个介于电子邮件服务和社交网络之间的Web应用程序。我觉得它将来有很大的发展潜力,所以我担心可扩展性。

我决定不使用一个集中的MySQL / InnoDB数据库,然后在该时间进行分区,而是决定为每个活动用户创建一个单独的SQLite数据库:每个"碎片"一个活动用户。

这样,备份数据库就像每天将每个用户的小型数据库文件复制到远程位置一样容易。

扩展就像添加额外的硬盘来存储新文件一样容易。

当应用程序超出单个服务器的范围时,我可以使用GlusterFS在文件系统级别将服务器链接在一起,并在不更改应用程序的情况下运行该应用程序,或者建立一个简单的SQLite代理系统,该系统将允许每个服务器在相邻服务器中处理sqlite文件。

并发问题将是最小的,因为每个HTTP请求一次只能接触一个或者两个数据库文件(成千上万个),而SQLite无论如何都只能阻止读取。

我敢打赌,这种方法将允许我的应用优雅扩展,并支持许多很酷的独特功能。我打赌错了吗?我有什么想念的吗?

UPDATE我决定采用一个不太极端的解决方案,到目前为止,该解决方案运行良好。确切地说,我正在使用固定数量的256个sqlite数据库。每个用户都通过简单的哈希函数分配并绑定到随机分片。

我的应用程序的大多数功能每个请求只需要访问一个或者两个分片,但是特别需要解决的一个功能是对256个分片中的10到100个不同的分片执行简单查询,具体取决于用户。测试表明,如果所有数据都缓存在RAM中,则大约需要0.02秒或者更短的时间。我想我可以忍受!

UPDATE 2.0我将应用程序移植到MySQL / InnoDB,能够为常规请求获得相同的性能,但是对于一个需要分步处理的请求,innodb的速度要快4-5倍。由于这个原因和其他原因,我放弃了这种体系结构,但是我希望有人能找到它的用处...谢谢。

解决方案

在我看来,这就像一场维修噩梦。当模式在所有这些DB上更改时会发生什么?

失败的地方是如果我们必须执行所谓的"碎片行走",即找出一大堆不同用户中的所有数据。那种特殊的"查询"必须通过编程来完成,依次查询每个SQLite数据库,这很可能是我们网站中最慢的方面。在将数据"分片"到单独的数据库的任何系统中,这都是一个常见问题。

如果所有数据都是用户自包含的,那么这应该很好地进行扩展,使其成为有效设计的关键是要知道如何使用数据以及是否有人会与之交互来自另一个的数据(在上下文中)。

我们可能还需要注意文件系统资源,SQLite很棒,很棒,快速等等,但是当使用"标准数据库"(例如MySQL,PostgreSQL等)时,确实会获得一些缓存和写入方面的好处设计。在我们提出的设计中,我们会错过其中的一些内容。

如果要为每个用户创建一个单独的数据库,听起来好像我们没有建立关系...那么为什么要使用关系数据库呢?

如果数据很容易分片,为什么不只使用标准的数据库引擎,又要扩展到足以使数据库成为瓶颈的原因,则在不同实例中使用不同的用户分片数据库?效果是一样的,但是我们没有使用许多微小的小型数据库。

实际上,我们可能至少有一些不属于任何单个用户的共享数据,并且我们可能经常需要访问多个用户的数据。但是,这将导致任何一个系统出现问题。

一个可能的问题是,为每个用户使用一个数据库将非常低效地使用磁盘空间和RAM,并且随着用户群的增长,使用轻便快速的数据库引擎的好处将完全丧失。

解决此问题的一种可能的方法是创建" minishards",其中可能包含1024个SQLite数据库,每个数据库最多可容纳100个用户。这将比每个用户使用DB的方法更为有效,因为数据打包效率更高。并且比Innodb数据库服务器方法更轻巧,因为我们使用的是Sqlite。

并发性也将很好,但是查询的优雅度将降低(shard_id yuckiness)。你怎么认为?

当然,每个用户只有一个数据库将非常容易地恢复单个用户的数据,但是正如@John所说,架构更改将需要一些工作。

不足以使其变得困难,但不足以使其变得微不足道。

我正在考虑使用与我基本上想使用服务器端SQLLIte数据库作为客户端的备份和同步副本相同的体系结构。我查询所有数据的想法是使用Sphinx进行全文搜索,并从所有数据的平面转储到Scribe中运行Hadoop作业,然后将结果公开为网络服务。这篇文章给了我一些思考的机会,因此我希望人们能继续回应他们的意见。

http://freshmeat.net/projects/sphivedb

SPHiveDB是sqlite数据库的服务器。它使用HTTP上的JSON-RPC公开网络接口以使用SQLite数据库。它支持将多个SQLite数据库合并到一个文件中。它还支持使用多个文件。它是为极端分片模式而设计的-每个用户一个SQLite数据库。