初步了解redis

redis介绍

Redis是一个开源的使用ANSIC语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

其中value可以为string、hash、list、set、zset五种数据结构。

还提供了键过期,发布订阅,事务,等附加功能

redis的数据类型一、字符串(String)

String类型可以是:字符串(包括XML、JSON),还有数字(整形、浮点数),二进制(图片、音频、视频),最大不能超过MB

设置一个字符串型的valueset

.0.0.1:setkeyvalue[EXseconds

PXmilliseconds

EXATtimestamp

PXATmilliseconds-timestamp

KEEPTTL][NX

XX][GET]EXseconds--Setthespecifiedexpiretime,inseconds.PXmilliseconds--Setthespecifiedexpiretime,inmilliseconds.EXATtimestamp-seconds--SetthespecifiedUnixtimeatwhichthekeywillexpire,inseconds.PXATtimestamp-milliseconds--SetthespecifiedUnixtimeatwhichthekeywillexpire,inmilliseconds.NX--Onlysetthekeyifitdoesnotalreadyexist.XX--Onlysetthekeyifitalreadyexist.KEEPTTL--Retainthetimetoliveassociatedwiththekey.GET--Returntheoldvaluestoredatkey,ornilwhenkeydidnotexist.

查看key的剩余过期时间ttl

.0.0.1:setkey1value1ex20OK.0.0.1:ttlkey1(integer)17.0.0.1:ttlkey1(integer)13.0.0.1:ttlkey1(integer)8.0.0.1:ttlkey1(integer)3.0.0.1:ttlkey1(integer)0.0.0.1:ttlkey1(integer)-2

key不存在时才设置valuesetnx

.0.0.1:setnxkey2value2(integer)1.0.0.1:setnxkey2value2(integer)0.0.0.1:getkey2"value2"等同于.0.0.1:setkey1value1nxOK.0.0.1:setkey1value1nx(nil).0.0.1:getkey1"value1"

批量命令msetmget

.0.0.1:msetkey3value3key4value4OK.0.0.1:mgetkey1key2key3key41)"value1"2)"value2"3)"value3"4)"value4"

数学计算incrdecrincrbydecrby

.0.0.1:incrkey5(integer)1.0.0.1:incrkey5(integer)2.0.0.1:decrkey5(integer)1.0.0.1:incrbykey53(integer)4.0.0.1:decrbykey52(integer)2.0.0.1:getkey5"2"

字符串操作appendstrlengetrange

.0.0.1:setkey6value6OK.0.0.1:strlenkey6(integer)6.0.0.1:appendkey(integer)9.0.0.1:getrangekey""二、哈希(hash)

哈希hash是一个string类型的field和value的映射表,hash特适合用于存储对象。

常用命令

.0.0.1:hsethkey1id1namechungeage18#可以批量设置field(integer)3.0.0.1:hgethkey1age#取某个field的值"18".0.0.1:hkeyshkey1#显示所有field字段1)"id"2)"name"3)"age".0.0.1:hdelhkey1name#删除一个字段(integer)1.0.0.1:hexistshkey1name#判断字段是否存在(integer)0.0.0.1:hvalshkey1#显示所有的字段值1)"1"2)"18".0.0.1:hgetallhkey1#显示所有的字段和值1)"id"2)"1"3)"age"4)"18".0.0.1:hsethkey1namechunge#单独设置field(integer)1.0.0.1:hincrbyhkey1age2#给字段增加数值(integer)20.0.0.1:hlenhkey1#返回字段数量(integer)3.0.0.1:hgetallhkey11)"id"2)"1"3)"age"4)"20"5)"name"6)"chunge".0.0.1:三、列表(list)

用来存储多个有序的字符串,一个列表最多可存

个元素,元素可以重复。

常用操作

