天天看點

memcached詳細介紹,安裝,高可用,分布式案例,監控

memcached 是一套記憶體緩存系統或者軟體,用于動态應用系統中緩存資料庫資料,減少資料庫通路壓力,達到性能提升目的

1,一般在企業中用于資料庫的cache

2,作為叢集架構節點應用伺服器之間session資料共享的存儲

memcached 是通過預配置設定指定記憶體空間來存儲資料,java ,php 應用并發超不過1000  單台mysql200-300 已經很大了

memcached(不能持久化),redis(可持久化緩存)     後端資料庫的緩存,動态資料。博文,bbs

nginx ,squid,varnish         前端web應用的緩存  靜态資料緩存,圖檔,附件,js,css,html

需要事先配置設定一塊記憶體,通過api方式存取,讀取記憶體中的緩存資料,每條資料是以key-value形式存放

當程式更新,删除資料庫中已有的資料時候,用戶端會同時發送請求通知memcached已經緩存過的同一ID内容的舊資料失效,進而保證memecached中的資料和資料庫中的

資料一緻 

如果是高并發場合,除了通知memcached過期的緩存失效外,還會通過相關機制使使用者通路新資料前,通過程式預先把更新的資料推送到memcached中緩存起來,然後再

通路,這樣可以減少資料的通路壓力,,這樣的效率非常高

缺點:

1,如果memcached 重新開機(斷電),緩存丢失,可能造成資料雪崩

如何處理??

先把前端代理設定禁止對外通路,通過程式做初始化,把mysql資料緩存好,緩存到memcached中,然後慢慢挂載好伺服器,然後讓前端找緩存

當memcached記憶體空間用完之後,memecached自身會使用(LRU least recently used 最近最少使用)加到期權失效政策,失效的資料首先被替換掉,然後是最近未使用

的資料被替換掉

幾乎所有網站,當通路量很大的時候,最先出現的是資料庫角色伺服器,以及存儲角色伺服器出現瓶頸,我們設計的時候應該靠前原則

千萬級pv/ip規模高性能并發網站架構

http://oldboy.blog.51cto.com/2561410/736710

memcached 【分布式應用1】

memcached支援分布式,我們在應用伺服器程式上改造,就可以好的支援,例如我們的key可以适當進行有規律的

封裝,比如以使用者為主的網站來說,每個使用者都有userid,那麼可以按照固定的ID來進行提取和存取,比如1-100w開頭的使用者儲存在第一台memcached伺服器上,,以

100-200w開頭的儲存在第二台伺服器上,存取資料都先按照userID來進行相應的轉換存儲。

但是這個有缺點,就是需要對userID 進行判斷,如果業務不一緻,或者其他類型的應用,肯定不是那麼合适,根據自己業務判斷.

memcached【分布式應用2】

在應用伺服器通過程式URL_HASH,抑制性雜湊演算法通路memcached服務, 所有memcached伺服器位址池可以簡單的每個程式配置檔案裡

memcached【分布式應用3】

門戶 百度。會通過一個中間件代理負責請求後端的cache服務,然後連接配接web

memcached【分布式應用4】

可以用常見的LVS haproxy做cache的負載均衡. 重點是排程算法, cache一般選擇url_hash以及一緻性hash算法,會犧牲LVS的性能

memcahed 服務應用優化案例

資料庫負責很高 load 20-30

登入資料庫

show processlist;

show full processlist ;

mysql -u -p -e "show full processlist | grep -vi sleep"

結果顯示like "***" 類似語句很多

優化思路:

1,從業務上實作使用者登入後在搜尋,可以減少搜尋次數,進而減輕資料庫壓力

2,如果有大量平凡的搜尋,一般是爬蟲在爬你們網站,ip封掉

3,配置主從同步,程式實作讀寫分離,最好案吧like的語句去從庫查詢,減輕主庫壓力

4,一般像like的語句,一般很難在mysql裡面優化,可以通過搜尋服務sphinx實作搜尋

5.在資料庫前端加memcached伺服器

memcached 特性:

memcached 作為高并發,高性能的緩存服務,具有以下特征:

協定簡單

memcached 的協定實作比較簡單,使用基本的文本協定,能通過telent之間操作memcached伺服器存取資料

基于libevent的事件處理

内置的記憶體管理方式 (slab allocation)

這個内置管理方式很高效,所有資料都儲存在memecache中,當存入的資料占滿空間時候,memcached使用URL算法自動删除不适用的緩存資料,就,即重用過期資料的内

