2013-02-12 50 views
0

背景Cachekey代从对象状态

我期待纯粹的存储是否查询已执行。如果存在,查询应该针对数据缓存(内部数据库,进程外)运行,如果没有,它应该针对原始数据源(第三方外部web服务)运行。这种缓存的动机是,我们被允许对这个API进行调用的次数是有限的,我们很可能会多次执行相同的查询。

在对原始数据源运行一次查询后,它只会在随后的调用中针对缓存的数据源运行。注意:为了简单起见,我故意忽略了缓存过期的问题。

假设每个查询可能包含许多参数(目前只有5),我不希望被查询的东西,如缓存的数据源“的参数会随着时间增加数,其中x和y和z a AND b AND c AND d AND ...“

为此,我想知道这个确切的查询是否已经运行过,如果它已经存在,我会假设它的数据已经在缓存的数据存储中可用(尽管格式不同)。我认为某种形式的“cachekey”可以识别具有相同参数和相关值的任何查询。每次我尝试查询时,我都会根据查询对象的状态生成缓存键,并检查缓存键存储以确定查询是否曾经运行过。 cachekey存储需要快速查找。

问题

我发现棘手摸出这是什么cachekey应该是什么样子,以及如何生成它。到目前为止,我倾向于

  1. 串连有趣查询参数和其价值的一个字节数组
  2. 从字节数组中的二进制(16)索引的列创建一个MD5
  3. 店这cachekey

为了论证的缘故,我愿意接受一些碰撞,可能会导致缓存报告缓存数据可用于查询,当它没有被给出时,可能性很小(一个虽然我不是100%确定的小)。

以上创建缓存键的解决方案看起来是否合理,还有其他方法我应该考虑吗?

回答

1

您的潜在解决方案正是我过去所做的,并且运作良好。我实际上将方法/调用名称连接起来,然后将所有参数值连接成一个字符串,然后在其上运行MD5并获得缓存键。

我不明白怎么会有碰撞。如果更改参数值,缓存键将会不同,这可能会带回不同的数据。

(所有这一切说,我不知道你所说的“有趣”参数的意思。)

+0

MD5碰撞有问题,但他们(取决于输入)罕见。从我读过的内容来看,如果输入是结构化的,那么碰撞发生的几率就会更高。 http://www.mathstat.dal.ca/~selinger/md5collision/ http://www.links.org/?p=6 – 2013-02-14 10:56:20

+0

还有其他的散列算法,我会想象会更好地工作。你总是可以在每个函数中命名一个参数来疯狂地散布哈希。哈哈。 =) – ryan1234 2013-02-14 19:52:50