Performance 以良好的性能服务数百万条路线

Performance 以良好的性能服务数百万条路线,performance,routes,bigdata,Performance,Routes,Bigdata,我正在为一个新项目做一些研究,这个项目的约束条件和规格还没有确定。需要的一件事是在根域的正下方有大量的路径。这可能会增加到数百万条路径。路径没有共同的结构或唯一的部分,因此我必须寻找精确的匹配 现在我知道分解这些路径更有效,这也有助于路径查找。不过,我正在研究这种可能性,所以请容忍我 我正在评估实现这一目标的方法,同时保持优异的性能。我想到了以下方法: 将路径存储在SQL数据库中,并对每个请求进行查找。这似乎是最糟糕的选择,绝对不会被使用 将路径存储在像Redis这样的键值存储中。这会好得多,

我正在为一个新项目做一些研究,这个项目的约束条件和规格还没有确定。需要的一件事是在根域的正下方有大量的路径。这可能会增加到数百万条路径。路径没有共同的结构或唯一的部分,因此我必须寻找精确的匹配

现在我知道分解这些路径更有效,这也有助于路径查找。不过,我正在研究这种可能性,所以请容忍我

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

  • 将路径存储在SQL数据库中,并对每个请求进行查找。这似乎是最糟糕的选择,绝对不会被使用
  • 将路径存储在像Redis这样的键值存储中。这会好得多,而且我认为表现相当好(不过必须对其进行基准测试)
  • 与许多框架一样,对字符串/正则表达式进行匹配(即开箱即用),以获得如此多的可能匹配是不可能的,因此不是一个真正的选项。但我可以看到,在进行某种算法时,你可以逐个字母进行比较,并结合一些智能优化,这是如何工作的
但也许有一些我不知道的工具/方法更适合这种类型的问题。不过,我可以利用任何技巧来实现这一点

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


更新

我已经测试了Redis方法。基于两组关键字,我得到了1.5亿条路径。我使用
set
命令添加了它们中的每一个,该值是一个id的序列化字符串,我可以使用它来标识请求中的实际关键字。(
设置“关键字1-关键字2”

在本地VM中使用一百万条记录的数据集进行快速测试,结果令人鼓舞:对1000个请求进行基准测试平均需要2毫秒。这是在我的笔记本电脑上,里面有很多其他的东西

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


显然,这将不起作用,也无法很好地扩展。要么每个web服务器都需要大量的RAM,要么我们必须使用专用的Redis路由服务器。我读过Instagram的工程师们的文章,他们想出了一个大大减小数据库大小的窍门,但我还没有尝试过。不管怎样,这似乎都不是正确的方法。回到绘图板。

我建议使用某种键值存储(即散列存储),可能同时对键值进行散列,使其更短(像SHA-1这样的东西就可以了)。

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

我将执行以下步骤来测试Redis:

  • 使用本地VM或在云上(如EC2)启动Redis实例
  • 下载一两本字典并将这些数据输入Redis。例如,这里的内容:确保数据正常化。例如,始终将字符串小写,并删除字符串开始/结束处的空白,等等
  • 我会忽略散列。我不明白你为什么需要对URL进行哈希?如果你想调试一些东西,而它似乎并没有给你“买”任何东西,那么以后就不可能阅读了。我去了,输入了
    ryan
    ,得到了
    ea3cd978650417470535f3a4725b6b5042a6ab59
    作为散列。原始文本要小得多才能放入RAM中,这将有助于Redis。显然,对于较长的路径,哈希会更好,但您的示例非常小
  • 编写一个从Redis读取的工具,看看它的性能如何
  • 利润 请记住,Redis需要将整个数据集保存在RAM中,因此需要进行相应的计划

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

    您可能低估了数据库的功能。我能请你重新考虑一下你在那里的立场吗

    对于Postgres(或带InnoDB的MySQL),一百万条条目比微小的条目高出一个档次。将整个路径存储在一个字段中,在其上添加索引,抽真空,分析。在确定关键对象的ID之前,不要进行nutty联接,这样在查找速度方面就可以了。从psql运行查询时,请说几毫秒

    如果您获得大量流量,您真正的问题将是与磁盘IO相关的瓶颈。这里的经营格言是:越少越好。除了在php服务器上安装APC、使用Ruby时使用Passenger等基础知识外:

  • 确保服务器有足够的RAM来适应该索引

  • 缓存与memcached中每个路径相关的对象的引用

  • 如果您可以在十几个左右的正则表达式中对所有路由进行分类,它们可能会有帮助,因为它们允许使用更小、更有针对性的索引,这些索引更容易保存在内存中。如果没有,只需继续存储(可能是尾部斜线)整个路径,然后继续

  • 担心失误。如果您有一个重定向到规范URL的非规范URL,请将重定向存储在memcached中,不带任何过期日期,然后开始使用它

  • 我提到过很多RAM和memcached吗

  • 哦,也不要高估你使用的ORM。很可能构建查询所花费的时间比数据存储解析、检索和返回结果所花费的时间要多

  • 公羊。。。内存缓存

  • 老实说,Reddis与SQL+memcached选项没有太大区别,除非它