存空間.但是容易丢失資料,可以會用sina開發的memcaceDB 持久性記憶體緩存系統,當然還有redis,mongodb

memcached伺服器之間不通信,都是獨立存儲資料,不共享任何資訊,通過對用戶端的設計,讓memcached具有分布式,支援海量資料的大規模應用

.

memcached軟體工作原理:

memcached是一個C/S架構軟體,在服務端啟動服務守護程序,可以為memcached伺服器指定監聽IP位址,端口号,并發連接配接數,以及配置設定多少記憶體來處理用戶端的請求參

采用異步的I/O,應用程式通過指定伺服器的IP位址,和端口,就可以連接配接memcached服務互相通信

需要被緩存的資料以key/value鍵值對的形式儲存在伺服器端配置設定的記憶體中,每個被緩存的資料有唯一的标示key,操作memcached中的資料通過這個唯一标示key進行,

緩存到memcached的資料都被放在被配置設定放的記憶體中,而不是被配置設定到磁盤中,是以讀書速遞非常快

注意事項,要考慮重新啟動丢失資料帶來的影響和高并發場合丢失資料

memcached删除機制

memcached不會釋放已配置設定的記憶體空間,(除非添加資料時候設定過期或者記憶體滿了的時候)

lazy expiration政策,自己不會監控存入的key/value對是否過期,而是擷取key值檢視記錄時間戳檢查key/value對空間是否過期,這種政策不會再過期檢查上浪費CPU

資源

LRU算法來配置設定空間,删除最近最少使用的key/value對,如果記憶體足夠大,不想使用LRU算法,那麼可以再啟動時候加上-M 參數,這樣memcached會在記憶體耗盡時候傳回

一個錯誤

安裝memcached

<code>1,wget  http:</code><code>//www</code><code>.monkey.org/~provos</code><code>/libevent-1</code><code>.4.13-stable.</code><code>tar</code><code>.gz</code>

<code>[root@localhost ~]</code><code># tar xvf libevent-1.4.13-stable.tar.gz </code>

<code>[root@localhost ~]</code><code># cd libevent-1.4.13-stable</code>

<code> </code> 

<code>[root@localhost libevent-1.4.13-stable]</code><code>#</code>

<code>make</code> 

<code>make</code> <code>install</code>

<code>2,memcached</code>

分為用戶端和服務端

<code>memcached-2.2.5.tgz   ---client</code>

<code>memcached-1.4.15.</code><code>tar</code>  <code>--server</code>

<code>wget http:</code><code>//memcached</code><code>.googlecode.com</code><code>/memcached-1</code><code>.4.13.</code><code>tar</code><code>.gz</code>

<code>        </code><code>cd</code> <code>memcached-1.4.15</code>

<code> </code><code>1004  .</code><code>/configure</code> <code>&amp;&amp; </code><code>make</code> <code>&& </code><code>make</code> <code>install</code> 

<code> </code><code>1010   </code><code>ls</code> <code>/usr/local/lib/</code>

<code> </code><code>1011   </code><code>echo</code> <code>"/usr/local/lib"</code> <code>&gt;&gt; </code><code>/etc/ld</code><code>.so.conf </code>

<code> </code><code>1012   ldconfig </code>

<code> </code><code>1013   </code><code>which</code> <code>memcached</code>

<code>       </code><code>/usr/local/bin/memcached</code>

<code> </code><code>memcached 1.4.15</code>

<code>-p &lt;num&gt;      TCP port number to listen on (default: 11211)</code>

<code>-U &lt;num&gt;      UDP port number to listen on (default: 11211, 0 is off)</code>

<code>-l &lt;addr&gt;     interface to listen on (default: INADDR_ANY, all addresses)</code>

<code>              </code><code>&lt;addr&gt; may be specified as host:port. If you don't specify</code>

<code>              </code><code>a port number, the value you specified with -p or -U is</code>

<code>              </code><code>used. You may specify multiple addresses separated by comma</code>

<code>              </code><code>or by using -l multiple </code><code>times</code>

<code>-d            run as a daemon </code>

<code>-r            maximize core </code><code>file</code> <code>limit</code>

<code>-u &lt;username&gt; assume identity of &lt;username&gt; (only when run as root)</code>

<code>-m &lt;num&gt;      max memory to use </code><code>for</code> <code>items </code><code>in</code> <code>megabytes (default: 64 MB)</code>

<code>-M            </code><code>return</code> <code>error on memory exhausted (rather than removing items)</code>

<code>-c &lt;num&gt;      max simultaneous connections (default: 1024) 并發</code>

