认识Redis (基于Windows操作)
1.Redis安装
2.Redis 5大存储数据类型操作
- Redis-Key
set name ruobai #设置值
keys * #查询所有
move name 1 #移除当前数据库的name key
get name #获取key值
EXPIRE name 10 #设置过期时间
EXISTS name #判断当前key是否存在
ttl name #查看当前key剩余时间
type name #查看当前key数据类型
- String
作用:(1)计数器(2)统计多单位的数量(3)粉丝数(4)对象缓存存储
APPEND key1 "hello" #key1 后追加字符串
APPENd name "hello" #若key不存在相当于set key
STRLEN name #获得key的长度
set views 0 #设置访问量
incr views #views++
decr views #views--
INCRBY views 10 #设置自增步长10
DECRBY views 10 #设置自减步长10
GETRANGE name 0 3 #查看字符串【0,3】
GETRANGE name 0 3 #获取全部字符串
SETANGE name 1 "ruobai good" #替换指定位置开始的字符串
setex key3 30 "hello" #设置制定key和key的过期时间
setnx key3 "redis" #存在会创建失败,不存在再设置key(在分布式锁中会常常使用)
mset k1 v1 k2 v2 k3 v3 #批量设置值
mget k1 k2 k3 #批量获取值
msetnx k1 v1 k2 v2 k3 v3 k4 v4 #msetnx(有一个key存在就会失败)是一个原子性操作,要么都成功,要么都失败
`###################设置对象################`
set user:1 {name:zhangsan,age:3} #设置一个user:1对象,对象值为json字符来保存一个对象
mset user:1:name:zhangsan user:1:age:3 #设置一个user:1对象
mget user:1:name user:1:age #获取一个user:1对象
getset db redis #如果不存在值,则返回nil,如果不存在值则更新值
- List
作用:可以用作——堆、栈、队列
LPUSH list one #将一个多个值放到列表头部
LRANGE list 0 1 #获取list中的值
Rpush list righr #将一个多个值放到列表的尾部
Lpop list #移除list第一个元素
Rpop list #移除list最后一个元素
index list 0 #通过下标获取list中的某一个值
Llen list #获取list长度
Lrem list 1 three #移除一个叫three的值
Ltrim list 1 2 #通过下标截取list指定长度,只剩下截取的元素
`###################组合命令###############`
rpush list "hello"
rpoplpush list mylist #将list中首个值移动到mylist
lset list 0 item #设置指定下标的值(当前下标元素需要存在)——相当于更新操作
Linsert list before "three" "other" #精准插入
小结:list实际上是一个链表,before、Node、after、left、right都可以插入值
- 如果key不存在,创建新链表
- 如果key存在,新增内容
- 如果移除了所有值,空链表,也代表不存在
- 在两边插入或者改动值,效率最高!中间元素,相对来说效率会低一点
- Set
Set: (1)Set集合不包含重复元素(2)
sadd myset "hello" #set集合中添加匀速
SMEMBERS myset #查看置顶set的值
SISMEMBER myset hello #判断某个值是不是在set集合中
srem myset "hello" #移除set集合中的hello
scard myset #查看set集合中元素个数
SRANDMEMBER myset #随机抽取set集合中的一个元素
spop myset #随机删除一些set集合中的元素
smove myset myset2 "helo" #将myset中的hello移动到myset2
sdiff key1 key2 #key1 key2 做差集
sinter key1 key2 #key1 key2 做交集 (共同好友可以实现)
sunion key1 key2 #key1 key2 做并集
- Hash
Hash: Map集合:key-map时候是一个map集合!本质和String类型没有多大区别还是一个简单的key-value
hset myhash field1 ruobai #添加值
hget myhash field1 #获得值
hmset myhash field1 hello field2 world #添加多个值
hmget myhash field1 field2 #获取多个值
hgetall myhash #获取所有值
hdel myhash field1 #删除值
hlen myhash #获取hash长度
hexists myhash field1 #判断hash中是否存在制定字段
hkeys myhash #只获取所有的key
hvals myhash #只获得所有的value
hincrby myhash field3 1 #自增1
hdecrby myhash field3 -1 #自减1
hsetnx myhash field4 hello #如果不存在就添加,存在就不添加
hset user:1 name qingjiang #设置对象
- Z-Set
zadd salary 2500 xiaohong #添加有序数列salary
zrange myzset 0 -1 #获取所有值
zrangebyscore salary -inf +inf #从小往大排列
zrem salary xiaohong #移除元素
zcard salary #查看元素个数
zcount myset 0 2 #获取指定区间的成员数量
3.事务
原子性:全成功或全失败(redis)没有
1.Redis事务本质:一组命令的集合!一个事务中的所有命令都会被序列化,在事务执行过程中,会按照顺序执行!一次性、排他性、顺序性!执行一系列命令!
2.Redis事务中没有隔离级别的概念!
3.Redis单条命令保存原子性,但是事务不保证原子性!
- 开启事务(multi)
- 命令入队(…)
- 执行事务(exec)
- 放弃事务(DISCARD)
4.悲观锁、乐观锁(面试常问)
- 悲观锁:很悲观,什么时候都会有问题,无论做什么都会出现问题
- 乐观锁:很乐观,认为什么时候都不会出现问题,所以不会上锁!更新数据的时候去判断一下,在此期间是否有人修改了数据
- 获取version
- 更新的时候比较version
## 实现乐观锁监控
watch money
unwatch ##取消监控
4.Springboot整合Redis
SpringBoot2.x之后,原来使用的jedis被替换为了lettuce
jedis:采用直连,多个线程操作是不安全的,如果想要避免不安全的,使用jedis pool连接池!更像BIO模式
lettuce:采用netty,实例可以再多个线程中进行共享,不存在线程不安全的情况!可以减少线程数据量,更像NIO模式!
- 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
5. Redis发布订阅
Redis 发布订阅 (pub/sub) 是一种消息通信模式:发送者 (pub) 发送消息,订阅者 (sub) 接收消息。
Redis 客户端可以订阅任意数量的频道。
下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:
当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:
subscribe ruobai #创建一个通信信道
publish ruobai "hello world" #发布一个消息