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

我决定为每个活跃用户创建一个单独的SQLite数据库,而不是使用一个集中式MySQL / InnoDB数据库然后对其进行分区:每个“分片”一个活跃用户。

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

向上扩展就像添加额外的硬盘来存储新文件一样简单。

当应用程序增长到单个服务器之外时,我可以使用GlusterFS在文件系统级别将服务器链接在一起并运行应用程序,或者构建一个简单的SQLite代理系统,允许每个服务器操作相邻服务器中的sqlite文件。

并发问题将是最小的,因为每个HTTP请求一次只能触及一个或两个数据库文件,成千上万,而SQLite只会阻止读取。

我认为这种方法可以让我的应用程序优雅地扩展,并支持许多很酷的独特的功能。我打错了吗?我错过了什么吗?

更新我决定采用一种不太极端的解决方案,到目前为止工作正常。我正在使用固定数量的分片 - 准确地说是256个sqlite数据库。通过简单的散列函数将每个用户分配并绑定到随机分片。

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

UPDATE 2.0 我将应用程序移植到MySQL / InnoDB并且能够获得与常规请求相同的性能,但对于需要碎片行走的一个请求,innodb的速度提高了4-5倍。出于这个原因,以及其他原因,我正在放弃这种架构,但我希望某个地方找到它的用途......谢谢。

有帮助吗?

解决方案

这将失败的地方是你必须做什么叫做“碎片行走” - 查找一堆不同用户的所有数据。那种特殊的“查询”必须以编程方式完成,依次询问每个SQLite数据库 - 并且很可能是您网站中最慢的方面。这是数据被“分片”的任何系统中的常见问题。分开的数据库。

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

您可能还需要注意文件系统资源 - SQLite很棒,很棒,很快等等 - 但是当使用“标准数据库”时,您确实可以获得一些缓存和写入优势。 (即MySQL,PostgreSQL等)因为它们的设计方式。在你提出的设计中,你会错过其中一些。

其他提示

听起来像维护噩梦。当架构在所有这些DB上发生变化时会发生什么?

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

此问题的可能解决方案是创建“ minishards ”由1024个SQLite数据库组成,每个 100个用户。这将比每用户数据库方法更有效,因为数据打包效率更高。并且比Innodb数据库服务器方法更轻,因为我们使用的是Sqlite。

并发性也会很好,但查询不那么优雅(shard_id yuckiness)。你觉得怎么样?

http://freshmeat.net/projects/sphivedb

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

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

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

如果您的数据很容易分片,那么为什么不使用标准数据库引擎,如果扩展到足够大以至于数据库成为瓶颈,请在不同实例中使用不同用户对数据库进行分片?效果是一样的,但你没有使用很多小小的数据库。

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

每个用户拥有一个数据库,当然可以很容易地恢复单个用户数据,但是正如 @John 说,架构变化需要一些工作。

不足以使其变得困难,但足以使其变得非常重要。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top