配色: 字号:
KeySpaceNotification 键空间通知
2016-10-26 | 阅:  转:  |  分享 
  
KeySpaceNotification键空间通知



1、Redis键淘汰机制简介



在Redis中,内存的大小是有限的,所以为了防止内存饱和,需要实现某种键淘汰策略。主要有两种方法,一种是当Redis内存不足时所采用的内存释放策略。第二种是对过期键进行删除的策略,也可以在某种程度上释放内存。



1.1Redis键过期淘汰的策略



当需要进行内存释放的时候,需要用某种策略对保存的的对象进行删除。Redis有六种策略:



volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰



volatile-ttl:从已设置过期时间的数据集中挑选将要过期的数据淘汰



volatile-random:从已设置过期时间的数据集中任意选择数据淘汰



allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰



allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰



no-enviction(驱逐):禁止驱逐数据



2、KeySpaceNotification功能



2.1开启KeySpaceNotification功能



默认情况下,该功能是关闭的,因为该功能消耗部分CPU。开启该功能需要修改redis的配置文件。



当前需要修改的配置的机器有两台:Redis1、Redis2



配置文件的路径均为:/etc/redis



clip_image002



图1Redis1中需要修改的配置文件



clip_image004



图2Redis2中需要修改的配置文件



2.2修改配置文件



1.使用vi6379.conf进入文件;



clip_image006



图3使用vi指令进入配置文件



2.输入/keyspace,回车后定位到该功能开启部分;



clip_image008



图4定位keyspace



clip_image009



图4查看通知功能介绍



3.修改配置文件为下图所示KEA表示所有的操作都会向相应的频道中发布通知信息;



clip_image011



图5修改后的配置文件



4.按下Esc,输入:wq!回车保存文件;



5.按照上述过程将所有的配置文件。



6.重启Redis1、Redis2,使键空间通知功能开启。



3、使用键空间通知功能



3.1实现频道的订阅



复制代码

publicclassjedisSubscribe{



publicstaticvoidmain(String[]args){



SetjedisClusterNodes=newHashSet();



JedisClustercluster;



cluster=newJedisCluster(RedisPool.loadServers());



Stringhost1="192.168.1.34";



JedisPubSubjedisPubSub=null;



jedisPubSub=newJedisPubSub(){



/



常规模式:关闭订阅时触发arg0key值arg1订阅数量



/



publicvoidonUnsubscribe(Stringarg0,intarg1){



}



/



常规模式:启动订阅时触发arg0key值arg1订阅数量



/



publicvoidonSubscribe(Stringarg0,intarg1){



System.out.println("SuccessonSubscribe"+arg0);



}



/



常规模式:收到匹配key值的消息时触发arg0key值arg1收到的消息值



/



publicvoidonMessage(Stringarg0,Stringarg1){



System.out.println("GetMessage"+arg1);



System.out.println("Get"+arg0);



Stringkey=cluster.get(arg0);



System.out.println("Success"+key);



}



/



正则模式:关闭正则类型订阅时触发



arg0key的正则表达式arg1订阅数量



/



publicvoidonPUnsubscribe(Stringarg0,intarg1){



}



/



正则模式:启动正则类型订阅时触发



arg0key的正则表达式



arg1订阅数量



/



publicvoidonPSubscribe(Stringarg0,intarg1){



}



/



正则模式:收到匹配key值的消息时触发



arg0订阅的key正则表达式



arg1匹配上该正则key值



arg2收到的消息值



/



publicvoidonPMessage(Stringarg0,Stringarg1,Stringarg2){



}



};



Stringchannel4="__keyevent@0__:expire";//设置订阅的频道channels



JedisPooljedisPool1=newJedisPool(host1);



jedisPool1.getResource().subscribe(jedisPubSub,channel4);



}



}

复制代码





3.2对Redis中的键进行操作



复制代码

publicstaticvoidmain(String[]args)throwsInterruptedException{



SetjedisClusterNodes=newHashSet();



JedisClustercluster;



cluster=newJedisCluster(RedisPool.loadServers());



Stringkey="name";//设置一个key



Stringvalue="zpf";//设置该key的value



cluster.set(key,value);//向redis中写入该(key,value)



cluster.expire(key,2);//设置key过期时间为2秒



cluster.del(key);



}

