﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-不急不徐，持之以恒。-随笔分类-缓存技术</title><link>http://www.blogjava.net/linli/category/54834.html</link><description>http://blog.gopersist.com/</description><language>zh-cn</language><lastBuildDate>Sun, 31 May 2015 09:22:58 GMT</lastBuildDate><pubDate>Sun, 31 May 2015 09:22:58 GMT</pubDate><ttl>60</ttl><item><title>Web缓存技术-Memcached</title><link>http://www.blogjava.net/linli/archive/2015/05/31/425412.html</link><dc:creator>老林</dc:creator><author>老林</author><pubDate>Sun, 31 May 2015 09:18:00 GMT</pubDate><guid>http://www.blogjava.net/linli/archive/2015/05/31/425412.html</guid><wfw:comment>http://www.blogjava.net/linli/comments/425412.html</wfw:comment><comments>http://www.blogjava.net/linli/archive/2015/05/31/425412.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/linli/comments/commentRss/425412.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/linli/services/trackbacks/425412.html</trackback:ping><description><![CDATA[<article style="margin-bottom: 30px; color: #111111; font-family: Helvetica, Arial, sans-serif; font-size: 16px; line-height: 24px; background-color: #fdfdfd;"><p style="margin: 0px 0px 15px; padding: 0px;">互联网上的应用、网站，随着用户的增长，功能的增强，会导致服务器超载，响应变慢等问题。缓存技术是减轻服务器压力、加快服务响应时间、提升用户体验的有效途径。Memcached是非常流行的缓存系统，这里介绍对Memcached的安装、设定，以及在集群环境下的使用。</p><h2>Memcached简介</h2><p style="margin: 0px 0px 15px; padding: 0px;">Memcached是一个开源、高性能、分布式的内存缓存系统，用于加速动态网站的访问，减轻数据库负载。</p><p style="margin: 0px 0px 15px; padding: 0px;">Memcached使用了Slab Allocator的机制分配、管理内存，解决了内存碎片的问题。</p><p style="margin: 0px 0px 15px; padding: 0px;">Memcached虽然可以在多线程模式下运行，但线程数通常只需设定为与CPU数量相同，这一点与Nginx的设定类似。</p><h2>Memcached使用</h2><p style="margin: 0px 0px 15px; padding: 0px;"><strong>安装:</strong></p><p style="margin: 0px 0px 15px; padding: 0px;">在CentOS下使用下面的命令安装：</p><pre style="margin-top: 0px; margin-bottom: 15px; padding: 8px 12px; font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; overflow-x: scroll; background-color: #eeeeff;"><code style="border: 0px; border-radius: 3px; padding: 1px 0px;">sudo yum install memcached </code></pre><p style="margin: 0px 0px 15px; padding: 0px;"><strong>启动：</strong></p><pre style="margin-top: 0px; margin-bottom: 15px; padding: 8px 12px; font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; overflow-x: scroll; background-color: #eeeeff;"><code style="border: 0px; border-radius: 3px; padding: 1px 0px;">memcached -m 100 -p 11211 -d -t 2 -c 1024 -P /tmp/memcached.pid </code></pre><blockquote style="margin: 0px 0px 15px; padding: 0px 0px 0px 15px; color: #828282; border-left-width: 4px; border-left-color: #e8e8e8; font-size: 18px; letter-spacing: -1px; font-style: italic;"><p style="margin: 0px 0px 15px; padding: 0px;">-m 指定使用的内存容量，单位MB，默认64MB。</p><p style="margin: 0px 0px 15px; padding: 0px;">-p 指定监听的TCP端口，默认11211。</p><p style="margin: 0px 0px 15px; padding: 0px;">-d 以守护进程模式启动。</p><p style="margin: 0px 0px 15px; padding: 0px;">-t 指定线程数，默认为4。</p><p style="margin: 0px 0px 15px; padding: 0px;">-c 最大客户端连接数，默认为1024。</p><p style="margin: 0px; padding: 0px;">-P 保存PID文件。</p></blockquote><p style="margin: 0px 0px 15px; padding: 0px;"><strong>关闭：</strong></p><pre style="margin-top: 0px; margin-bottom: 15px; padding: 8px 12px; font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; overflow-x: scroll; background-color: #eeeeff;"><code style="border: 0px; border-radius: 3px; padding: 1px 0px;">kill `cat /tmp/memcached.pid` </code></pre><p style="margin: 0px 0px 15px; padding: 0px;"><strong>测试：</strong></p><p style="margin: 0px 0px 15px; padding: 0px;">使用telnet连接memcached服务。</p><pre style="margin-top: 0px; margin-bottom: 15px; padding: 8px 12px; font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; overflow-x: scroll; background-color: #eeeeff;"><code style="border: 0px; border-radius: 3px; padding: 1px 0px;">telnet localhost 11211 </code></pre><p style="margin: 0px 0px 15px; padding: 0px;">存储命令格式：</p><pre style="margin-top: 0px; margin-bottom: 15px; padding: 8px 12px; font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; overflow-x: scroll; background-color: #eeeeff;"><code style="border: 0px; border-radius: 3px; padding: 1px 0px;">set foo 0 0 4 abcd STORED  &lt;command name&gt; &lt;key&gt; &lt;flags&gt; &lt;exptime&gt; &lt;bytes&gt; &lt;data block&gt;  &lt;command name&gt; set, add, replace等 &lt;key&gt; 关键字 &lt;flags&gt; 整形参数，存储客户端对键值的额外信息，如值是压缩的，是字符串，或JSON等 &lt;exptime&gt; 数据的存活时间，单位为秒，0表示永远 &lt;bytes&gt; 存储值的字节数 &lt;data block&gt; 存储的数据内容 </code></pre><p style="margin: 0px 0px 15px; padding: 0px;">读取命令格式：</p><pre style="margin-top: 0px; margin-bottom: 15px; padding: 8px 12px; font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; overflow-x: scroll; background-color: #eeeeff;"><code style="border: 0px; border-radius: 3px; padding: 1px 0px;">get foo VALUE foo 0 4 abcd END  &lt;command name&gt; &lt;key&gt;  &lt;command name&gt; get, gets。gets比get多返回一个数字，这个数字检查数据有没有发生变化，当key对应的数据改变时，gets多返回的数字也会改变。 &lt;key&gt; 关键字  返回的数据格式：  VALUE &lt;key&gt; &lt;flags&gt; &lt;bytes&gt; </code></pre><p style="margin: 0px 0px 15px; padding: 0px;">CAS(checked and set)：</p><pre style="margin-top: 0px; margin-bottom: 15px; padding: 8px 12px; font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; overflow-x: scroll; background-color: #eeeeff;"><code style="border: 0px; border-radius: 3px; padding: 1px 0px;">cas foo 0 0 4 1 cdef STORED  cas &lt;key&gt; &lt;flags&gt; &lt;exptime&gt; &lt;bytes&gt; &lt;version&gt;  除最后的&lt;version&gt;外，其他参数与set, add等命令相同，&lt;version&gt;的值需要与gets获取的值相同，否则无法更新。 incr, decr可对数字型数据进行原子增减操作。 </code></pre><p style="margin: 0px 0px 15px; padding: 0px;">全局统计信息</p><pre style="margin-top: 0px; margin-bottom: 15px; padding: 8px 12px; font-size: 15px; border: 1px solid #e8e8e8; border-radius: 3px; overflow-x: scroll; background-color: #eeeeff;"><code style="border: 0px; border-radius: 3px; padding: 1px 0px;">stats STAT pid 10218 STAT time 1432611519 STAT curr_connections 6 STAT total_connections 9 STAT connection_structures 7 STAT reserved_fds 10 STAT cmd_get 5 STAT cmd_set 1 STAT cmd_flush 0 STAT cmd_touch 0 STAT get_hits 3 STAT get_misses 2 STAT delete_misses 0 STAT delete_hits 0 ... END </code></pre><h2>Memcached集群</h2><p style="margin: 0px 0px 15px; padding: 0px;">Memcached本身不做任何容错处理，对故障节点的处理方式完全取决于客户端。对Memcached的客户端来说，不能使用普通的哈希算法（哈希取模）来寻找目标Server，因为这样在有缓存节点失效时，会导致大面积缓存数据不可用。如下图：</p><p style="margin: 0px 0px 15px; padding: 0px;"><img src="http://blog.gopersist.com/images/memcached/1.png" alt="" style="max-width: 100%; vertical-align: middle;" /></p><p style="margin: 0px 0px 15px; padding: 0px;"><img src="http://blog.gopersist.com/images/memcached/2.png" alt="" style="max-width: 100%; vertical-align: middle;" /></p><p style="margin: 0px 0px 15px; padding: 0px;">当Server3失效后，客户端需要根据可用Server数量重新计算缓存的目标Server，这时，Key的哈希值为10的数据被指定为由Server1维护，这时原本Server2上可用的缓存也无效了。</p><h4>一致性哈希算法</h4><p style="margin: 0px 0px 15px; padding: 0px;">一致性哈希算法解决了在动态变化的缓存环境中，定位目标Server的问题，通常的实现可将它想像成一个闭合的环形。如下图：</p><p style="margin: 0px 0px 15px; padding: 0px;"><img src="http://blog.gopersist.com/images/memcached/3.png" alt="" style="max-width: 100%; vertical-align: middle;" /></p><p style="margin: 0px 0px 15px; padding: 0px;">当有节点失效时，不会影响到正常工作的缓存服务器，只有原本分配到失效节点的缓存会被重新分配到下一个节点。如下图：</p><p style="margin: 0px 0px 15px; padding: 0px;"><img src="http://blog.gopersist.com/images/memcached/4.png" alt="" style="max-width: 100%; vertical-align: middle;" /></p></article><p style="margin: 0px 0px 15px; padding: 0px; color: #111111; font-family: Helvetica, Arial, sans-serif; font-size: 16px; line-height: 24px; font-weight: bold; font-style: italic; background-color: #fdfdfd;">微信订阅号：<img src="http://blog.gopersist.com/images/about/weixin.jpg" width="100" height="100" style="max-width: 100%; vertical-align: middle;"  alt="" /><br />原文地址：<a href="http://blog.gopersist.com/2015/05/28/memcached/">http://blog.gopersist.com/2015/05/28/memcached/</a></p><img src ="http://www.blogjava.net/linli/aggbug/425412.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/linli/" target="_blank">老林</a> 2015-05-31 17:18 <a href="http://www.blogjava.net/linli/archive/2015/05/31/425412.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>