我们使用Yii框架和Memcached进行缓存。
我们有以下问题:
如果我们在设置memcache键之前再次请求相同的查询q(步骤4之前),那么由于没有设置memcache键,所以我们再次查询db。
我们希望将此行为更改为:
下面是所发生的事情和我们想要的东西的伪代码:
get(q):
if q not in memcache:
value = query_db(q)
memcache[q] = value
return memcache[q]
else:
return memcache[q]
getNew(q):
if q not in memcache:
memcache[q] = null
value = query_db(q)
memcache[q] = value
return memcache[q]
elif q in memcache and memcache[q] != null:
return memcache[q]
else:
while True:
if memcached[q] != null:
return memcached[q]
else:
sleep(3)换句话说,我们希望在将结果设置为null之前将memcache键设置为空,而对相同查询的其他请求则检查该值是否为null,并等到值为null (这意味着查询已经在处理)。
你知道易伊框架的哪一部分应该修改吗?
发布于 2013-03-21 15:20:54
Mysql有这些系统范围的锁定功能,可以帮助:get_lock和release_lock --这些函数都是锁名字符串。
这样做的目的是进行常规的memcache检查,然后检查这个确切的查询本身是否已经使用锁名进行处理。为此,每个查询都需要一个唯一的锁名。可以使用crc32($sql)的十六进制(php中最快的非加密散列)来创建锁名,这将为每个查询生成一个4字符唯一的十六进制字符串。
TIMEOUT可能是一个很大的数字
getNew(q):
if q not in memcache:
hash = crc32hex(q)
if mysql-is_free(hash) == 0 # means query is processing
# now attach youself to the other thread's synchronous exit
if(mysql-get_lock(hash,TIMEOUT)==1) #waiting...
release_lock(hash)
# call self since by now, memcache has your value
return getNew(q)
endif
endif
if(mysql-get_lock(hash,TIMEOUT)==1)
value = query_db(q)
memcache[q] = value
mysql-release_lock(hash)
endif
return memcache[q]
else:
return memcache[q]https://stackoverflow.com/questions/15546668
复制相似问题