memcached 常见问题 翻译?Then, when you get from the cache andexamine the timeout and find it expire
memcached 常见问题 翻译
?
Then, when you get from the cache andexamine the timeout and find it expired, immediately edit the embedded timeoutto a time in the future and re-store the data as is. Finally, fetch from the DBand update the cache with the latest value. This does not eliminate, butdrastically reduces the amount of time where a stampede can occur.
?
A decent python example can be found here: http://www.djangosnippets.org/snippets/155/
?
If you have a lot of data excelling atcausing this problem, you might also consider using MySQL Cluster for it, or atiered caching approach
?
Another (pretty cool!) idea is to useGearman, as noted on the mailing list: http://lists.danga.com/pipermail/memcached/2007-July/004858.html
?
模拟带锁的添加命令
如果你实在需要锁,你可以通过“添加”命令模仿锁的功能。尽管在未命中的情况下它不是那么有用,但如果你用它缓存平常的数据(应用服务器池的元数据)那还是有用的。
比如,你要更新键A。
?????? 1.添加一个"lock:A"的键,这个键有一个持续几秒的过期时间(足够长以使你能完成计算和更新,也不要很长,因为如果锁进程挂了,这个键不会立即释放)
?????? 2.如果添加操作成功了,你就拥有了锁:
????????????? 从缓存获取键A的数据。
????????????? 在客户端更改数据。
????????????? 更新缓存键A的数据。
????????????? 删除键"lock:A",如果你不需要立即再次更新,就让它存活直到失效。
??? 3.如果添加操作失败,说明有人获取了锁。这时让应用做些合适的事,比如返回老数据,等待后重试,或是其他的。
以上这些操作类似MySQL将GET_LOCK的timeout值设置成0。没有办法在memcached中通过互斥锁模拟GET_LOCK()的timeout操作。
预热你的缓存
?
如果你有一个很高访问率的站点,并且你正想加入故障恢复功能或是其他全新的功能,你最终可能会碰到空缓存的问题。一开始缓存是空的,然后一大群人点击你的站点,在填充缓存的过程中,你的数据库可能会承受不住压力。为了解决这一问题,你可以试试任何可行的方法来"温暖"你的数据库。
?
你可以写一些脚本来缓存通用的页面。你也可以写一个命令行工具来填充缓存。两种方法都可能对你有帮助。你可以在高峰时刻在缓存里填充一些内容。
1 楼 一点点 2008-12-02 储存list类型的数据
在memcached储存list类型的数据可以认为是存储序列化数组的单个数据项,也可以是在不操作整个数据集的前提下添加删除大集合内的数据项。或者两者皆有。
需要考虑的是memcached对数据项大小有1M的限制,所以在memcached存储整个集合可能不是一个好的方案。
Steven Grimm提出了一个较好的方案:
http://lists.danga.com/pipermail/memcached/2007-July/004578.html
Chris Hondl和Paul Stacey详细说明了另一种方案:
http://lists.danga.com/pipermail/memcached/2007-July/004581.html
两种方案的结合可能会产生具有相当规模的List。在某一范围内的IDs可以用不同的键储存,数据用各自的键储存。
用get_muti发起批量请求
如果你刚开始使用memcached,你可能会写出像下面一样的代码:
greet = get("Foo")
person = get("Bar")
place = get("Baz")
当你调整性能时,你可能会发现每次调用get()都会有以下过程:
get("Foo") - client - server - client
get("Bar") - client - server - client
get("Baz") - client - server - client
许多客户端都支持一次从单个memcached实例中获取多个键,有些客户端支持并行获取。如果有3个键在3台memcached上,请求会被同时发出,你只要等待最慢的那台返回数据后就可以得到所有数据。如果你有很多数据要取,这可以大大提高速度。
很多有关发出组合和并行请求的技术方案可以在邮件列表中找到http://lists.danga.com/pipermail/memcached/2007-July/004528.html
生成好的键
在生成键时,用sprintf()或差不多的方法是个好主意。否则,null值或布尔值会很容易成为键,而这并不是你所希望的。memKey = sprintf ( 'cat:%u', categoryId );
把memcached当作简单的消息通道使用
也许你想要把memcached当作廉价的队列或写回缓存使用。有个技术使用incr/decr产生唯一的键来管理队列项。[url]http://broddlit.wordpress.com/ 2008/04/09/memcached-as- simple-message-queue/[/url]
小心碰到内存限制和缓存到期失效问题。
常见的问题
连接偶尔断开
如果memcached服务器偶尔拒绝连接,可能是因为存在一些潜在的问题,他们可能是:
1.客户端太旧了。老版本的php pecl/memcache需要额外时间保持连接。
2.向服务器发送了不合适的键。如果空格,新行等等从客户端泄漏,这可能会造成和服务器不同步。
3.防火墙阻断了连接。
4.用完了TIME_WAIT buckets或是本地的tcp/ip端口。参考你的操作系统。
太多的连接
会超出memcached集群的最大连接数吗?首先请记住,memcached可以满足你要的连接数的要求。只要增加你需要的连接数就可以了。但如果你有4000个连接而只有3台服务器,那就没办法了。
每个web服务器至少连接着一个memcached实例。如果你的应用跑在apache2上,同时设置了apache2的最大连接数为10,那正常情况下你的memcached最多只有10个连接。相反,如果你运行线程模式并设置最大客户端为1024,那连接数就会高出很多。连接数也取决于你有多少CPU。同样连接率也有些依赖客户端行为。一些客户端建立了连接池,这会减少与服务器的连接数。
记住没有什么能阻止你多次连接memcached。如果你存储一个拥有memcached客户端实例的对象,不要惊讶有一次请求中有1000个对象要创建1000个并发的连接。请仔细考虑此类问题。