




版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
文章来源 整理补充:redis之环境搭rediskey-valuevaluestring类型还有list,setsortedsethashstring操作。比如对一个字符value追加字符串(APPEND命令)。加加或者减减一个数字字符串(INCRset(intersectionuniondifference)。memcache也有类似与一样为了性能,redisredis可以每间隔一定时间将内存中数据写入到磁盘以防止数据丢失。redis也支持主从机制(master-slavereplication)。redis的其他特性地址 /files/redis-2.0目前 稳定$tar$tarxzfredis-$cdredis-$make完后redis-2.0.4 下面启动redis服务redis.conf是一个默认的配置文件。我们可以根据需要使用自己的配启动redis服务进程后,就可以使用测试客户端程序redis-cli和redis服务交互了.$$./redis-cli没linux的可以通过这个的来练习,当然版的很多管理相关令是不支持的。 java /downloads/alphazero/jredis/jredis-1.0-版本目前有点老,支持到Redis1.2.6。版2.0的还没 o,world程importorg.jredis.*;publicclassApp{{tryJRedisjrnewJRedisClient("5",6379redis服务地址和端Stringkey="mKey"; Stringv=newStringk2="count";}catch(Exceptione)//TODO:handle}}}redis之数据类redisstring,list,set,sortedsethashkeykeybinarysafe的字符串,所以像"mykey"和"mykey\n"这样包含边界字符当成的key吧,免得被bug纠缠。另外关于key的一个格式约定介绍下,object-type:id:field。比如user:1000:password,blog:xxidxx:title,还key的长度最好不要太长。道理很明显占内存啊,而且查找时候相对短key也更慢。不过也不推荐过短的key,比如u:1000:pwd,这样的。显然没上面的user:1000:password可读性好。 无序集合类型redis>keysredis>keysredis>keys失败。可能是oldkey不存在或者和newkey相同
返回设置过过期时间的key的剩余过期秒数-1key不存在或者没有设置过过期时间示成功,0stringstringredis最基本string类型是二redisstring可以包含任何数据。比如jpg或者序列化的对象。从实现来看其实string可以看作byte数组,最大上限是1G字节。下面是string类型的定义。struct{longlen;longfree;charbuf[];buf是个char数组用于存贮实际的字符串内容。其实char和c#中的byte是等价的,都安全的了。因为它本质上就是个byte数组。当然可以包含任何数据了。另外string类型可以被部分命令按int处理.比如incr等命令,下面详细介绍。还有redislist,set,sortedsethash它们包含的元素与都只能是string类型。的操作比memcached多很多啊。如下:同上,如key已经存在,返回0。nxnotexist的意思下面是个实验,首先清空当前数据库,然后设置k1,k2.获取时k3对应返回nil.redis>dbsize(integer)0redis>mgetk1k20
个不存在的key,则设置key为1rincrkeykeyvaluerredis>redis>setoredis>appendk,world(integer)11redis>getk redis>substrk08 redis>getk list类redisliststring类型的双向链表。所以[lr]push和[lr]pop命令的算法时间复杂度都是O(1)。另外list会记录链表的长度。所以llen操作也是O(1).链表的最大长当然可以加超时时间,超时后也会返回nil。有任务存在。当任务来时候工作线程可以立即返回,也可以避免轮询带来的延迟。oklistkeylist中指定下标的元素值,成功返回1,key或者下标不存在返回错误果key对应值不是list返回错误listtimeout秒,timeout0表示一直阻塞。当阻塞时,如果有如果超时发生,则返回nil。有点像unixselectpoll。从srckey对应list的尾部移除元素并添加到destkey对应list的头部,最后返回被移除的元素值,整个操作是原子的.如果srckey是空或者不存在返回nil。setredissetstring类型的无序集合。set元素最大可以包含(232次方-1)个元素。set的是通hashtableO(1)。hashtable会随着添加或者删除自可能不久后就会改用跳表(skiplist)来实现,跳表已经在sortedset中使用了。(intersection),差集(difference)。通过这些操作可以很容易的实现sns中的好友推荐和blog的tag功string元素到,key对应的set1,如果元素已经在集合中返回0,key对应的set不存在返回错误setsetkey0
key返回所有给定key的并集返回所有给定key的差集keyset的所有元素,结果是无序的sortedsetset一样,sortedsetstring类型元素的集合,不同的是每个元素都double类型score的被添加到hashtable中,所以给定一个元素获取score的开销是O(1),另一个score到元素的被添加到skiplist并按照score排序,所以就可以有序的获取集合中的元素。添加,删除操作O(log(N))skiplist的开销一致,redisskiplist实现用的是双向链表,这样就可以逆序从尾部取元素。sortedset最经常的使用方式应该是作为索引来使用。我们可以把要排序的字段作为score,对象的id当元素。memberscoreskiplist保持有序。返score同上,但是集合中元素是按score从大到小排序同上,返回结果是按score逆序的返回集合中score在给定区间的数量 删除集合中在给定区间的元素hashredishash是一个string类型的field和value的表它的添加,删除操作都是O(1)平均.hash特别适合用于对象。相较于将对象的每个字段存成单个string类型。将一个对象在hash类O(n),但是由于一般对象的field数量都不太多。所以使用zipmap也是很快的,也就是说添加删除平均还是O(1)。如果field或者value的大小超出一定限制后,redis会在自动将zipmap替换成正常的hash实现.这个限制可以在配置文件中指定。#下面介绍hash相关命令获取指定的hashfieldhashfiled加上给定值测试指定field是否存在返回hash的所有field排序。排序命令是sort完整令格式如下:SORTSORTkey[BYpattern][LIMITstartcount][GETpattern][ASC|DESC][ALPHA][STOREsortredis>lpushredis>lpushml12(integer)1redis>lpushml11(integer)2redis>lpushml23(integer)3redis>lpushml13(integer)4redis>sort.[ASC|DESC]desc选项,想按字母顺序排可以加alpha选项,当然alphadesc一起用。下面是个按字母顺序排的例子redis>redis>lpushmylistbaidu(integer)1redis>lpushmylist (integer)2redis>lpushmylistxhan(integer)3(integer)4redis>sort redis>sortmylist redis>sortmylistdesc [BY并按照新key中对应的内容进行排序。下面的例子接着使用第一个例子中的ml集合做演示:redis>sortmlby.序的,[这个例子加上alpha,更容易理解]当然返回的还是排序后ml集合中的元素。[GETredis>sortmlbyname*getname*redis>sortmlbyname*getname*name12name13name23name23get选项可以有多个。看例子redis>redis>sortmlbyname*getname*get redis>redis>hsetuser1namehanjie(integer)1redis>hsetuser11namehanjie(integer)1redis>hsetuser12name86(integer)1redis>hsetuser13namelxl(integer)1redis>sortmlgetuser*-[LIMITstart上面例子返回结果都是全部。limit选项可以限定返回结果的数量。例子redis>redis>sortmlgetname*limit1[STOREredis>sortmlgetname*limit12storecl(integer)2redis>sortmlgetname*limit12storecl(integer)2redis>lrangecl0-功能介绍完后,再下关于排序的一些问题。如果我们有多个redisserver的话,不同的key可能存在于不同的server上。比name12name13name23name23,很有可能分别在四个不serverkey,都这样命名[name]12name]13name]11name]23client程序就会把他们都放到同一server上。还有一个问题也比较严重。如果要sort的集合非常大的话排序就会消耗很长时间。由于redis单制到多个slave上。然后我们只在slave上做排序操作。并进可能的对排序结果缓存。另外就是一个方案是就是采用sortedset对需要按某个顺序的集合建立索引。sadd sadd sadd sadd setuid:sort:123setuid:sort:456setuid:sort:789setuid:sort:101setuid:123setuid:456setuid:789setuid:101sorttom:friend:listbyuid:sort:*getsorttom:friend:listbyuid:sort:*getuid:*getredis对事务的支持目前还比较简单。redis只能保证一个client发起的事务中令可以连续的执行,而中间不会其他client令。由于redis是单线程来处理所有client的请求的所以做到一般情况下redis在接受到一个client发来令后会立即处理并返回处理结果,但是当一个client在接中发出multi命令后,这个连接会进入一个事务上下文,该连接后续令并不是client.然后此连接就结束事务上下文。下面可以redis>redis>redis>incraincrbexec后我们可以调用discard命令来取消一个事务。接着上面redis>redis>redis>可以发现这次incraincrb都没被执行。discard命令其实就是清空事务令队列并退出事务上实现Redis事务中的CAS操作。生改变,那么整个事务将跳出,exec命令返回(nil)。下面看个例子redis>redis>1.redis>redis>除。当然了exec,discard,unwatch命令都会清除连接中的所有监视。 redis>lpushb5(integer)1redis>setc5redis>redis>(integer)(error)ERROperationagainstakeyholdingthewrongkindof(integer)另一个十分罕见的问题是,redis意外的挂了。很遗憾只有部分命令执行了,后面的也就被丢弃了。当然如果我们使用append-onlyfile方式持久化,redis会用单个writeredis之redis是一个cs模式的tcpserver使用和http类似的请求响应协议。一个client可以通过一个socketclientredis服务处理,redis处理完后请求命令后会将结果通过响应报文返回给client。基本的通信过程如下:Server:1Server:2Server:3Server:4基本上四个命令需要8tcp报文于通信会有网络延迟,假如从clientserver之间的包传输时间需0.125秒。那么上面的四个命令8个报文至少会需要1秒才能完成这样即使redis的方式从client打包多条命令一起发出,不需要等待单条命令的响应返回,而redis服务端会处理完Client:Client:INCRXClient:INCRXClient:INCRXClient:INCRXServer:1Server:Server:Server:假设不会因为tp个tp报文就能完成四条命令,lint可以将四个in个tp报一发送,erver则可以将四条命令的处理结果放到一个tp报文返回。通过pipeine方式当有大批量的操作时候。我们可以节省很多原来浪费在网络延迟的时间。需要注意到是用pipline方式打包命令发送,redis必须在处理完所有命前先缓存所有命令处理结。 打包 令越多,缓存消耗内存也越多。所以并是不是打包令越多越好。具体多少合适需要根据具体情况测试。packagejredisStudy;importpackagejredisStudy;importorg.jredis.JRedis;importimportpublicclassPipeLineTest{publicstaticvoidmain(String[]args)longstart=System.currentTimeMillis();longend=System.currentTimeMillis();start=System.currentTimeMillis();end=System.currentTimeMillis();}privatestaticvoid{tryJRedisjredis=newJRedisClient("5",6379);for(inti=0;i<100000;i++){}}catch(Exceptione)}}privateprivatestaticvoid{tryConnectionSpecspec=DefaultConnectionSpec.newSpec("5",6379,0,null);JRedisjredis=newJRedisPipelineService(spec);for(inti=0;i<100000;{}}catch(Exceptione)}}}104598redis之发布订这点和设计模式中的观察者模式比较相似。pub/sub不仅仅解决发布者和订阅者直接代码级别耦合也解决两者在物理部署上的耦合。redis作为一个pub/subserver,在订阅者和发布者之间起到了消息路由的功能。订阅者可以通过subscribe和psubscribe命令向redisserver订阅自己感的消息类型,clientclient可以订阅多个channel,也可以向多个channel发送消息。单的client。代码如下.*;importjava.io.*;publicclassPubSubTest{Stringcmd=args[0]+"\r\n";try{SocketsocketnewSocket("5",6379);InputStreamin=socket.getInputStream();OutputStreamout=socket.getOutputStream();out.write(cmd.getBytes());//发送订阅命令byte[]buffer=newwhile(true)intreadCount= System.out.write(buffer,0,readCount); }}catch(Exceptione)}}}然后进入while循环一直redisserver传过来订阅的消息。并打印到控制启动redis-Readingmessages...(pressCtrl-cto(integer)再启动一个redis-cliredis>redis>publishnews.share"sharealink (integer)redis>publishnews.blog"Iposta(integer)sharealinkIposta另一个redis-cli输出如"sharealink"Iposta"成功消息,可以看出redis的协议是文本类型的,这里不解释具体协议内容了,可以参考或者redisclient使用psubscribe订阅了一个使用通配符的通道(*表示任意字符串),此订阅会收到所有与news.*匹配的通道消息。redis-cli打印到控制台的订阅成功消息表示使用psubscribe命令news.*成功后,连接订阅通道总数为1clientpublishnews.sharenews.blog通道发出两个消息后。redis返回的看完一个小例子后应该对pub/sub功能有了一个感性的认识。需要注意的是当接通过subscribe或者psubscribe订阅通道后就进入订阅模式。在这种模式除了再订阅额外的通道或者用jredispub/sub支持,不过自己实现一个应该也挺简单的。整个应用程序可以共到消息后可以根据不同的通道信息去调用不同的callback来处理。另外个人觉得redis的pub/sub还是有点太单薄(实现才用150行代码)。在安全,认证,可靠证持久化。redis支持两种持久化方式,一种是Snapshotting(快照)也是默认方式,另一种是Append-onlyfile(缩写aof)的方式。下面分别介绍:默认的文件名为dump.rdb。可以通过配置设置自动做快照持久化的方式。save9001#9001keysave30010#30010keysave60onwrite)父子进共享相同的物理页面,当父进程处理写请求时os会为父进程要修改的页面创建fork时刻整个数据库的一个快照。rdis是用一个主线程来处理所有lintlint请求。所以不推荐使用。另一点需要注意的是,每次快照持久化都是将内存数据完整写入到磁盘一次,并io操作,可能会严重影响性能。后一次快照后的所有修改。如果应用要求不能丢失任何修改的话,可以采用aof持久化方式。Append-onlyaofaof持久化方式时,redis会将每一个收到的写write函数追加到文件中(appendonly.aof)redis重启时会通过重新执行文件中oswrite做的修改,所aof方式的持久化也还是有可能会丢失部分修改。不过我们可以是:每秒fsync一次)appendonly
appendfsync //完全依赖os,性能最好,持久化aofincrtest命令100次,文件中必须保存全部的100条命令,其实有99条都是多余的。因为要恢复数据库的状态其实文件中保存一条settest100就够为了压aof的持久化redis提供了bgrewriteaof命令。子进程根据内存中的数据库快照,往临时文件中写入重建数据库状态令用命令的方式重写了一个新的aof文件,这点和快照有点类似。redisM/Sserver相同的数据库副本。下面是关于redis主从的一些特点:主从不会阻塞master。也就是说当一个或多个slave与master进行初次同步数据时,如sort操作可以使用slave来处理,也可以用来做简单的数据冗余。在slave上配置数据持久化M/S下面介绍下主从的过程slave服务器后,slavemastersync命令。无论是第一次同步建立的连接还是连接断开后的重新连接,master都会启动一个进程,将数据库快照保存到文件中,同时master主进开始收集新的写命令并缓存起来。进程完成写文件后,master就发从master到slave的同步数据令和从client发送令使用相同的协议格式。当master和slaveslavemasterslave发来的同步连接命令,只会使用启动一个进程来写数据库镜像,然后发送给所有slave。M/Sslaveofslaveof6379#masteripredis之虚拟内尤其是对于redis这样的内存数据库,内存总是不够用的。除了可以将数据分割到多个redisserver外。另外的能够提高数据库容量的办法就是使用vm把那些不经常的的磁盘上。如果我们的的数据总是有少部分数据被经常,大部分数据很少被,对于来说确实总是只有少量用户经常活跃。当少量数据被经常时,使用vm不但能提高单台redisserver数据库的容量, osredisredislist,set可能存在与多个os页面有内存真正耗尽时os才会交换页面。指针和对象元数据信息。一般压缩后的对象会比内存中的对象小10倍。这redisvmosvm能少做很多io操作。VM vms134217728#最多使用在文件中使用多少页面,交换文件的大小=vmsize*vmsvaluekeyvmosredis也是按页面会选择较老的对象。如果两个对象一样老会优先交换比较大的对象,精确的公式swappability=对于vmsize的设置应该根据自己的应用将页面的大小设置为可以容纳大多数对象的大小。太大了会浪费磁盘空间,太小了会造成交换文件出现碎片。对于交换文件中的每个页面,redis会16M内存用来记录页面空闲状态。vm-max-threads表示用做交换任务的线程数量。如果大于0推荐设为服务器的cpucore的数量。如果是0则交换过程在主线程进行。vm-max-threads0时(Blocking件中,并对象占用的内存,此过一直重复直到下面条件满足:加载时此时会阻塞所有client,然后再处理client的请求。作线程处理,主线继续处理client请求。如果有client请求的key被换出了,主线阻塞发出命令的client,然后将加载对象的信息放这种方式只阻塞请求value被换出keyclient。blockingvm的方式。redisvm/post/redis-virtual-memory-随着SNS 随着SNS 的是MongoDb和Redis,因为单纯的Key-Value 杂的逻辑业务,仍这两个数据库分别加入了一些关系性的特性,如能有效利用会有很好的效果。zset是个非常好的 value(待)排序的元素)和score(用来排序的得分依据)。例如用来 榜,value可 用户的ID,而score则是该用户的关注数。 没有顺序的,排序计算是在获取的时候来做的.redisTopN外面的元素,保持例如一个需要发30名的榜,我们使用的时候可以保留500名的数据,防止需求变化。然后不断的往其中添加新数据,1000trim操作,将集合的元素数量压缩成500。当获取前30名的时候,同样用redis做一个缓存,缓存时间设成ps.的应用大家一起来补充吧Redis指令文 连接控制QUITAUTH(仅限启用时)简单的验适合全体类型EXISTSkey1;DELkeykey,key;DELkey1key2key3KEYSpatternkey(KEYSfoo*:fookeys)RENAMEoldnamenewnamekey的名字,新键如果存在将被覆盖SELECTindexMOVEkeydbindexdbindex1;0(源数据库不存在key或目标数据库已存在同名key);FLUSHDB清空当前数据库中的所有键处理字符串令SETkeyvalueSETkeynamedatalengthdata(SETbruce10paitoubing:GETSETkeyvaluekeySET(SETbruce10bruce101234567890)MGETkey1key2…keyN返回多个键的MSETkey1value1key2value2…keyNvalueN在一次原子操作下 MSETNXkey1value1key2value2…keyNvalueN在一次原子操作下 标键不存在情况下,如果有一个以上的key已存在,则失败)INCRkeyINCRBYkeyintegerDECRkeyDECRBYkeyinteger处理listsRPUSHkeyvalueList(KeyLPUSHkeyvalueListLLENkeyList012LTRIMkeystartend(LTRIMtestlist02;012LSETkeyindexvalue更新某个位置元素的值匹配value的元素,返回删除的元素数量。LPOPkeyListRPOPkeyListRPOPLPUSHsrckeydstkey_srckey__dstkey_头部,key处理集合(sets)令(有索引无序序列testlist3\none)3\None)SPOPkeySMOVE
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 安全用气手册3篇
- 出租车买卖条件3篇
- 工程代理人职责说明3篇
- 双方项目合作协议3篇
- 2025学前班班主任工作总结(15篇)
- 托管房屋租赁合同集锦(20篇)
- 高中语文作文教学中高阶思维训练的实证研究与效果分析
- 2024年新疆石河子国有资产经营有限公司岗位选聘考试真题
- 2024年神农架优抚医院招聘医疗卫生专业技术人员考试真题
- 浙江大学爱丁堡大学联合学院招聘笔试真题2024
- 研究性学习-鸡蛋上的物理学
- 妇科内分泌检查记录表
- 人工智能原理与方法智慧树知到课后章节答案2023年下哈尔滨工程大学
- 院前急救业务学习介绍课件
- 虎林市四平山金矿有限责任公司黑龙江省虎林市四平山岩金矿矿山地质环境保护与土地复垦方案
- 《春江花月夜》说课 统编版高中语文选择性必修上册
- 西政安徽校友会通讯录
- 2017沂源县新医药产业园区控制性详细规划
- 养老护理员第一章职业道德
- 动词三单专项练习
- GB/T 27007-2011合格评定合格评定用规范性文件的编写指南
评论
0/150
提交评论