复制代码





3.3运行结果



clip_image013



4.车辆信息的实时性维护



4.1利用键空间通知的方法



Redis会在设置过期时间的键集合中随机抽选进行键的判断,如果过期则进行删除操作,同时会向频道__keyevent@0__:expire中过期消息,并且监听这个频道的程序会得到过期的键是哪一个键。也会向频道__keyspace@0__:key中发布该键过期的消息,其中这里的频道根据过期的键key不同发布的频道也不同。进行删除操作时,Redis也会向频道__keyevent@0__:del和__keyspace@0__:key中分别发布消息。



为了维护车辆信息的实时性,需要对过期的车辆数据进行相应的删除操作,但是Redis中的删除操作只能将对应的key删除掉,这里的需求是进行网格以及其他相应的维护操作,删除操作是不相同的。因此需要再删除之前得到过期的key的值value。



clip_image015



clip_image017



根据上面的描述,无法再订阅频道__keyevent@0__:expire接收到通知的时候得到过期键的值value。为了实现借助Redis的删除功能需要在该频道接收到信息之前得到要过期的key的值value。但是这样的话又成了对redis的判断操作。为了实现得到过期键的value,可以通过在得到该数据并进行设置过期时间的时候提前构造一个map其中key为车牌,value为车牌+原始信息的value。这样在频道__keyevent@0__:expire接收到通知时,就可以使用map得到相应的value值。



4.2使用该方法造成的问题



构造map时,需要对每一辆车进行判断,如果车牌key不在此map中时,需要将该信息放入map中;如果车牌key存在此map中,需要更新map。那么存储该map需要占用额外的存储空间。



参考资料:



RedisKeyspaceNotifications

IMPORTANTKeyspacenotificationsisafeatureavailablesince2.8.0

Featureoverview

KeyspacenotificationsallowsclientstosubscribetoPub/SubchannelsinordertoreceiveeventsaffectingtheRedisdatasetinsomeway.

Examplesoftheeventsthatispossibletoreceivearethefollowing:

Allthecommandsaffectingagivenkey.

AllthekeysreceivinganLPUSHoperation.

Allthekeysexpiringinthedatabase0.

EventsaredeliveredusingthenormalPub/SublayerofRedis,soclientsimplementingPub/Subareabletousethisfeaturewithoutmodifications.

BecauseRedisPub/Subisfireandforgetcurrentlythereisnowaytousethisfeatureifyouapplicationdemandsreliablenotificationofevents,thatis,ifyourPub/Subclientdisconnects,andreconnectslater,alltheeventsdeliveredduringthetimetheclientwasdisconnectedarelost.

Inthefuturethereareplanstoallowformorereliabledeliveringofevents,butprobablythiswillbeaddressedatamoregeneralleveleitherbringingreliabilitytoPub/Subitself,orallowingLuascriptstointerceptPub/Submessagestoperformoperationslikepushingtheeventsintoalist.

Typeofevents

KeyspacenotificationsareimplementedsendingtwodistincttypeofeventsforeveryoperationaffectingtheRedisdataspace.ForinstanceaDELoperationtargetingthekeynamedmykeyindatabase0willtriggerthedeliveringoftwomessages,exactlyequivalenttothefollowingtwoPUBLISHcommands:

PUBLISH__keyspace@0__:mykeydel

PUBLISH__keyevent@0__:delmykey

Itiseasytoseehowonechannelallowstolistentoalltheeventstargetingthekeymykeyandtheotherchannelallowstoobtaininformationaboutallthekeysthataretargetofadeloperation.

Thefirstkindofevent,withkeyspaceprefixinthechanneliscalledaKey-spacenotification,whilethesecond,withthekeyeventprefix,iscalledaKey-eventnotification.

Intheaboveexampleadeleventwasgeneratedforthekeymykey.Whathappensisthat:

TheKey-spacechannelreceivesasmessagethenameoftheevent.

