色尼玛亚洲综合影院,亚洲3atv精品一区二区三区,麻豆freexxxx性91精品,欧美在线91

Memcached使用點(diǎn)滴

  我對(duì)于Memcached的接觸,還是在去年看了CSDN的一系列國外大型網(wǎng)站架構(gòu)設(shè)計(jì)而開始的。最初的時(shí)候只是簡單的封裝了Memcached Java版的客戶端,主要是對(duì)于配置的簡化以及Memcached多點(diǎn)備份作了一些工作,然后就作為ASF的組件一部分提供給其他Team使用。其實(shí)看過Memcached Java客戶端代碼的人就會(huì)了解其實(shí)客戶端的事情很簡單,就是要有一套高性能的Socket通信框架以及對(duì)Memcached的私有協(xié)議實(shí)現(xiàn)的接口,自己去做這些事情也是很簡單的,不過既然有可以滿足自己需求的開源部分,那么就去實(shí)現(xiàn)自己需要的但沒有實(shí)現(xiàn)的。這里我用的是Whalin的客戶端版本,這里為什么還要提出來講這個(gè),后面會(huì)提到。

       在對(duì)Java客戶端作了簡單封裝和擴(kuò)展以后,由于其他Team使用的沒有什么特殊需求,也就沒有再去做太多的修改,直到最近自己的服務(wù)集成平臺(tái)需要做服務(wù)訪問控制,才重新豐富了Cache組件,也就是這個(gè)過程中對(duì)于Memcached的一些特性和小的細(xì)節(jié)有了一些新的認(rèn)識(shí)。

       作為服務(wù)集成平臺(tái)需要對(duì)服務(wù)有所監(jiān)控,包括訪問頻率控制以及訪問次數(shù)控制。頻率控制其實(shí)很類似于硬件方面的頻率控制,例如硬件可以對(duì)IP的高頻率訪問視為攻擊,列入黑名單。而作為服務(wù)的訪問,對(duì)于服務(wù)訪問者的控制其實(shí)涉及到了業(yè)務(wù)參數(shù),那么硬件就不是很適合去做這方面的控制,為此我也考慮了很久,最開始打算在Apache上做一個(gè)模塊控制,但是最后覺得還是放在后面的業(yè)務(wù)框架上做這件事情。當(dāng)然后面我說說的方案可能并不好,但是也算是一種想法。要把頻繁的訪問數(shù)據(jù)記錄下來同時(shí)分析,那么數(shù)據(jù)庫肯定是不行的,最簡單的方式就是采用Cache,又因?yàn)槭羌悍秶鷥?nèi)的控制,那么集中式Cache就非Memcached莫數(shù)了(分布式的Cache傳播本身損耗太大,集中式Cache本來的最大缺點(diǎn)就是單點(diǎn),但作簡單的備份操作就可以基本解決此類問題)。

       作為解決這個(gè)問題的方法來說只需要實(shí)現(xiàn)兩部分工作:訪問計(jì)數(shù)器,定時(shí)任務(wù)。定時(shí)任務(wù)在我做日志分析框架的時(shí)候都是采用了Jdk5Concurrent包里面的ScheduledExecutorService,這個(gè)作簡單的循環(huán)任務(wù)足夠用了,同時(shí)也是有很好的多線程異步支持,復(fù)雜一點(diǎn)么用Quartz。計(jì)數(shù)器就要靠Memcached來實(shí)現(xiàn)了,本來一般的Cache最大的問題就是高并發(fā)下的事務(wù)保證,如果采用Get+Set來完成計(jì)數(shù)的話,那么高并發(fā)下計(jì)數(shù)器就會(huì)出現(xiàn)讀寫不一致性的問題,幸好Memcached提供了計(jì)數(shù)累加功能,讓這種累加動(dòng)作能夠在服務(wù)端一次做好,服務(wù)端控制并發(fā)寫入,保證數(shù)據(jù)的一致性。

下面就看看以下幾個(gè)方法:

boolean storeCounter(String key, long count)存儲(chǔ)key的計(jì)數(shù)器,值為count

long getCounter(String key):獲取key的計(jì)數(shù)器,如果不存在返回-1

