首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >你的记忆

问你的记忆
EN

Stack Overflow用户
提问于 2013-03-21 11:47:59
回答 1查看 1.7K关注 0票数 0

我们使用Yii框架和Memcached进行缓存。

我们有以下问题:

  1. 我们创建一个db查询q。
  2. 如果q已经被缓存,我们将从memcache获取数据。
  3. 否则,yii会查询Mysql。
  4. 设置缓存值
  5. 我们从memcache中得到结果

如果我们在设置memcache键之前再次请求相同的查询q(步骤4之前),那么由于没有设置memcache键,所以我们再次查询db。

我们希望将此行为更改为:

  1. 我们创建一个db查询q。
  2. 如果在memcache中存在q的键,且值不是空的,则返回值
  3. 否则,如果设置了密钥,而值为空,则为=>空。
  4. 设置缓存值
  5. 我们从memcache中得到结果

下面是所发生的事情和我们想要的东西的伪代码:

代码语言:javascript
复制
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 (这意味着查询已经在处理)。

你知道易伊框架的哪一部分应该修改吗?

EN

回答 1

Stack Overflow用户

发布于 2013-03-21 15:20:54

Mysql有这些系统范围的锁定功能,可以帮助:get_lock和release_lock --这些函数都是锁名字符串。

这样做的目的是进行常规的memcache检查,然后检查这个确切的查询本身是否已经使用锁名进行处理。为此,每个查询都需要一个唯一的锁名。可以使用crc32($sql)的十六进制(php中最快的非加密散列)来创建锁名,这将为每个查询生成一个4字符唯一的十六进制字符串。

TIMEOUT可能是一个很大的数字

代码语言:javascript
复制
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]
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/15546668

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档