.0.0.1:lpushlkey1cba#从左侧插入元素(integer)3.0.0.1:rpushlkey1ef#从右侧插入元素(integer)7.0.0.1:lrangelkey#返回列表key中指定区间内的元素,区间以偏移量start和stop指定。1)"a"2)"b"3)"c".0.0.1:lrangelkey10-1#可以使用负数下标,以-1表示列表的最后一个元素,-2表示列表的倒数第二个元素。1)"a"2)"b"3)"c"4)"e"5)"f".0.0.1:linsertlkey1beforeed#将值value插入到列表key当中,位于某值之前或之后。(integer)6.0.0.1:lrangelkey10-11)"a"2)"b"3)"c"4)"d"5)"e"6)"f".0.0.1:llenlkey1#返回列表key的长度。(integer)6.0.0.1:lsetlkey13ddd#将下标为3的元素的值设置为ddd。OK.0.0.1:lrangelkey10-11)"a"2)"b"3)"c"4)"ddd"5)"e"6)"f".0.0.1:lpoplkey11#左侧弹出一个元素1)"a".0.0.1:rpoplkey11#右侧弹出一个元素1)"f".0.0.1:lrangelkey10-11)"b"2)"c"3)"ddd"4)"e".0.0.1:rpoplpushlkey1lkey2#在一个原子时间内,执行两个动作:"e"#1、弹出lkey1最后元素并返回结果,2、同时写入到lkey2中.0.0.1:lrangelkey10-11)"b"2)"c"3)"ddd".0.0.1:lrangelkey20-11)"e".0.0.1:ltrimlkey#对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,OK#不在指定区间之内的元素都将被删除。.0.0.1:lrangelkey10-11)"b"2)"c"四、集合(set)

保存多元素,与列表(list)不一样的是不允许有重复元素,且集合是无序,一个集合最多可存

个元素。

除了支持增删改查,还支持集合交集、并集、差集;

常用命令

.0.0.1:saddskey1abcd#将一个或多个元素加入到集合当中(integer)4.0.0.1:scardskey1#返回集合key的基数(集合中元素的数量)。(integer)4.0.0.1:smembersskey1#返回集合key中的所有成员。1)"d"2)"b"3)"a"4)"c".0.0.1:sismemberskey1a#判断元素是否集合key的成员。(integer)1              #存在返回1.0.0.1:sismemberskey1e(integer)0              #不存在返回0.0.0.1:saddskey2cdefg(integer)7.0.0.1:sunionskey1skey2#返回集合的并集1)"g"2)"f"3)"c"4)"e"5)"d"6)"b"7)"a".0.0.1:sdiffskey1skey2#返回集合的差集1)"a"#skey1减去skey2剩下a,b2)"b".0.0.1:sdiffskey2skey1#skey2减去skey1剩下g,f,e1)"g"2)"f"3)"e".0.0.1:sinterskey1skey2#返回集合的交集1)"d"2)"c".0.0.1:sremskey1a#移除一个元素(integer)1.0.0.1:smembersskey11)"d"2)"b"3)"c".0.0.1:smoveskey1skey2b#把b元素从skey1移动到skey2(integer)1.0.0.1:smembersskey11)"d"2)"c".0.0.1:smembersskey21)"f"2)"g"3)"c"4)"e"5)"b"6)"d".0.0.1:spopskey22#从集合中随机返回并移除2个元素1)"g"2)"d".0.0.1:smembersskey21)"f"2)"c"3)"e"4)"b"五、有序集合(zset)

有得分,可以排序的set。

常用命令

