39

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

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

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

扩大规模就像添加额外的硬盘来存储新文件一样简单。

当应用程序超出单个服务器时,我可以使用 GlusterFS 在文件系统级别将服务器链接在一起并保持不变地运行应用程序,或者安装一个简单的 SQLite 代理系统,允许每个服务器操作相邻服务器中的 sqlite 文件。

并发问题将是最小的,因为每个 HTTP 请求一次只会触及一个或两个数据库文件,在数千个中,而且 SQLite 无论如何只会阻塞读取。

我敢打赌,这种方法将使我的应用程序能够优雅地扩展并支持许多很酷和独特的功能。我赌错了吗?我错过了什么吗?

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

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

更新 2.0我将应用程序移植到 MySQL/InnoDB 并且能够获得与常规请求大致相同的性能,但是对于需要分片遍历的请求,innodb 快 4-5 倍。出于这个原因,以及其他原因,我放弃了这个架构,但我希望有人能在某个地方找到它的用途......谢谢。

4

8 回答 8

31

这将失败的地方是,如果您必须执行所谓的“分片行走”——即找出一堆不同用户的所有数据。这种特定类型的“查询”必须以编程方式完成,依次询问每个 SQLite 数据库——并且很可能是您网站中最慢的方面。在任何将数据“分片”到单独数据库中的系统中,这都是一个常见问题。

如果所有数据对用户来说都是独立的,那么这应该可以很好地扩展 - 使其成为有效设计的关键是了解数据可能会被如何使用以及来自一个人的数据是否会交互来自另一个人的数据(在您的上下文中)。

您可能还需要注意文件系统资源——SQLite 非常棒、很棒、速度快等——但是当使用“标准数据库”(即 MySQL、PostgreSQL 等)时,您确实会获得一些缓存和写入优势,因为它们是如何实现的'被设计。在您提出的设计中,您将错过其中的一些。

于 2008-09-24T18:35:01.747 回答
8

对我来说,这听起来像是一场维护噩梦。当所有这些数据库上的架构发生变化时会发生什么?

于 2008-09-24T18:33:55.650 回答
5

http://freshmeat.net/projects/sphivedb

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

于 2009-05-24T12:00:51.677 回答
4

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

这个问题的一个可能的解决方案是创建“迷你分片”,其中可能包含 1024 个 SQLite 数据库,每个数据库最多可容纳100 个用户。这将比每个用户的 DB 方法更有效,因为数据的打包效率更高。而且比 Innodb 数据库服务器方法更轻,因为我们使用的是 Sqlite。

并发性也会很好,但查询会不太优雅(shard_id yuckiness)。你怎么看?

于 2008-09-25T12:15:06.800 回答
3

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

于 2008-09-24T18:37:51.910 回答
2

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

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

于 2008-09-24T18:39:43.763 回答
2

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

于 2008-10-30T04:00:14.817 回答
1

每个用户拥有一个数据库当然可以很容易地恢复单个用户的数据,但正如@John所说,模式更改需要一些工作。

不足以让它变得困难,但足以让它变得不平凡。

于 2008-09-28T17:05:13.947 回答