基础知识
- redis 有16个数据库(redis-conf配置文件中设置了database 16),默认使用的是第0个数据库
- select 切换数据库
127.0.0.1:6379[3]> select 0 #切换数据库 OK 127.0.0.1:6379> dbsize #查看数据库大小 (integer) 0 #没有数据所以是0 127.0.0.1:6379> set name qian #插入数据 OK 127.0.0.1:6379> get name #查询数据 "qian" 127.0.0.1:6379> dbsize (integer) 1 #size发生了变化 127.0.0.1:6379>
-
keys * 查看所有的key
127.0.0.1:6379> keys * 1) "name" 127.0.0.1:6379> set age 34 OK 127.0.0.1:6379> set sex ᅣ OK 127.0.0.1:6379> get sex "\xc4\xd0" 127.0.0.1:6379> keys * 1) "sex" 2) "age" 3) "name" 127.0.0.1:6379>
-
flushall 清空所有数据(16个库全部清空),flushdb 清空当前数据库
-
exists检查key是否存在
-
move移除键
127.0.0.1:6379> move name 1 #1表示当前库 (integer) 1 #移除name这个key和对应的值 127.0.0.1:6379> 127.0.0.1:6379> exists name (integer) 0 #移除后检查存在 127.0.0.1:6379>
-
expire设置过期时间
127.0.0.1:6379> set name qian
OK
127.0.0.1:6379> expire name 10 #设置10秒后过期
(integer) 1
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> keys *
1) "name"
127.0.0.1:6379> keys *
(empty list or set)
127.0.0.1:6379>
8. ttl查看剩余有效时间
127.0.0.1:6379> set name qian
OK
127.0.0.1:6379> expire name 10
(integer) 1
127.0.0.1:6379> ttl name
(integer) 6
127.0.0.1:6379> ttl name
(integer) 4
127.0.0.1:6379> ttl name
(integer) 3
127.0.0.1:6379> ttl name
(integer) 1
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379> ttl name
(integer) -2
127.0.0.1:6379>
当键过期或者被删除了,TTL命令返回-2,当键没有设置过期时间,表示是永久的,TTL命令返回-1
9. type查看key的类型
127.0.0.1:6379> type name
string
127.0.0.1:6379> set 1 3
OK
127.0.0.1:6379> type 1
string #注意上面这个1的key也是string
127.0.0.1:6379>
10. info replcation 查看当前redis的信息(在搭建集群的时候使用)
127.0.0.1:6379> info replication
# Replication
role:master
connected_slaves:0
master_replid:38bdf044f280134fe3708430c675d6d64b94eb01
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
11. redis为什么读写很快?
redis是基于内存操作的,使用单线程去操作效率就是最高的 ,因为多线程涉及到CPU上下文切换耗时且消耗资源。对于内存来说,没有上下文切换效率就是最高的!多次读写都是在一个CPU上的。CPU不是Redis的性能瓶颈,Redis的瓶颈是根据内存和网络带宽。Redis是C语言写的,官方提供的数据为100000+的QPS,这个不比Memecache差
数据类型
redis五大数据类型包括String、List、Hash、Set、Zset
另外三种特殊类型geospatial、hyperloglog、bitmap
具体指令可以参考redis官网redis命令手册使用
也可以通过help查看命令
help @string
help @list
help @hash
help @set
help @sorted_set
总结:
String 特点:value除了字符串还可以是数字
常用字符串操作
SET key value; -- 存入一个字符串键值对
MSET key1 value1 key2 value2 ... -- 批量存储键值对
SETNX key value -- 存入一个不存在的字符串键值对
MGET key1 key2 ... --批量获取键值
DEL key1 key2 ... --删除键值对
EXPIRE key seconds -- 设置一个键的过期时间(秒)
数字类型操作
INCR key -- 将key中存储的数值加一
DECR key -- 将key中存储的数值减一
INCRBY key increment --将key中存储的数值加上increment
DECRBY key decrement --将key中存储的数值减去decrement
应用场景:
a. 单值缓存
就是基本的SET key value和GET key
b. 对象缓存(不建议使用,建议使用hash)
c. 分布式锁
当出现高并发时使用SETNX命令:抢到锁的服务进程会设置成功,没抢到的则会返回0,业务逻辑处理完成后删除该键即可
d. 计数器:文章阅读量,INCR article:id;
e. web集群session共享:session+redis实现session共享
Set特点
QQ共同好友实现:可通过SINTER 交集指令
hash特点
常用命令
HSET key field value -- 存储
HGET key field -- 获取一个字段值
HMSET key field1 value1 field2 value2 ... -- 存储多个hash键值对
HMGET key field1 field2 ... -- 获取多个hash键值对
HSETNX key field value --存储一个不存在filed的值,注意不是key
HDEL key field1 field2 ... -- 删除fields
HLEN key -- 返回key中field的数量
HGETALL key -- 返回所有field
HINCRBY key field increment -- 为field的值增加increment
应用场景
存储对象
扩展:hash与string存储对象相比优缺点
- 优点
- 同类数据归类整合存储,方便管理
- 相比string操作消耗内存和cpu更小
- 比string节省空间
2.缺点
- 过期功能不能用在field上,只能用在key上
- redis集群架构下不适合大规模使用
set特点
常用命令
SADD key member1 member2 ... -- 向set中放入一个或多个value
SREM key member1 member2 ... -- 从set中删除元素
SMEMBERS key -- 从set中获取所有元素
SCARD key -- 获取集合key中元素个数
SISMEMBER key member -- 判断member是否存在于集合key中
SRANDMEMBER key count -- 从集合key中随机选出count个元素,不删除元素。
SPOP key count -- 从集合key中随机取出count个元素,从集合中删除。
#set运算命令
SINTER key1 key2 ... -- 交集运算
SINTERSTORE newKey key1 key2 ... -- 将key的交集存入新的集合newKey
SUNION key1 key2 ... -- 并集运算
SUNIONSTORE newKey key1 key2 ... -- 将key的并集存入新的集合newKey
SDIFF key1 key2 ... ---差集运算
SDIFFSTORE newKey key1 key2 ... -- 将key的差集存入新的集合newKey
应用场景
微信抽奖
用户参与抽奖:
SADD lottery 1001;
SADD lottery 1002;
SADD lottery 1003;
查看所有抽奖用户:
SCARD lottery;
抽取一名幸运儿:
SRANDMEMBER lottery 1;
如果是多次抽奖,不能重复获奖,则使用 SPOP lottery count
微信、微博、QQ等社交软件关注模型
例如:bob、ashuai、anna、lisi、zhangsan
bob关注的人bobSet = {lisi,anna}
ashuai关注的人ashuaiSet = {lisi,zhangsan}
则bob和ashuai共同关注的人:SINTER bobSet ashuaiSet;
bob可能认识的人:SDIFF bobSet ashuaiSet 然后去除bob关注的人。
Zset特点
常用命令
ZADD key [[score member]...] -- 向有序集合key中添加带分值的member
ZREM key member1 member2 ... -- 删除元素
ZSCORE key member -- 返回元素member的分值
ZINCRBY key increment member -- 为元素member的分值加上increment
ZCARD key -- 返回集合中元素个数
ZRANGE key start stop -- 正序返回从start下标到stop下标的元素
ZREVRANGE key start stop -- 倒序返回从start下标到stop下标的元素
ZINTERSTORE destination numkeys key [key ...] -- 交集计算
ZUNIONSTORE destkey numkeys key [key ...] -- 并集计算
应用场景
排行榜:可通过ZRANGEBYSCORE key option命令实现带权重的排序
List特点
常用命令
LPUSH key value1 value2 ... -- 将一个或多个值从左边放入key中
RPUSH key value1 value2 ... -- 将一个或多个值从右边放入key中
LPOP key -- 从左边弹出值
RPOP key -- 从右边弹出值
LRANGE key start stop -- 返回列表key中指定区间内的元素,区间以偏移量start和stop指定
BLPOP key1 key2 ... [timeout] -- 从多个list中左边弹出元素,超时时间timeout
BRPOP key1 key2 ... [timeout] -- 从多个list中右边弹出元素,超时时间timeout
应用场景
公众号消息流
比如大v们给订阅了的粉丝发送消息:
例如:用户xxx的id1001
V1给粉丝推送消息:
LPUSH msg:1001 1888
V2也发送消息:
LPUSH msg:1001 1999
xxx获取最近消息:
LRANGE msg:1001 0 2 – 查看最近3条消息
扩展:使用list构建数据结构
Stack(栈) = LPUSH + LPOP
Queue(队列) = LPUSH + RPOP
Blocking Queue(阻塞队列) = LPUSH + BRPOP
geospatial特点
附近好友,打车距离计算,朋友定位等
hyperloglog特点
统计网页浏览量(一个人不管访问几次,只能算一个)
127.0.0.1:6379> pfadd fp1 a b c d e
(integer) 1
127.0.0.1:6379> pfcount fp1
(integer) 5
127.0.0.1:6379> pfadd fp2 a b f g h
(integer) 1
127.0.0.1:6379> pfmerge fp3 fp1 fp2
OK
127.0.0.1:6379> pfcount fp3
(integer) 8
bitmap(位图)
它也是一种数据结构,通过二进制数据0,1进行记录,常用于统计用户当前状态信息,如打卡/未打卡,登录/未登录
127.0.0.1:6379> setbit qian 0 1 #设置
(integer) 0
127.0.0.1:6379> setbit qian 1 1 #设置
(integer) 0
127.0.0.1:6379> setbit qian 5 1 #设置
(integer) 0
127.0.0.1:6379> bitcount qian #统计
(integer) 3
127.0.0.1:6379> getbit qian 5 #查询
(integer) 1
127.0.0.1:6379> getbit qian 4 #查询
(integer) 0
Jedis使用
导入依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.7.0</version>
</dependency>
连接redis
package com.qian;
import redis.clients.jedis.Jedis;
/**
* @Author qian
* @Date 2021/12/30 15:57
* @Version 1.0
*/
public class TestPing {
public static void main(String[] args) {
//1.new 一个 jedis对象
Jedis jedis = new Jedis("127.0.0.1",6379);
//检查链接是否成功
System.out.println(jedis.ping());
//2.指令对应 方法
jedis.set("name","qian");
}
}
//输出
PONG
提示:使用过程中所有的jedis调用的方法和redis操作的指令是一一对应的
断开连接
jedis.close()
SpringBoot整合Redis
注意:在实际开发中,为了解决序列化或者丰富redis,我们都会自定义实现redisTemplate以及封装一些常用的redis操作方法