<code>-P &lt;</code><code>file</code><code>&gt;     save PID </code><code>in</code> <code>&lt;</code><code>file</code><code>&gt;, only used with -d option</code>

<code>[root@localhost ~]</code><code># memcached -p 11211 -u root -m 16m -c 10240 -d </code>

<code>[root@localhost ~]</code><code># lsof -i:11211</code>

<code>COMMAND     PID USER   FD   TYPE DEVICE SIZE</code><code>/OFF</code> <code>NODE NAME</code>

<code>memcached 20124 root   26u  IPv4 139731      0t0  TCP *:memcache (LISTEN)</code>

<code>memcached 20124 root   27u  IPv6 139732      0t0  TCP *:memcache (LISTEN)</code>

<code>memcached 20124 root   28u  IPv4 139735      0t0  UDP *:memcache </code>

<code>memcached 20124 root   29u  IPv6 139736      0t0  UDP *:memcache</code>

<code>啟動memcached 多執行個體  各個執行個體之間是相對獨立的</code>

<code> </code><code>memcached -p 11212 -u root -m 16m -c 10240 -d </code>

<code>/etc/rc</code><code>.</code><code>local</code>

(4)寫入資料檢查結果

向memcached中添加資料

<code>1,通過nc寫入</code>

<code>[root@localhost ~]</code><code># printf "set key007 0 0 10\r\noldboy0987\r\n"|nc 127.0.0.1 11211</code>

<code>STORED   ----指令的位元組是10,那麼後面就是10個字元,否則添加不成功</code>

<code>[root@localhost ~]</code><code># printf "get  key007\r\n" | nc 127.0.0.1 11211</code>

<code>VALUE key007 0 10</code>

<code>oldboy0987</code>

<code>END</code>

<code>[root@localhost ~]</code><code># printf "set key001 0 0 10\r\noldboy0098\r\n"|nc 127.0.0.1 11211</code>

<code>STORED</code>

<code>删除:</code>

<code>[root@localhost ~]</code><code># printf "delete key001\r\n" | nc 127.0.0.1 11211</code>

<code>DELETED</code>

<code>[root@localhost ~]</code><code># printf "get key001\r\n" | nc 127.0.0.1 11211</code>

<code>telent 127.0.0.1 11211</code>

<code>stats         ---檢視memcached的服務狀态</code>

<code>STAT pid 20124</code>

<code>STAT uptime 10911</code>

<code>STAT </code><code>time</code> <code>1437183342</code>

<code>STAT version 1.4.15</code>

<code>STAT libevent 1.4.13-stable</code>

<code>STAT pointer_size 64</code>

<code>STAT rusage_user 0.146977</code>

<code>STAT rusage_system 0.469928</code>

<code>STAT curr_connections 10</code>

<code>STAT total_connections 54</code>

<code>STAT connection_structures 12</code>

<code>STAT reserved_fds 20</code>

<code>STAT cmd_get 28</code>

<code>STAT cmd_set 4</code>

<code>STAT cmd_flush 0</code>

<code>STAT cmd_touch 0</code>

<code>STAT get_hits 12   ---------命中率  ,每次get 便會遞增1</code>

<code>STAT get_misses 16 ---------丢失率</code>

<code>STAT delete_misses 0</code>

<code>STAT delete_hits 1</code>

<code>STAT incr_misses 0</code>

<code>STAT incr_hits 0</code>

<code>STAT decr_misses 0</code>

<code>STAT decr_hits 0</code>

<code>STAT cas_misses 0</code>

<code>STAT cas_hits 0</code>

<code>STAT cas_badval 0</code>

<code>STAT touch_hits 0</code>

<code>STAT touch_misses 0</code>

<code>STAT auth_cmds 0</code>

<code>STAT auth_errors 0</code>

<code>STAT bytes_read 3888</code>

<code>STAT bytes_written 2571</code>

<code>STAT limit_maxbytes 16777216</code>

<code>STAT accepting_conns 1</code>

<code>STAT listen_disabled_num 0</code>

<code>STAT threads 4</code>

<code>STAT conn_yields 0</code>

<code>STAT hash_power_level 16</code>

<code>STAT hash_bytes 524288</code>

<code>STAT hash_is_expanding 0</code>

<code>STAT bytes 161</code>

<code>STAT curr_items 2</code>

<code>STAT total_items 3   新增一個,此值會遞增</code>

<code>STAT expired_unfetched 0</code>

<code>STAT evicted_unfetched 0</code>

