Dogpile效应以及solution

Redis/Memcached高并发访问下的缓存失效时可能产生Dogpile效应(Cache Stampede效应)。看代码:

# redis read-through cache
conn = redis.Redis()
data = conn.get('cachekey')
if not data:
    # long-running process
    data = generateData()
    conn.setex('cachekey', data, 10)


Dogpile 产生情况:

generateData()是耗时的运算过程或者复杂的数据库操作。当缓存失效或者redis-server不可用(服务器宕机/网络原因),此时恰好有大量的请求涌入,会直接穿透cache层从而导致CPU使用率或者数据库操作数短时间急剧攀升,可能会引发数据库/web服务器故障。

Solution:

1.      使用独立的进程\线程更新cache

实践:web应用中启动调度线程;单独进程Job(spring-boot)

// every ten seconds
@Scheduled(cron = "*/10 * * * * *")

现在我们的应用就是基于这样的方案,可靠,经历618考验^_^。

2.      使用”锁”

实践:cache失效,单一请求,其余等待;单一请求cache失效前更新

# redis read-through cache
conn = redis.Redis()

def get(key):
    data = conn.get(key)
    if data:
        return data
    # try lock
    if conn.setnx('lock:' + key, 'locked'):
        # long-running process
        data = generateData()
        conn.setex(key, data, 10)
        conn.delete('lock:' + key)
        return data
    else:
        # 'waiting & try get'
        loop = 10
        while loop > 0:
            time.sleep(0.1)
            data = conn.get(key)
            if data:
                print 'found'
                return data
            loop -= 1
        return None
或者是

# redis read-through cache
conn = redis.Redis()

def get(key):
    recache = 2
    data = conn.get(key)
    ttl = conn.ttl(key)

    if ttl < recache and conn.setnx('lock:' + key, 'locked'):
        print 'recache'
        # long-running process
        data = generateData()
        conn.setex(key, data, 10)
        conn.delete('lock:' + key)
    # normal return
    return data

这两者各有优势,看具体业务选取。我们应用涉及到实时或者重定向的功能采用的是第一种锁。

另外:按照具体的使用确定是否要对锁的冲突和异常进行特殊处理,代码中没有实现。

参考(力荐):http://www.linuxidc.com/Linux/2013-07/86960.htm (关于这次项目的实践,上线后才看到这篇文章,相见恨晚。本文只做实践,详解看这篇推荐。)

618值班顺利




  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值