【发布时间】:2010-12-13 02:28:10
【问题描述】:
我们向客户提供的许多 LOB 应用程序都具有营销/促销性质(抽奖、活动注册等)。大多数应用程序虽然非常简单,但对数据库的要求很高。例如,想象一个“注册”类型的网站作为在超级碗期间播放的商业广告的后盾(是的,我们有几个)。
尽管我们已经非常擅长优化我们的网络应用程序代码,但数据库始终是一个问题,尽管应用程序相对简单。流程通常是这样的:
- 从数据库中读取以检测现有记录
- 如果记录是新的,则写入数据库
在许多情况下,这就是我们的应用程序需要执行的所有数据访问。但是,鉴于这是应用程序的唯一目的,对这个简单的过程进行大幅度优化是非常重要的。
就这个问题而言,我们有一个服务器运行一个raid 5 磁盘阵列来存储数据文件,另一个运行raid 5 阵列来存储日志。此时,操作系统为 Windows 2003 标准 32 位,服务器有 4 GB 内存。一些应用程序使用 SQL 2005 标准,而其他应用程序使用 MySQL 5.1。我非常清楚在这里可以进行某些操作系统和硬件优化,但我希望首先从软件方面解决我的需求。广泛的分析告诉我们,磁盘 IO 通常是主要瓶颈。
说了这么多,并且知道缓存无济于事,因为大多数读取都是唯一的并且返回的数据很少(通常只有一点点指示记录是否存在),我正在考虑跳入内存数据库领域作为真实数据库的写入缓存层。考虑到我们的大部分高流量本质上是零星的,并且不会持续几个小时,这似乎很合适。此外,在大多数情况下,由于服务器崩溃可能会丢失几分钟的数据是可以接受的。
在最简单的形式中,我会修改一个典型的注册应用来执行以下操作:
- 在磁盘 DB 和内存 DB 中查询现有记录
- 如果没有,则将数据写入内存数据库并返回
- 定期将内存 DB 刷新到磁盘 DB
我的问题是:对于这个中间内存数据库,我有哪些选择?我已经尝试过内存中的哈希表、数据表等,但我正在寻找其他选项,甚至是针对完全不同方法的建议。
【问题讨论】:
-
请提供记录的数量和大小的数量级,可能在特定活动之前和之后区分计数(即包括活动期间收集的额外记录计数的粗略概念)
-
在一个由高流量驱动程序(如电视广告或广播广告)支持的典型应用程序中,我们可能会在广告播放后的 15-30 分钟内看到超过 200,000 次注册尝试。其中大部分通常发生在现场之后的 3-5 分钟内,因此存在争用问题。绝对数量不是问题,问题是并发性。对于此类性质的单一短期应用程序,我们有史以来最大的数据库在 2 个月内接近 1000 万条记录,其中大部分流量来自电视广告和电子邮件活动。
-
另一种选择是将 UPSERT 逻辑封装在存储过程中,这样可以节省您的数据库访问(以及相关开销)。
-
+1 在 UPSERT 上(现在在 SQL2003 规范中 MERGE - 这是 SQL Server 所说的),也就是 MySQL 中的 REPLACE。这可能会有所帮助:msdn.microsoft.com/en-us/library/cc879317.aspx
-
添加更多 RAM 以使您的工作集适合 RAM 远不止获得额外的硬盘。现代数据库也足够聪明,可以缓冲写入。对同一块的 1000 次写入可以转换为一次写入,前提是您有足够的 RAM 将所有内容的副本保存在 RAM 中,速度会快几个数量级。
标签: database-design data-modeling