Redis
一,docker方式安装redis
# 拉取 redis 镜像
> docker pull redis
# 运行 redis 容器
> docker run --name myredis -d -p6379:6379 redis
# 执行容器中的 redis-cli,可以直接使用命令行操作 redis
> docker exec -it myredis redis-cli
二,数据结构
- string --字符串
- list–列表
- set-- 集合
- hash – 哈希
- zset – 有序集合
String
用途:缓存用户信息。
redis的字符串是动态的,类似java的arrayList,用预分配冗余空间的方式来减少内存的频繁分配。每次扩容1M,最大长度512M
#设置字符串
set userName "小明"
#获取字符串
get userName
("小明")
#是否存在
exists userName
(integer)1
#删除
del userName
(integer)1
#批量设置
mset name1 dog name2 cat name3 monkey
#批量获取 返回一个列表
mget name1 name2 name3
"dog"
"cat"
"monkey"
#设置过期时间---用语控制缓存的失效时间
expire userName 5 #5s后过期
setex userName 5 codehole #5s后过期,等价于set+expire
setnx userName codehole # 如果name不存在就执行set创建
#计数 如果value值是一个整数,可以对他进行自增操作,自增有范围,(signed long 的最大最小值,超值会报错)
set age 30
incr age #自增
(integer)31
incrby age 5 #自增5个
(integer)36
incrby age -5 #自减5个
(integer)31
list列表
相当于java里的linkedList,她是链表不是数组,插入删除快。
redis列表结构常用来做异步队列使用。
#右进左出--队列 (先进先出)
rpush books java python golang #右进队列名books
llen books #查看长度
(integer)3
lpop books #左出(每次出一个,按照顺序)
#右进右出--栈 (先进后出)
rpush books java python golang #进入栈
rpop books #出数据
"golang"
慢操作
lindex相当于java链表的get(index)方法,需要对链表进行遍历,性能随着参数index增大而变差。
ltrim start_index end_index 定义了一个区间,在这个区间内的值,会被保留,此外统统砍掉。
rpush books python java golang
lindex books 1 #查询下标是1的元素(慎用)
"java"
lrang books 0 -1 #获取所有元素
1) "python"
2) "java"
3) "golang"
ltrim books 1 -1 #截取保留【1,-1】区间内的元素
lrang books 0 -1 # 获取所有元素
1) "java"
2) "golang"
快速列表
redis底层存储是 quickList的快速链表结构。在列表元素较少时使用一块连续的内存存储,这个结构是ziplist(压缩列表)。当数据量比较多是才会改成quickList。因为普通链表需要的附加指针空间太大,会比较浪费空间。还会加重内存的碎片化。
hash字典
相当于java种的hashMap,无序字典。结构(数组+链表二维结构)。第一维hash的数组位置碰撞时,就会将碰撞的元素使用链表串接起来。
redis的字典值只能是字符串。java的hashMap在字典很大时,rehash是个耗时的操作,需要一次性全部rehash。Redis为了不阻塞服务,采用了渐进式rehash策略。
# hset 字典名 key名 value
hset book java "this is java" #命令行的字符串如果包含空格,要用引号括起来
hset books golang "concurrency in go"
#查看
hgetall books # key和value间隔出现
1) "java"
2) "this is java"
3) "golang"
4) "concurrency in go"
#查看元素长度
hlen books
(integer)2
#查看某key的value
hget books java
"this is java"
#批量设置
hmset books java "effective java" python "learning python" golang "modern golang
programming"
#hash结构种单个子key也可以计数
hincrby user-ming age 1 #在原来的年龄数上加1
set集合
相当于java里的hashSet,内部唯一无序。他的内部实现相当于一个特殊的字典,字典中所有的value都是一个值null.
当集合种最后一个元素移除后,数据结构自动删除,内存被回收,
#sadd 集合名 key
sadd books java #重复添加相同的key不会添加成功
#批量添加
sadd books python golang
#查看集合内容
smembers books
1) "java"
2) "python"
3) "golang"
#查询某个key是否存在
sismember books java
(integer)1
sismember books rust
(integer)0
#获取集合长度
scard books
(integer)3
#弹出一个
spop books
"java"
zset-有序列表
有序唯一,它可以给每一个value赋予一个score,代表这个value的排序权重,它内部实现用的是一种叫着跳跃列表的数据结构。
zset中最后一个value被移除后,数据结构自动删除,内存被回收。
#添加元素
> zadd books 9.0 "think in java"
(integer) 1
> zadd books 8.9 "java concurrency"
(integer) 1
> zadd books 8.6 "java cookbook"
(integer) 1
#正序排序
zrange books 0 -1
1) "java cookbook"
2) "java concurrency"
3) "think in java"
#逆序排序
zrevrange books 0 -1
1) "think in java"
2) "java concurrency"
3) "java cookbook"
#查看长度
zcard books
(integer)3
#获取指定value的score
> zscore books "java concurrency" # 获取指定 value 的 score
"8.9000000000000004" # 内部 score 使用 double 类型进行存储,所以存在小数点精度问题
#查看排名
zrank books "java concurrency" # 排名
(integer) 1
# 根据分值区间遍历 zset
> zrangebyscore books 0 8.91
1) "java cookbook"
2) "java concurrency"
# 根据分值区间 (-∞, 8.91] 遍历 zset,同时返回分值。inf 代表 infinite,无穷大的意思。
> zrangebyscore books -inf 8.91 withscores
1) "java cookbook"
2) "8.5999999999999996"
3) "java concurrency"
4) "8.9000000000000004"
# 删除 value
> zrem books "java concurrency" # 删除 value
(integer) 1
> zrange books 0 -1
1) "java cookbook"
2) "think in java"