服务于数百万条具有良好表现的路线

时间:2013-04-16 15:44:05

标签: performance routes bigdata

我正在为一个新项目做一些研究,其中尚未设定约束和规范。需要做的一件事是直接在根域下的大量路径。这可能会增加到数百万条路径。路径没有共同的结构或独特的部分,所以我必须寻找完全匹配。

现在我知道分解这些路径会更有效,这也有助于路径查找。但是我在这里研究这种可能性,所以请耐心等待。

我正在评估实现这一目标的方法,同时保持卓越的性能。我想到了以下方法:

  • 将路径存储在SQL数据库中并对每个请求执行查找。这似乎是最糟糕的选择,绝对不会被使用。
  • 将路径存储在像Redis这样的键值存储中。这会好很多,并且我认为表现相当不错(但必须对它进行基准测试)。
  • 执行字符串/正则表达式匹配 - 就像许多框架一样开箱即用 - 因为这些可能的匹配数量很多,因此不是一个选项。但我可以看到,如果你在某些算法中进行逐字比较,结合一些智能优化,就可以了。

但也许有一些我不知道的工具/方法更适合这类问题。我可以使用任何有关如何实现此目的的提示。

哦,如果有人想知道,不是这不是作业。


更新

我测试了Redis方法。根据两组关键字,我获得了1.5亿条路径。我使用set命令添加了每个命令,其中值是一个id的序列化字符串,我可以使用它来标识请求中的实际关键字。 (SET 'keyword1-keyword2' '<serialized_string>'

在具有一百万条记录的数据集的本地虚拟机中进行的快速测试返回了有希望的结果:对1000个请求进行基准测试平均需要2毫秒。这是在我的笔记本电脑上,它运行了大量的其他东西。

接下来,我对具有4核和8GB RAM的VPS进行了全面测试,完整的1.5亿条记录。这产生了一个3.1G文件大小的数据库,内存大约9GB。由于数据库无法完全加载到内存中,因此Redis开始交换,导致可怕的结果:平均约100毫秒。

显然这不会起作用并且规模很好。每个Web服务器都需要有大量的RAM,否则我们将不得不使用专用的Redis路由服务器。我从Instagram上的工程师那里读到了an article,他们提出了一个大大减少数据库大小的技巧,但我还没有尝试过。无论哪种方式,这似乎都不是正确的方法。回到绘图板。

3 个答案:

答案 0 :(得分:1)

我认为Redis是你最好的选择。 SQL会很慢,而且我的经验中的正则表达式在查询中总是很慢。

我会按照以下步骤测试Redis:

  1. 使用本地VM启动Redis实例,或者在EC2之类的云中启动Redis实例。
  2. 下载一两个字典并将此数据输入Redis。例如,来自此处的内容:http://wordlist.sourceforge.net/确保规范化数据。例如,始终小写字符串并删除字符串开头/结尾处的空格等
  3. 我会忽略哈希。我没有看到你需要散列URL的原因?如果你想调试一些东西并且它似乎并没有“购买”任何东西,那么以后就不可能阅读。我转到http://www.sha1-online.com/,输入ryan并获得ea3cd978650417470535f3a4725b6b5042a6ab59作为哈希值。放入RAM的原始文本要小得多,这将有助于Redis。显然对于更长的路径,哈希会更好,但你的例子非常小。 =)
  4. 编写一个工具,从Redis中读取并查看其执行情况。
  5. 利润!
  6. 请记住,Redis需要将整个数据集保存在RAM中,因此请进行相应的规划。

答案 1 :(得分:1)

  

将路径存储在SQL数据库中并对每个请求执行查找。这似乎是最糟糕的选择,绝对不会被使用。

您可能低估了数据库的功能。我可以邀请你重新考虑你在那里的位置吗?

对于Postgres(或带有InnoDB的MySQL),一百万个条目是微不足道的。将整个路径存储在一个字段中,在其上添加索引,真空,分析。在确定关键对象的ID之前不要进行坚果连接,并且在查找速度方面你会没问题。从psql运行查询时说几毫秒。

如果您获得大量流量,那么您的真正问题将是与磁盘IO相关的瓶颈。这里的经营座右铭是:越少越好。除了基本知识,比如在你的php服务器上安装APC,如果你使用Ruby等,使用Passenger:

  1. 确保服务器有足够的RAM来容纳该索引。

  2. 在memcached中缓存对与每个路径相关的对象的引用。

  3. 如果您可以对十几个正则表达式中的所有路由进行分类,则可以通过允许使用更容易保留在内存中的更小,更有针对性的索引来帮助它们。如果没有,只需坚持存储(可能是尾随斜线)整个路径并继续前进。

  4. 担心失误。如果您有一个重定向到规范网址的非规范网址,请将重定向存储在memcached中,而不会有任何过期日期,并将其重新定位。

  5. 我提到了很多RAM和memcached吗?

  6. 哦,也不要高估你正在使用的ORM。有可能需要花费更多时间来构建查询,而不是数据存储用于解析,检索和返回结果。

  7. RAM ... Memcached ...

  8. 说实话,Reddis与SQL + memcached选项没有什么不同,除了内存管理(如你所知),分片,复制和语法。当然还有熟悉感。

    您的关键决策点(除了不包括迭代多个正则表达式)应该是您的数据结构的方式。如果它是高度结构化的,具有对原子性的关键需求,那么SQL + memcached应​​该是您的首选。如果你有自定义字段和肥胖的EAV表,那么玩Reddis或CouchDB或其他NoSQL商店应该在你的雷达上。

    在任何一种情况下,将批量 RAM用于将这些索引保留在内存中是有帮助的,如果需要扩展,整个事物前面的memcached集群将永远不会受到影响。 / p>

答案 2 :(得分:0)

我建议使用某种键值存储(即哈希存储),可能还需要对键进行哈希处理,以便它更短(类似SHA-1就好了恕我直言)。

相关问题