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

我们必须存储大约300万种产品的基本信息。 目前的信息是一个180 MB CSV每季度更新。

每天将会有大约30,000个查询,但查询只是一个非常简单的关键值存储。 我们只需要查看产品ID并显示其余的信息(这些信息都在一个logging中)。

这是为了networking,快速的performance是至关重要的。

我们是否应该使用MySQL,即使我们真的不需要关系数据库? 我们是否应该每个季度生成3百万个静态HTML文件? 我们是否应该在Amazon S3或Rackspace Cloud Files等产品上存储每行产品的单行CSV? 什么是最好的方法来做到这一点?

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

一旦你开始把你的数据放到数据库中,无论是MySQL还是别的,你很可能会发现你会发现更多的用途。 现在你只是在讨论关键值对,但其余的与你的产品相关的数据必须存储在某个地方。 如果这不是在数据库中,我不能想象数据存储是非常有效的。

不pipe你做什么, 都不要创build这三百万个文件。 我们已经看到了许多问题已经由这么多文件创build的问题导致。

您可以使用专门为此类任务而优化的 Key-Valuetypes的NoSQL数据库。 看一下:

  • Redis – Redis是一个开源的高级键值存储。 它通常被称为数据结构服务器,因为密钥可以包含string,散列,列表,集合和有序集合。
  • MemcacheDB – MemcacheDB是为持久性devise的分布式键值存储系统。
  • 其他(这样的列表之一可以在这里find: http : //nosql-database.org/ )

当然,你可以使用MySQL或其他关系数据库,但专门为键值types的数据devise的解决scheme应该是更好的(否则首先devise它们的要点是什么,除了它可能会小得多(根据RAM和HDD)解决scheme)。

现在完全不同了:

鉴于:

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

解决scheme之外:

将每个产品转储为TXT资源logging并将其存储在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" 

优点:

  • 非常可靠和值得信赖(你每天都依靠它)
  • 可以build立在几乎任何平台上
  • 几乎每种语言都支持DNS查询
  • 开源和商业服务器支持不同types的后端数据库
  • 可以简单地复制(只需指定多个名称服务器)
  • 处理primefaces更新,即使在十几台服务器上复制时也是如此
  • 可以进行encryption签名以确保数据的完整性
  • 可以处理更高的每秒查询速度(每秒10,000个查询很容易用商品硬件处理)

原因可能是一个坏主意:

  • 你需要search数据(DNS是纯粹的键/值查找)
  • 你需要隐藏数据(DNS没有保密性)

MySQL与MyISAM和一些好的索引听起来很完美。 当然还有很多其他的select,但是MySQL在任何商业的Web主机上都非常普遍(如果不是普遍的话)。 取决于你需要的速度, memcached也可能值得一看 ,但不知道每个键/值对的大小,将其中的300万存储在内存中可能比180Mb的CSV文件更糟糕的想法(哦,等等,这是一个180Mb的CSV文件,所以我们知道它们有多大,它们必须非常小,所以memcached可能会更好)。

想要300万个静态的HTML文件,这会严重的伤害你的文件系统。 即使在S3上,单行CSV也会遇到同样的问题。 没有人想要一个文件夹中的300万个文件。

你可以使用Berkeley数据库来完成这种事情,即使它从Perl5开始就没有被使用。 伯克利只支持键值对,而且你把整个数据库绑定到一个散列并且像这样访问它。

使用Berkeley在很多老的Perl参考资料中都有详细的介绍,或者试用BerkeleyDB CPAN模块的Perldoc 。 我通常会避免使用Berkeley DB(虽然我的雇主有很多古代代码,其中一些数据库和你的数据库一样大),因为当你的数据变得越来越复杂的时候,这并不好玩。

你已经把你的问题标记为亚马逊S3。

我想提请您注意他们的其他相关产品之一,称为亚马逊SimpleDB。
这听起来像SimpleDB数据模型将适合您的应用程序的types。

这不是一个插件,但值得一看,尤其是如果你打算使用亚马逊云服务。

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

看到这里的更多信息: http : //aws.amazon.com/simpledb/和数据模型: http : //docs.amazonwebservices.com/AmazonSimpleDB/latest/DeveloperGuide/

尽pipe任何关系数据库都可以轻松处理180mb的数据,但我强烈推荐在MySQL,Redis,MemcacheDB和其他更简单的键值存储或关系数据库之上的MongoDB( http://www.mongodb.org/ )。 原因在于,对于这样的问题,MongoDB是最快,最具performance力的系统,允许超高速的dynamic更新,没有模式限制,所以如果你喜欢,你的文档可以有不同的格式。 我前几天在guardian.co.uk做了一个演讲,他们做出了一个政策决定,禁止所有的关系数据库,并且使用MongoDB来为他们服务。 你可以感受到自己的网站有多快,自1995年以来(网上最古老的在线报纸)上网。 由于关系数据库的存在,它们也经历了各种各样的瓶颈。 对于180MB,MongoDB将从内存中提供一切服务,因此sub-ms加载时间可能会是这种情况。

每天将会有大约30,000个查询,但查询只是一个非常简单的关键值存储。 我们只需要查看产品ID并显示其余的信息(这些信息都在一个logging中)。

你说你的查询只是简单的密钥查找,在二进制search你需要21迭代最糟糕的情况下,用散列键你的查询甚至更快。 只要避免连接(或其他笛卡尔产品types的操作)和线性search,就可以有三百万条logging。

我敢说几乎任何事情都会好起来的。 你的负载是每天30000个查询意味着(假设你的负载是一整天不变的),你每20秒就有一个查询; 这不是太糟糕。

我build议先在您最熟悉的技术中实施,然后衡量这是否真的是系统的瓶颈。

要做到这一点,最好的方法确实取决于数据和查询的质量和性质。 对于初学者来说,对于产品而言,单个表中的180MB数据不会成为问题,无论以何种方式查看。 而每天30k的查询更不是一个问题。 使用正确configuration的数据库,任何旧的桌面都可以处理这个负载。

其他人已经指出了你的两个主要选项,MySQL或一个noSQL数据库。

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

如果属性和数据types的属性差别很大,那么最好使用一个noSQL数据库,它比传统的SQL数据库更有效。

关于业绩:我以前曾经在一家电子商务公司工作过,很长一段时间以来,这个网站都提供了来自MySQL服务器的数据。 这台服务器有2GB的内存,总共数据库大概是。 5GB的大小和最高负载下,服务器每秒处理数千个查询。 是的,我们做了很多的查询优化,但这绝对是可行的。