.0.0.1:zaddzkeya5b6c7d8e9f11g12i#把一个或多个有分值的元素加到集合中(integer)8.0.0.1:zrangezkey10-1#查看集合中的元素,从第一个(0)到导数第一个(-1)1)"b"2)"c"3)"d"4)"e"5)"f"6)"a"7)"g"8)"i".0.0.1:zrangezkey10-1withscores#查看集合元素,同时显示分数1)"b"2)"5"3)"c"4)"6"5)"d"6)"7"7)"e"8)"8"9)"f"10)"9"11)"a"12)"10"13)"g"14)"11"15)"i"16)"12".0.0.1:zincrbyzkey13c#增加元素c的得分,加3分"9".0.0.1:zaddzkeyi#修改元素i的得分,改成10分(integer)0.0.0.1:zrangezkey10-1withscores#修改之后排序发生了变化1)"b"2)"5"3)"d"4)"7"5)"e"6)"8"7)"c"8)"9"9)"f"10)"9"11)"a"12)"10"13)"i"14)"10"15)"g"16)"11".0.0.1:zrevrangezkey10-1#倒序显示元素1)"g"2)"i"3)"a"4)"f"5)"c"6)"e"7)"d"8)"b".0.0.1:zrangebyscorezkey#查询分值在8到10之间的元素1)"e"2)"c"3)"f"4)"a"5)"i"我们可能遇到的问题慢查询

10.1.6.:slowlogget1)1)(integer)#唯一id2)(integer)#慢查执行的时间,时间戳3)(integer)#查询执行时间,以微秒为单位4)1)"keys"#具体执行的命令2)"*cdd05c44a1b5cf3dc6af9*"5)"10.1.6.:"#客户端IP和端口6)""#客户端名称2)1)(integer))(integer))(integer))1)"keys"2)"*threads_stat*"5)"10.1.6.:"6)""10.1.6.:configgetslow*#查看慢查配置1)"slowlog-log-slower-than"#代表慢查询的阈值,单位为:微秒。                  #当执行查询命令消耗时间大于配置的阈值时,会将该条命令记录到慢查询日志。                  #slowlog-log-slower-than=0时,记录所有命令。                  #slowlog-log-slower-than0时,不记录任何命令。2)""#slowlog-log-slower-than的默认值为(10毫秒)。3)"slowlog-max-len"        #代表慢查询日志最大条数。它是一个队列形式的存储结构,先进先出的队列.                  #slowlog-max-len的默认值为)""              #保存在内存内,所以重启redis会清空慢查询日志。.0.0.1:debugsleep1#模拟一个耗时1秒的命令OK(1.01s).0.0.1:slowlogget1)1)(integer)02)(integer))(integer))1)"debug"2)"sleep"3)"1"5)".0.0.1:"6)""缓存穿透

描述

缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。

这时的用户很可能是攻击者,攻击会导致数据库压力过大。

解决

1、将key--null写入缓存,同时缩短缓存时间;

2、使用布隆过滤器

缓存雪崩、缓存击穿

描述

两个概念类似,是单key和多key的区别;

击穿:如果一个key是热点数据,当期缓存时间到期时那一刻,大量数据同时涌入,对数据库造成压力。

雪崩:大量key在同一时间到期,导致数据库的压力突然增大。

解决

对于雪崩,可以考虑不同的key设置不同的到期时间,尽量均匀,防止同时到期;

对应击穿,两种方式,一是热点数据,缓存永不过期;二是使用互斥锁,到期后,确保已有一个线程去查数据库。

应用场景分布式锁(string)

//伪代码--加锁publicbooleanlock(StringlockKey,Stringid,longtimeout){Longstart=System.currentTimeMillis();  for(;;){//SET命令返回OK,则证明获取锁成功Stringlock=jedis.set(lockKey,id,"EX","NX"timeout);//加过期时间,防止死锁if("OK".equals(lock)){returntrue;}//否则循环等待,在timeout时间内仍未获取到锁,则获取失败longl=System.currentTimeMillis()-start;if(l=timeout){returnfalse;}Thread.sleep();}}//伪代码--解锁publicvoidunlock(StringlockKey,Stringid){if(id.equals(jedis.get(lockkey))){//确保是锁的持有者,在进行解锁jedis.del(lockkey)}}

!!不要使用上面这种方式做!!

推荐使用框架,比如redission



转载请注明地址:http://www.sanbaicaoasb.com/sczz/8380.html
  • 上一篇文章:
  • 下一篇文章: 没有了
  • 热点文章

    • 没有热点文章

    推荐文章

    • 没有推荐文章