TheKey-eventchannelreceivesasmessagethenameofthekey.

Itispossibletoenableonlyonekindofnotificationinordertodeliverjustthesubsetofeventsweareinterestedin.

Configuration

BydefaultkeyspaceeventsnotificationsaredisabledbecausewhilenotverysensiblethefeatureusessomeCPUpower.Notificationsareenabledusingthenotify-keyspace-eventsofredis.conforviatheCONFIGSET.

Settingtheparametertotheemptystringdisablesnotifications.Inordertoenablethefeatureanon-emptystringisused,composedofmultiplecharacters,whereeverycharacterhasaspecialmeaningaccordingtothefollowww.wang027.comwingtable:

KKeyspaceevents,publishedwith__keyspace@__prefix.

EKeyeventevents,publishedwith__keyevent@__prefix.

gGenericcommands(non-typespecific)likeDEL,EXPIRE,RENAME,...

$Stringcommands

lListcommands

sSetcommands

hHashcommands

zSortedsetcommands

xExpiredevents(eventsgeneratedeverytimeakeyexpires)

eEvictedevents(eventsgeneratedwhenakeyisevictedformaxmemory)

AAliasforg$lshzxe,sothatthe"AKE"stringmeansalltheevents.

AtleastKorEshouldbepresentinthestring,otherwisenoeventwillbedeliveredregardlessoftherestofthestring.

ForinstancetoenablejustKey-spaceeventsforlists,theconfigurationparametermustbesettoKl,andsoforth.

ThestringKEAcanbeusedtoenableeverypossibleevent.

Eventsgeneratedbydifferentcommands

Differentcommandsgeneratedifferentkindofeventsaccordingtothefollowinglist.

DELgeneratesadeleventforeverydeletedkey.

RENAMEgeneratestwoevents,arename_fromeventforthesourcekey,andarename_toeventforthedestinationkey.

EXPIREgeneratesanexpireeventwhenanexpireissettothekey,oraexpiredeventeverytimesettinganexpireresultsintothekeybeingdeleted(seeEXPIREdocumentationformoreinfo).

SORTgeneratesasortstoreeventwhenSTOREisusedtosetanewkey.Iftheresultinglistisempty,andtheSTOREoptionisused,andtherewasalreadyanexistingkeywiththatname,theresultisthatthekeyisdeleted,soadeleventisgeneratedinthiscondition.

SETandallitsvariants(SETEX,SETNX,GETSET)generatesetevents.HoweverSETEXwillalsogenerateanexpireevents.

MSETgeneratesaseparatedseteventforeverykey.

SETRANGEgeneratesasetrangeevent.

INCR,DECR,INCRBY,DECRBYcommandsallgenerateincrbyevents.

INCRBYFLOATgeneratesanincrbyfloatevents.

APPENDgeneratesanappendevent.

LPUSHandLPUSHXgeneratesasinglelpushevent,eveninthevariadiccase.

RPUSHandRPUSHXgeneratesasinglerpushevent,eveninthevariadiccase.

RPOPgeneratesanrpopevent.Additionallyadeleventisgeneratedifthekeyisremovedbecausethelastelementfromthelistwaswww.baiyuewang.netpopped.

LPOPgeneratesanlpopevent.Additionallyadeleventisgeneratedifthekeyisremovedbecausethelastelementfromthelistwaspopped.

LINSERTgeneratesanlinsertevent.

LSETgeneratesanlsetevent.

LREMgeneratesanlremevent,andadditionallyadeleventiftheresultinglistisemptyandthekeyisremoved.

LTRIMgeneratesanltrimevent,andadditionallyadeleventiftheresultinglistisemptyandthekeyisremoved.

RPOPLPUSHandBRPOPLPUSHgenerateanrpopeventandanlpushevent.Inbothcasestheorderisguaranteed(thelpusheventwillalwaysbedeliveredaftertherpopevent).Additionallyadeleventwillbegeneratediftheresultinglistiszerolengthandthekeyisremoved.

HSET,HSETNXandHMSETallgenerateasinglehsetevent.

