如何缓存热门查询,以避免stamedes和空白结果
在我们网站的可定制首页上,我们为用户提供显示最近更新内容的模块的选项,从100多个模块中进行选择。
所有数据都由MySQL查询生成,其结果通过memcached进行缓存。 我们当前的系统是这样工作的:当用户加载一个包含模块,模块的页面时,它们立即从缓存中提供数据,并且查询被添加到一个队列中,由一个独立的gearman进程更新(这样页面加载不要等待mysql查询)。 然后,该查询每15分钟运行一次以刷新缓存中的数据。 查询队列本身会定期清除,以便我们不会不断刷新最近未请求的数据。
问题是由于某种原因,当缓存为空时该怎么做。 这不会经常发生,但是当它发生时,用户当前显示为空模块,并且在齿轮人员过程中刷新数据,以便稍后当相同(或不同的)用户重新加载页面时,在那里是要显示的数据。
我们的流量是这样的,如果我们试图在缓存为空时为用户运行查询,我们会遇到一个严重的问题 - 我们会多次运行相同的(可能很慢)查询许多用户加载了该页面。 有没有办法解决“空白模块”问题而不会冒着被踩踏的危险?
这是一个有趣的实现,尽管与最典型的在MySQL前端实现memcached的方式有所不同。
在大多数情况下,用户将设置在memcached首次评估查询的位置,以查看是否存在可用条目。 如果是这样,他们从memcached服务器并从不查询数据库。 如果存在高速缓存未命中,则对数据库进行查询,将结果添加到memcached中,并将信息返回给调用者。 这是您通常为读取查询构建缓存的方式。
在数据更新的情况下,将针对数据库进行更新,然后memcached中的相应数据将失效和/或更新。 同样,对于插入,您可以对缓存做任何事情(并让下一次读取该记录填充缓存),也可以根据您的应用程序需要主动将与插入相关的数据添加到缓存中。
这样,在从memcached获取初始数据后,您不需要额外调用数据库来获取权威数据。 memcached中的数据将是更新/插入时更新/失效的权威数据的副本。
根据您的意见,您可能想要尝试的一件事是,在缓存未命中的情况下阻止对数据库进行大量查询,即使用各种类型的互斥体。 例如,当第一个客户端访问memcached并获取该查找的缓存未命中时,可以在memcached中插入一个表示数据未决的临时值,然后对数据库进行查询,并使用该数据更新memcached数据结果。
在客户端,当您遇到缓存未命中或“未决”结果时,您可以在一段时间(您可能想要以指数方式增加)之后简单地启动缓存重试。 因此,也许首先等待1秒,然后在2秒内尝试恢复增益,如果他们仍然得到“待处理”结果,然后在4秒内重试,依此类推。
这可能会导致对memcached服务器的更多请求,但应该解决数据库层上的任何问题。
链接地址: http://www.djcxy.com/p/62997.html上一篇: How to cache popular queries to avoid both stamedes and blank results