Redis学习
基础学习网站:https://www.runoob.com/redis/redis-lists.html
1. 常用数据结构
-
String
使用命令:set key value
-
hash
使用命令:hmset key field value
-
list
使用命令:lpush key value
-
set
使用命令:sadd key value
-
zset
使用命令:zadd key 1 value
2. String类型
2.1 命令
-
set:单次set
-
mset:批量set
-
get:单次get
-
mget:批量get
-
del:删除
-
expire:设置过期时间
-
incr:key存储数字值+1
-
decr:key存储数字值-1
-
incrby:key存储数值+1,获取
-
decrby:key存储数值-1,获取
2.2 使用
2.2.1 缓存对象
set user:1 value(JSON序列化)
mset user:1:name xx user:1:address shanghai(每个字段缓存,类似于hashmap的方法,有利于修改)
2.2.2 分布式锁
setnx product:1 true
set product:1 true ex 10 nx
NOTE:setnx无记录才会更新
释放锁:
del product:1
使用方式最简单的方式:
A. SETNX product:1 true
B. 查询库存
C. 减库存
D. del product:1
2.2.3 web应用的token和session
2.2.4 分布式系统的全局序列号
使用incrby获取一批序列号,然后在内存里面慢慢消耗使用,减少redis的瓶颈
解决思路:
获取序列号,放在count里面,然后和生成的作比较
为了防止多线程问题,这个可以做AtomicInteger来保证原子操作
超过了count的数量,那就去redis获取
为了保证长度可以用StringUtils.leftPad(str,length,pad)
3. Hash类型
3.1 命令
-
Hset key field value
-
Hsetnx key filed value
-
hmset key filed1 value1 filed2 value [filed value ...]
-
hmget key filed
-
hdel key filed [filed ...]
-
hlen key //返回哈希表中key中的field数量
-
hgetall key //返回哈希表中所有的键值
-
Hincreby key filed increment //为hash表中key的filed值增加increment
3.2 使用
3.2.1 缓存对象
3.2.2 购物车
3.3 优缺点
优点:
数据归类管理,方便数据管理
相比String操作消耗内存和CPU少
节省存储空间
缺点:
过期功能只能设置在key上,不能设置到field
Redis集群架构不适合大规模使用
数据分片是根据key来的,会在落在同一个slot卡槽里面,压力大
4. List类型
4.1 命令
-
LPUSH key value [value]
-
RPUSH key value [value]
-
LPOP key
-
RPOP key
-
Lrange key start stop //返回一个区间的元素,偏移量是start和stop决定的
-
BLPOP key [key...] timeout //从key列表弹出一个元素,没有元素的话等待timeout时间,一直阻塞等待
-
BRPOP key [key...] timeout //从key尾部弹出一个元素,没有元素的话等待timeout时间,一直阻塞等待
4.2 应用
4.2.1 栈
LPUSH+LPOP:FILO,先进后出
4.2.2 队列
LPUSH+RPOP:FIFO,先进先出
4.2.3 阻塞队列
消息也可以这样实现,LPUSH + BRPOP:消息进入队列,然后通过阻塞查询搞定
4.2.4 微博微信消息流
1)A发消息,消息Id 10008
LPUSH msg:{userId} 10008
2)B发消息,消息Id 10009
LPUSH msg:{userId} 100009
3)查看最新的几条消息
LRANGE msg:{userId} 0 5
5. Set类型
5.1 命令
-
SADD key member [member ...]
-
SREM key menber [member ...]
-
SMEMBERS key //获取集合key中所有元素
-
SCARD key //获取集合中key元素个数
-
SISMEMBER key member //判断元素属不属于这个Set
-
SRANDMEMBER key [count] //从set中获取count个参数,并且不删除
-
SPOP key [count] //从set中选出count个元素,并且删除
运算操作:
-
SINTER key [key ...] //交集运算
-
SINTERSTORE destination key [key ...] //交集结果放入destination
-
SUNION key [key ...] //并集运算
-
SUNIONSTORE destination key [key ...] //并集结果放入destination
-
SDIFF key [key ...] //差集计算
-
SDIFFSTORE destination key [key ...] //差集结果放入destination
5.2 应用
5.2.1 微信抽奖
-
sadd key {userid} //参与抽奖
-
smembers key //参与抽奖的所有用户
-
srangemember key count //抽取用户
5.2.2 点赞功能
-
sadd msg {userId}
-
srem msg {userId}
-
sismember msg {userid} //查看是不是点赞过
-
smembers msg //点赞人数
-
SCAED msg //点赞个数
5.2.3 关注的人是不是也关注了你(互关)
sismember like:{userid} yourId
5.2.4 共同关注的人
sinter like:{yourid} like:{userId}
Note:5.2.3、5.2.4都是运算的操作
其他应用
-
附近的人参考文章
要点就是geohash和zset实现的
geoadd,georadios都是之后的插件加入的,最终都是通过hash经纬值然后geohash一下存储到zset中,然后通过member之类的命令实现的
-
bloomFilter参考文章
布隆表达式,通俗的将就是有一个bit数组,然后通过n个hash散列算法,置位bit数组。最终判断的方式是再过来一个请求就通过n个hash算法去计算,看是不是数组位有值。这个不是100%准确性,会出现假阳性的现象。
redis的方法:bf.add,是一个插件
-
搜索匹配补全:参考文章
这个要点就是拆分字符串,如nba拆分成:n,nb,nba这三份,存放在sort set里面。
然后通过search的方式来获取匹配的,最后搞定