<code>STAT evictions 0</code>

<code>STAT reclaimed 0</code>

重新開機memcached ,資料丢失

<code>[root@localhost ~]</code><code># printf "get key\r\n"|nc 127.0.0.1 11211</code>

<code>VALUE key 0 10</code>

<code>wybwyb</code>

<code>[root@localhost ~]</code><code># ps -ef | grep memcached</code>

<code>root     20124     1  0 06:33 ?        00:00:00 memcached -p 11211 -u root -m 16m -c 10240 -d</code>

<code>root     22920 22899  0 09:47 pts</code><code>/1</code>    <code>00:00:00 </code><code>grep</code> <code>memcached</code>

<code>[root@localhost ~]</code><code># kill -9 20124</code>

<code>root     22922 22899  0 09:48 pts</code><code>/1</code>    <code>00:00:00 </code><code>grep</code> <code>memcached</code>

<code>root     22924     1  0 09:49 ?        00:00:00 memcached -p 11211 -u root -m 16m -c 10240 -d</code>

<code>root     22931 22899  0 09:49 pts</code><code>/1</code>    <code>00:00:00 </code><code>grep</code> <code>memcached</code>

memcached指令文法

set           key    0            0     10

&lt;command name&gt; &lt;key&gt;  &lt;flags&gt;  &lt;exptime&gt; &lt;bytes&gt;\r\n

 command name  是set get add  replace

擷取資料

key 是接下來的用戶端所要求儲存的資料的鍵值

叢集中的session共享存儲

http://oldboy.blog.51cto.com/2561410/1331316

用memcached來存儲session特點:

優點:

1)讀寫速度上會比普通files時快很多。

2)可以解決多個伺服器共用session的難題。

1)session資料都儲存在memory中,持久化方面有所欠缺,但對session資料來說不是問題。

2)單點,部署多台,也無法資料同步。通過hash算法配置設定依然有sesson丢失的問題。

大規模企業解決思路:

2)可以用其他的持久化系統存儲sessons,例如:redis,ttserver,替代memcached。

3)高性能高并發場景,cookies效率比session要好很多,是以,大網站都會用cookies解決會話共享問題。

4)有初級運維網友通過犧牲LB的負載均衡的政策實作,例如:lvs -p,nginx ip_hash等,這些不是好的方法。

如何解決session不共享的問題呢 

http://oldboy.blog.51cto.com/2561410/1323468

1,在服務端啟動一個memcache執行個體,把這個執行個體作為共享 memcached -p 11211 -u root -m 16m -c 10240 -d

真正配置的開始

修改配置檔案,在php.ini中全局設定:

###################web叢集session共享存儲設定:

1,讓所有的web伺服器把session儲存在相同路徑的緩存裡面(/tmp)

可以做共享nfs ,把/tmp共享,(A-B伺服器),但是nfs高通路下,響應不夠及時,是以都存放到memcached中

php.ini

session.save_path = "/tmp"

2,使用memcached

把所有web站點的php.ini改成同一memcached的ip+port

預設php.ini中session的類型和配置路徑:

#session.save_handler = files

#session.save_path = "/tmp"

修改成如下配置:

session.save_handler = memcache

session.save_path = "tcp://10.0.0.18:11211"  ---

提示:

1)10.0.0.18:11211 為memcached資料庫緩存的IP及端口。

2)上述适合LNMP,LAMP環境。

3)memcached伺服器也可以是多台通過hash排程。

##################針對memcached單點故障出現的問題解決方案:(也不太完美,沒有解決master挂掉,再次開啟資料無法恢複問題)

1,針對memcached做高可用

http://blog.snsgou.com/post-800.html

2,使用新浪的memcachedDB,對原有用戶端來講還是memcached,但在服務端他是可以持久化存儲。

3,日本人開發的Tokyo tyrant+Tokyo Cabinet

#################memcached的管理方式

1,通過telent + port +ip

2, 通過nc    ---printf "get key008\r\n" | nc 127.0.0.1 11211

###############memcached 監控管理工具

memadmin-1.0.12.tar.gz  -----放到php站點目錄下----(lamporonmp 最好是源碼編譯)

tar xvf memamin

www.etiantian.com/memcache

通過memadmin工具,可以看到memcached的狀态,連接配接次數,目前的并發數,通過這些資訊可以

分析出,目前memcached的換入換出手否比較厲害,容量是否足夠

      本文轉自crazy_charles 51CTO部落格,原文連結:http://blog.51cto.com/douya/1677869,如需轉載請自行聯系原作者