一、redis的应用场景
缓存数据特点:访问频繁、相对稳定不易变化或者存在过期、分布式一致性等特性的数据;
举例:
- 短信、摘要、文章等各类模板;
- 登陆验证码;
- 频繁查询的sql:如状态机中根据当前状态和事件码查询下一个状态;
- 分布式锁;
二、memcache和redis的比较
- memcache只支持string,Redis支持多种数据结构的存储;
- memcache可以存储图片、视频等资源;
- 存储数据安全-memcache挂掉后,数据没了;redis可以定期保存到磁盘(持久化);
- memcache取value中的某个数据,需要将整个value取出来然后通过代码去解析出来;redis可以通过redis提供的数据结构方法来获取,无需再写代码。这样的好处是:如果value很大的情况下,可以避免server的读写IO和网卡IO出现瓶颈,以及节省应用的代码编写;所以,redis支持多种数据类型不是重点,重点是这些类型所提供的方法让redis变的好用。
三、redis的数据类型
1、String(字符串、数值、bitmap位图)
1)字符串常见操作:
redis-cli -h -p -n:客户端连接;
keys *;匹配所有符合条件的key;
STRLEN key:查看value字节长度;
set:设置key value
set key value nx|xx:nx,为空才能设值,意思只能新增值不能更新值;xx:不为空才能设置值即只能更新值不能新建值
setnx key value:等价于set key value nx为空才能设值。
setex key seconds value:设置值并指定过期时间,也可以写作:set key ex seconds或者set key value;expire key seconds;
get key:获取value;
del key:删除key;
GETSET key newValue:设置新值返回老值;
mset key1 value key2 value:同时设置多个值
mget key1 key2:同时获取多个key的值
type:返回value的类型(决定了适用哪些方法,string则适用string的方法,否则报错误类型异常)
append key value:往value后面追加值
SETRANGE key offset:从指定下标开始替换值
GRTRANGE key start end:从下标start开始取到end下标,redis为左闭右闭
OBJECT ENCODING key:返回value的编码类型(embstr、int、raw)
2)数值常见操作:
INCR key:如果value编码类型为int,则加1;
INCRBY key num: 如果value编码类型为int,则加给定的num数值;
DECR key:如果value编码类型为int,则减1;
DECRBY key num: 如果value编码类型为int,则减去给定的num数值;
INCRBYFLOAT key *.*: 如果value编码类型为数值,则加给定的浮点数值;
3)redis是二进制安全的:存的是字节而不是字符;二进制安全指的就是数据在写入是什么样,那么读取就是什么样。
4)bitmap常见操作:
setbit key offset value:第几个二进制位设值;999
bitpos key bit start end:返回给定的二进制bit在value中给定字节区间start和end中第一次出现的位置;如set k1 A@; bitpos k1 1 0 0;则返回1,因为A@的二进制表示为0100 0001 0100 0000;bitpos k1 1 1 1;则返回9;
bitcount key start end:在字节区间内1出现的次数;set k1 A@; bitcount k1 1 0 0;则结果是2,bitcount k1 1 0 0;则结果是3。
bitop operation destkey key1 key2...:将多个key对应的value做位运算后存到destkey。如bitop and andkey k1 k2:将k1和k2做位运算后放到andkey,get andkey得到与运算后的结果。
常见面试题:用户登陆统计
setbit huqiang 1 1;
setbit huqiang 2 1;
setbit huqiang 365 1;
问题:huqiang用户一年登陆了多少次?bitcount huqiang 0 -1
常见面试题:京东618登陆用户送1礼物,假设京东2亿用户,则需要备货多少礼物?
分析:客户分为活跃用户、僵尸用户、忠诚用户
设计:可以以365天为key,然后将2亿用户对应到bit的一个位置;最后做或运算,同一位置代表同一个用户,同一个位置多次出现1,就看成1即日期区间内登陆过。所以只需统计去年同期活跃用户数即可;
key为1年365天日期,用户为value的某个二进制位,想要统计某个日期区间的活跃用户数量,则
setbit 20210901 9 1; 比如第9位代表肖恩这个用户,设置为1则表示20210901这天肖恩登陆了
setbit 20210902 1 1;
bitop or activeuser 20210901 20210902;或合并运算后的结果表示这两天区间内所有用户的登陆情况;
bitcount activeuser 0 -1 ;统计有多少个1,即有多少个用户登陆过;
5)字符集:
标准的是字符集是:ascii,规则高位为0
其余的都是扩展字符集如:UTF-8,gbk2312;不再对ascii重编码,都是高位为1,然后去机器里面找对应的字符返显。所以所有机器都认识ascii码而不一定认识扩展字符集编码,即ascii码对应的字符永远不会乱码;
2、list
1)常见操作:
lpush key value1 value2 ...:从左边压入value1、value2...
lpop key:从左边弹出,先进后出,所以先弹出value2,后弹出value1;类似于栈;
rpush key value1 value2:从右边压入value1、value2;
rpop key:从右边弹出,先进后出,所以依然是先弹出value2,再弹出value1;
总结规律:同向压入和弹出,类似于栈;反向操作压入和弹出,则类似于队列(先进先出);
lrange key start end:从下标取元素;
lindex key index:取下标对应元素;
lset key index:根据下标设置元素;
lrem key count rmvalue:移除指定的rmvalue元素count次,count如果为正数,则从左边开始移除,count如果为负数则从右边开始移除;
linsert key before|after value newvalue:在第一个指定元素value前面或者后面插入值newvalue;
blpop key:阻塞取值;
ltrim key start end:取掉start和end外的所有元素;
3、hash
1)hash的应用场景:如果想要存储一条关系型记录,如果按照string去存取的话,可以set john::name john;set john::age 18;set john::score 80;如果要取john的所有信息,则需要通过keys john*;然后遍历或者mget去取所有的值;keys模式匹配命令比较耗费成本,所以引入hash类型;
2)常见操作:
hset key field value:设置值,如hset john age 18;
hmset key field value field value...:同时设置多个键值对;
hget key field:
hmget key field field ...:
hkeys key:获取key所有的field;
hvals key:取出key所有的value;
hgetall key:取出key所有的键值对;
4、set
1)与list区别:无序,不可重复(很重要,可以用于去重)
2)常见操作:
sadd key member member ...:添加set集合元素;
smemners key:拿到所有的元素
srem k1 member:移除集合元素;
sinter key key key ...:取多个set的交集;
sinterstore destkey key key:取多个set的交集并放到新的destkey集合里面;
sunion key key key ...:取多个set的并集;
sunion destkey key key:取多个set的并集并放到新的destkey集合里面;
sdiff key1 key2 ...:取多个set的差集;key1减去k2
sdiff destkey key1 key2:取多个set的并集并放到新的destkey集合里面;
srandmembers key count:随机取count个元素返回,如果是正数且count超过最大长度,则返回所有元素,为正数情况取出元素不会重复,如果count为负数,则返回count个元素且可能存在重复元素;(使用场景:抽奖规则:如奖品数量固定的情况下100个,用户数量不确定,中奖人可重复或者不可重复)
spop key:随机取出一个元素
5、sorted set有序集
1)这里指的是值的大小顺序而非插入顺序,与list说的添加顺序含义不同
2)常见操作:
zadd key score value score value score value:添加成员,并且必须给出排序所依据的分值;
zrange key start end:给出下标start到end的值;
zrange key start end withscores:给出下标start到end的值并带上它们的分数;
zrangebyscore key minscore maxscoer:按分值区间(左右包含)去取;
zscore key value:取出value对应的分值;
zrank key value:取value在集合中的排名;
zincrby key increment value:给某个value增加分值;
zunionstore deskey num key1 key2... weight w1 w2...(缺省都是1) aggregate max|min|sum(默认是sum):合并多个集合,可以指定权重和聚合规则;
3)排序的实现:skip list(跳跃表)-> 提升添加成员的速度;