HINCRBYgeneratesanhincrbyevent.

HINCRBYFLOATgeneratesanhincrbyfloatevent.

HDELgeneratesasinglehdelevent,andanadditionaldeleventiftheresultinghashisemptyandthekeyisremoved.

SADDgeneratesasinglesaddevent,eveninthevariadiccase.

SREMgeneratesasinglesremevent,andanadditionaldeleventiftheresultingsetisemptyandthekeyisremoved.

SMOVEgeneratesansremeventforthesourcekey,andansaddeventforthedestinationkey.

SPOPgeneratesanspopevent,andanadditionaldeleventiftheresultingsetisemptyandthekeyisremoved.

SINTERSTORE,SUNIONSTORE,SDIFFSTOREgeneratesinterstore,sunionostore,sdiffstoreeventsrespectively.Inthespecialcasetheresultingsetisempty,andthekeywheretheresultisstoredalreadyexists,adeleventisgeneratedsincethekeyisremoved.

ZINCRgeneratesazincrevent.

ZADDgeneratesasinglezaddeventevenwhenmultipleelementsareadded.

ZREMgeneratesasinglezremeventevenwhenmultipleelementsaredeleted.Whentheresultingsortedsetisemptyandthekeyisgenerated,anadditionaldeleventisgenerated.

ZREMBYSCOREgeneratesasinglezrembyscoreevent.Whentheresultingsortedsetisemptyandthekeyisgenerated,anadditionaldeleventisgenerated.

ZREMBYRANKgeneratesasinglezrembyrankevent.Whentheresultingsortedsetisemptyandthekeyisgenerated,anadditionaldeleventisgenerated.

ZINTERSTOREandZUNIONSTORErespectivelygeneratezinterstoreandzunionstoreevents.Inthespecialcasetheresultingsortedsetisempty,andthekeywheretheresultisstoredalreadyexists,adeleventisgeneratedsincethekeyisremoved.

Everytimeakeywithatimetoliveassociatedisremovedfromthedatasetbecauseitexpired,anexpiredeventisgenerated.

Everytimeakeyisevictedfromthedatasetinordertofreememoryasaresultofthemaxmemorypolicy,anevictedeventisgenerated.

IMPORTANTallthecommandsgenerateeventsonlyifthetargetkeyisreallymodified.ForinstanceanSREMdeletinganon-existingelementfromaSetwillnotactuallychangethevalueofthekey,sonoeventwillbegenerated.

Ifindoubtabouthoweventsaregeneratedforagivencommand,thesimplestthingtodoistowatchyourself:

$redis-cliconfigsetnotify-keyspace-eventsKEA

$redis-cli--csvpsubscribe''__key__:''

Readingmessages...(pressCtrl-Ctoquit)

"psubscribe","__key__:",1

Atthispointuseredis-cliinanotherterminaltosendcommandstotheRedisserverandwatchtheeventsgenerated:

"pmessage","__key__:","__keyspace@0__:foo","set"

"pmessage","__key__:","__keyevent@0__:set","foo"

...

Timingofexpiredevents

KeyswithatimetoliveassociatedareexpiredbyRedisintwoways:

Whenthekeyisaccessedbyacommandandisfoundtobeexpired.

Viaabackgroundsystemthatlooksforexpiredkeysinbackground,incrementally,inordertobeabletoalsocollectkeysthatareneveraccessed.

Theexpiredeventsaregeneratedwhenakeyisaccessedandisfoundtobeexpiredbyoneoftheabovesystems,asaresulttherearenoguaranteesthattheRedisserverwillbeabletogeneratetheexpiredeventatthetimethekeytimetolivereachesthevalueofzero.

Ifnocommandtargetsthekeyconstantly,andtherearemanykeyswithaTTLassociated,therecanbeasignificantdelaybetweenthetimethekeytimetolivedropstozero,andthetimetheexpiredeventisgenerated.

BasicallyexpiredeventsaregeneratedwhentheRedisserverdeletesthekeyandnotwhenthetimetolivetheoreticallyreachesthevalueofzero.

献花(0)
+1
(本文系thedust79首藏)