《缓存,究竟是淘汰,还是修改?》发布后,有小伙伴提到高并发情况下缓存更新可能会出现问题。今天就来简单聊聊这个话题。业务场景:调用第三方服务,比如微信,一般会分配一个token,每个访问接口都需要带上token;该token有有效期,token过期后需要申请重新认证;也可以在token过期之前重新申请,但是此时旧的token会失效。常见的实现方式,如图:把token放到缓存中,每次用token调用接口;如果token过期,需要申请新的token;申请新的token后,需要将新的token更新到缓存中。高并发下可能出现的问题,如图:获取旧的token,访问接口,发现token已经过期;并发请求,获取旧token,访问接口,发现token过期;申请新的token1;同时申请新的token2(此时token1将过期);将token1放入缓存,同时使用token1访问接口(此时token1已经过期),发现token1已经过期,可以递归申请新的token3(此时token2已过期);将token2放入缓存,使用token2访问接口(此时token2已经过期),发现token2已经过期,可以递归申请新的token4(此时token3已过期);...嗯,高并发请求导致相互失效。常见解决方案,如图:线上s1和s2只从缓存中读取token并异步更新token,asy-Master定时更新token避免并发更新使用shadow-master保证token更新的高可用,asy-Master挂了up,asy-Backup之上的潜在缺点:s1/s2/asy-master直接调用同一个缓存实例。如果缓存实例发生变化,可能需要同步变化,造成耦合。潜在优化:asy-Master在s1/s2使用多线程实现,保证高可用;在Redis中,时间戳用于指示令牌的更新时间。更新令牌时,检查令牌的时间戳。如果令牌刚刚更新,则并发请求将不再更新。文字虽短,但希望问题描述清楚,希望大家有所收获。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文