long addOrDecr(String key, long decr):計(jì)數(shù)器值減去decr,如果計(jì)數(shù)器不存在,保存decr作為計(jì)數(shù)器值

long addOrIncr(String key, long inc):計(jì)數(shù)器值增加inc,如果計(jì)數(shù)器不存在,保存inc作為計(jì)數(shù)器值

long decr(String key, long decr):與addOrDecr不同的是在計(jì)數(shù)器不存在的時(shí)候不保存任何值,返回-1

long incr(String key, long inc) :與addOrIncr不同的是在計(jì)數(shù)器不存在的時(shí)候不保存任何值,返回-1

這里需要說明幾點(diǎn):

storeCounter和普通的set方法不同,如果通過set方式置入key:value的話,getCounter等其他四個(gè)方法都認(rèn)為技術(shù)器不存在。所以Counter存儲(chǔ)方式是和普通內(nèi)容存儲(chǔ)不同的。

在不同的場(chǎng)景要慎用addOrXXXXXXXX的方法,兩者還是有比較大的區(qū)別的。

計(jì)數(shù)器沒有提供移除特殊方法,使用delete方法可以移除計(jì)數(shù)器,但是頻繁的deleteaddOrXXXX有時(shí)候會(huì)出現(xiàn)一些奇怪的問題(例如同名的計(jì)數(shù)器就沒有辦法再次被創(chuàng)建,不過這個(gè)還需要進(jìn)一步的去研究一下看看)。一般情況下如果計(jì)數(shù)器的key不是很多,同時(shí)也會(huì)被復(fù)用,那么可以通過置為0或者減去已經(jīng)分析過的數(shù)量來復(fù)位。

       有上面的一套計(jì)數(shù)器機(jī)制就可以很方便的實(shí)現(xiàn)Memcached的計(jì)數(shù)功能,但是又一個(gè)問題出現(xiàn)了,如何讓定時(shí)任務(wù)去遍歷計(jì)數(shù)器,分析計(jì)數(shù)器是否到了閥值,觸發(fā)創(chuàng)建黑名單記錄的工作。早先我同事希望我能夠提供封裝好的keySet接口,但是我自己覺得其實(shí)作為Cache來說簡單就是最重要的,Cache不需要去遍歷。首先使用Cache的角色就應(yīng)該知道Key,然后去Cache里面找,找不到就去后臺(tái)例如DB里面去搜索,然后將搜索的結(jié)果在考慮更新到Cache里面,這樣才是最高效并且最可靠的,Cache靠不住阿,隨時(shí)都可能會(huì)丟失或者崩潰,因此作為類似于一級(jí)緩存或者這類數(shù)據(jù)完整性要求不高,性能要求很高的場(chǎng)景使用最合適。當(dāng)時(shí)就沒有提供這樣的接口,直到今天自己需要了,才考慮如何去做這件事情。

       開始考慮是否能夠?qū)?/span>key都記錄在另外的Cache中或者是Memcached中,首先在高并發(fā)下更新操作就是一大問題,再者Memcached的內(nèi)存分配回收機(jī)制以及Value的大小限制都不能滿足這樣的需求,如果使用數(shù)據(jù)庫,那么頻繁更新操作勢(shì)必不可行,采用異步緩存刷新又有一個(gè)時(shí)間間隔期,同時(shí)更新也不是很方便。最后考慮如果能夠讓Memcached實(shí)現(xiàn)Keyset那么就是最好的解決方案,網(wǎng)上搜索了一下,找到一種策略,然后自己優(yōu)化了一下,優(yōu)化后的代碼如下:

Code

NET技術(shù)Memcached使用點(diǎn)滴,轉(zhuǎn)載需保留來源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 门头沟区| 上犹县| 沁阳市| 正阳县| 盐池县| 齐河县| 庐江县| 文水县| 勐海县| 华阴市| 大足县| 常山县| 毕节市| 杭锦后旗| 凌源市| 邹平县| 彭阳县| 朝阳区| 许昌市| 广水市| 越西县| 周至县| 梁河县| 德钦县| 增城市| 苍溪县| 浦北县| 洛扎县| 南华县| 乐安县| 安泽县| 枣强县| 吉木萨尔县| 宁阳县| 武山县| 仁寿县| 西乡县| 阜新市| 罗田县| 温宿县| 沿河|