如何以键值格式存储300万条记录?


10

我们必须存储有关300万种产品的基本信息。目前的信息是一个180 mb CSV,每季度更新一次。

每天大约有30,000个查询,但是查询只是一个非常简单的键值存储。我们只需要查找产品ID并显示其余信息(全部信息都记录在一条记录中)。

这是针对Web的,因此快速的性能至关重要。

即使我们确实不需要关系数据库,也应该使用MySQL吗?我们是否应该每季度生成300万个静态html文件?我们是否应该为每个产品在Amazon S3或Rackspace Cloud Files之类的文件中存储一行CSV?做这个的最好方式是什么?

Answers:


16

因为MySQL得到了如此广泛的支持,这确实是一件微不足道的事情,所以我建议使用它。除非服务器至少有几个GB的内存,否则我建议坚持使用MySQL,而不要使用内存系统。

一旦开始将数据放入数据库(无论是MySQL还是其他数据库),您很可能会发现有更多用途。现在,您只在谈论键值对,但是与产品相关的其余数据必须存储在某个位置。如果那不在数据库中,我将无法想象数据存储会非常高效。

无论您做什么,都不要创建这300万个文件。我们已经看到许多文件所产生的问题已经引起了许多问题。


13

您可以使用NoSQL数据库的专用键值类型,该类型针对此类任务进行了优化。看一下:

  • Redis -Redis是开源的高级键值存储。它通常被称为数据结构服务器,因为键可以包含字符串,哈希,列表,集合和排序集合。
  • MemcacheDB -MemcacheDB是为持久性而设计的分布式键值存储系统。
  • 其他(可以在此处找到这样的列表之一:http : //nosql-database.org/

当然,您可以使用MySQL或任何其他关系数据库,但是专门为键值类型的数据设计的解决方案应该更好(否则,首先设计它们的目的是什么,但可能会小得多) (就RAM和HDD而言)解决方案)。


我们可以使用Redis,但是您认为这可以在具有2 GB RAM的P4上使用吗?
菲尔(Phil)

@Phil考虑到您的CSV文件约为180MB,应该没问题。尽管我们在一个大约有200K记录的项目中使用了它(到目前为止只有一次),并且服务器具有8GB RAM,所以我很难比较。
LazyOne 2011年

6

现在换个完全不同的东西:

鉴于:

  • 180MB / 3M产品=平均62字节/产品。
  • 每天30,000个查询=每秒0.34个查询
  • 每季度更新一次=本质上是静态数据

开箱即用的解决方案:

将每个产品作为TXT资源记录转储并将其存储在DNS中,例如:

$origin products.example.com.

product_1_name IN TXT "product 1 description"
product_2_name IN TXT "product 2 description"
...
product_3000000_name IN TXT "product 3000000 description"

好处:

  • 非常可靠和值得信赖(您已经每天都依赖它)
  • 可以在几乎任何平台上构建
  • 几乎每种语言都以一种或另一种形式支持DNS查询
  • 开源和商业服务器支持不同种类的后端数据库
  • 可以轻松复制(只需指定多个名称服务器)
  • 处理原子更新,即使在十几个服务器上复制
  • 可以进行加密签名以确保数据完整性
  • 每秒能处理率更高数量级的查询命令(每10000个查询第二很容易与商品硬件处理)

为什么这可能不是一个好主意的原因:

  • 您需要搜索数据(DNS纯粹是键/值查找)
  • 您需要隐藏数据(DNS没有机密性)

1
如果我能为独创性提供加分,那将赢得我的投票。我不会说DNS绝对可靠,因为在典型的家庭网络中,DNS可以正常运作,而诅咒则不可行。
马丁·维尔坎斯

1
我很感兴趣 我实际上真的很喜欢这个主意,但是对我来说,我会尝试一些更经过尝试/测试的东西,例如CouchDB
Tom O'Connor

在看一些Monty Python吗?
马克·亨德森

大概这将在企业网络内。当数据包不得不冒着Internet的危险时,DNS可靠性就成为一个问题。由于默认情况下,DNS使用UDP,因此,如果数据包丢失,则必须依靠DNS解析器的重传策略。在企业网络中,您丢失足够多的数据包的机会(可能)可以忽略不计。而且,您始终可以强制DNS使用TCP(尽管会影响性能,但在这种情况下认为不重要)。而且,我保证,与所有CouchDB安装的总和相比,DNS的查找次数更多:-)。
Theobroma Cacao

Hindsight队长在这里。一句话:区块链。
datashaman

4

带有MyISAM和一些良好索引的MySQL听起来很完美。当然,还有许多其他选择,但是在任何商用Web主机上,MySQL都得到了广泛的支持(如果不是通用的话)。根据您所需的速度,memcached也许也值得一看,但是在不知道每个键/值对的大小的情况下,将300万个键/值对存储在内存中可能比180Mb CSV文件还要糟糕(哦,一个180Mb的CSV文件,因此我们确实知道它们的大小。它们必须是非常小的对,因此memcached可能会更好)。

希望有300万个静态HTML文件,这将严重损害文件系统。即使在S3上,单行CSV也会有相同的问题。没有人想要一个文件夹中的300万个文件。


它们是非常小的对……这是非常基本的数据,例如价格,生产日期,仓库编号等。少于10列。因此,您认为MySQL是必经之路,真的吗?将要运行的服务器是带有2 GB RAM的P4-我认为应该没问题吗?
菲尔(Phil)

@Phil-- So you think MySQL is the way to go, really?不,不是真的,但是它非常灵活,正如我提到的那样,几乎得到了所有人的支持。但是,LazyOne在上面发布了一些不错的选择。我不记得术语NoSQL的,但它是漂浮在我的大脑某处
马克·亨德森

4

您可以使用伯克利数据库来完成这种事情,即使自Perl5诞生以来就没有那么时髦。Berkeley仅支持键值对,并且您将整个数据库绑定到哈希并按此访问它。

坐在您的书架上的许多较旧的Perl参考资料中都对使用Berkeley进行了详细介绍,或尝试使用BerlleyDB CPAN模块的Perldoc。我通常避免使用Berkeley DB(尽管我的雇主有很多古老的代码在其中扮演着重要角色,并且某些DB与您的DB一样大),因为当数据变得更加复杂时,这并不有趣。


2
BDB很老套,但是非常有效并且适合这种情况。
womble

当心Berkely DB的许可证en.wikipedia.org/wiki/Sleepycat_license,它要求所有源代码都可用,而不仅仅是DB部分。
WolfmanJM 2011年

4

您已将问题标记为亚马逊S3。

我想提请您注意他们的其他相关产品之一,即Amazon SimpleDB。
听起来SimpleDB数据模型很适合您的应用程序类型。

这不是插件,但值得一看,尤其是当您计划使用Amazon云服务时。

SDB数据模型类似于电子表格。

请参阅此处以获取更多信息:http : //aws.amazon.com/simpledb/数据模型:http : //docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/


SimpleDB非常昂贵。痛苦的是,在许多情况下。
汤姆·奥康纳

1

即使任何关系数据库都可以轻松处理180mb的数据,但我还是强烈建议MongoDB(http://www.mongodb.org/)位于MySQL,Redis,MemcacheDB和其他更简单的键值存储或关系数据库之上。原因是对于此类问题,MongoDB是使用最快,最具表现力的系统,它允许无模式限制的超快速动态更新,因此您可以根据需要使用不同的格式。几天前,我在Guardian.co.uk的一次演讲中,他们已经做出一项政策决定,禁止所有关系数据库,并独家使用MongoDB来提供新闻。您可以了解他们的网站有多快以及自1995年以来一直在线(英国最古老的在线报纸)。由于关系数据库,它们在过去也经历了各种瓶颈。对于180mb,MongoDB将从内存中提供所有服务,因此sub-ms加载时间可能是这种情况。


0

每天大约有30,000个查询,但是查询只是一个非常简单的键值存储。我们只需要查找产品ID并显示其余信息(全部信息都记录在一条记录中)。

您说过,查询只是简单的键查询,对于二进制搜索,在最坏的情况下需要进行21次迭代,而使用散列键,则查询会更快。只要避免连接(或其他笛卡尔积类型操作)和线性搜索,三百万条记录就很小

我敢说几乎任何事情都可以。您的负载为每天30000个查询,这意味着(假设您的负载在一天内是恒定的),您每20秒就有一个查询;还算不错

我建议先使用您最熟悉的技术来实现,然后再衡量这是否真的是系统的瓶颈。


0

最佳方法实际上取决于数据和查询的质量和性质。对于初学者来说,无论您使用哪种方式查看产品,都可以在单个表中找到180MB的数据。每天3万次查询甚至不再是问题。使用正确配置的数据库,任何旧桌面都可以处理此负载。

其他人已经指出了您的两个主要选择,即MySQL或noSQL数据库。

如果每个产品都有一定数量的属性(例如制造商,价格,仓库编号等),那么最好的选择是为这些属性创建列,然后将键/值对转换为平面表格式,使用产品ID作为该表的主键,即使某些列仅被一半的行使用,这也将非常有效,因为对于大多数产品,您只需运行1个查询即可检索其所有属性。这是有关产品的数据,我想这很可能就是您的数据结构。

如果属性在状态和数据类型方面差异很大,则最好使用noSQL数据库,该数据库比传统的SQL数据库更有效地处理这种情况。

关于性能:我以前曾在一家电子商务公司工作过,很长一段时间以来,该公司一直向该网站提供来自MySQL服务器的数据。该服务器具有2GB的RAM,数据库总计约为2GB。5GB的大小和最高负载下,服务器每秒处理数千个查询。是的,我们已经做了很多查询优化,但这绝对是可行的。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.