Redis 高性能数据库,Redis能轻松实现秒杀系统
Redis写入内存而不是写入硬盘、异步处理而不是同步处理、分布式处理
安装 Redis
官方建议在 linux 上安装
本次使用windows安装 Redis Windows版本 下载地址
> redis-cli 连接redis客户端
Microsoft Windows [版本 10.0.19044.1526]
(c) Microsoft Corporation。保留所有权利。
C:\Users\CodeHaywire>redis-cli
127.0.0.1:6379> ping
PONG
127.0.0.1:6379>
Ridis的数据类型
string(字符串)
hash(哈希)
list(列表)
set(集合)
zset(sorted set:有序集合)
#字符串
Microsoft Windows [版本 10.0.19044.1526]
(c) Microsoft Corporation。保留所有权利。
C:\Users\CodeHaywire>redis-cli
127.0.0.1:6379> set name zhanshan
OK
127.0.0.1:6379> get name
"zhanshan"
127.0.0.1:6379>
mset
s1 "hello" s2 "world" s3 "ok"同时设置多个
mget:同时获得多个
127.0.0.1:6379> mset s1 "hello" s2 "world" s3 "ok"
OK
127.0.0.1:6379> mget s1 s2
1) "hello"
2) "world"
127.0.0.1:6379>
数据加减
incrby :添加
decrby:减少
使用场景:计数器
127.0.0.1:6379> set num 100
OK
127.0.0.1:6379> get num
"100"
127.0.0.1:6379> incrby num 100
(integer) 200
127.0.0.1:6379> get num
"200"
127.0.0.1:6379>
keys *
查询所有键
127.0.0.1:6379> keys *
1) "name"
2) "s1"
3) "num"
4) "s2"
5) "s3"
127.0.0.1:6379>
del key 删除某个键
type key 查看某个键的类型
rename key newkey 重命名某个键
定时删除
expire key 10
10s后删除该键
127.0.0.1:6379> expire name 10
(integer) 1
127.0.0.1:6379> get name
"zhanshan"
127.0.0.1:6379> get name
(nil)
127.0.0.1:6379>
strlen key
查询字符串的长度
127.0.0.1:6379> strlen s1
(integer) 5
127.0.0.1:6379> get s1
"hello"
127.0.0.1:6379>
list 列表
lpush list value1 value2 value3
头部添加
rpush list value1 value2 value3
尾部添加
lrange book start end
查询全部数据lpop key
移除头部第一个并返回删除的值
rpop key
移除尾部第一个并返回删除的值
127.0.0.1:6379> lpush book c++ c# c
(integer) 5
127.0.0.1:6379> lrange book 0 5 #查询全部数据
1) "c"
2) "c#"
3) "c++"
4) "c#"
5) "c++"
127.0.0.1:6379> lrange book 0 -1
1) "c"
2) "c#"
3) "c++"
4) "c#"
5) "c++"
127.0.0.1:6379> rpush book java
(integer) 6
127.0.0.1:6379> lrange book 0 -1
1) "c"
2) "c#"
3) "c++"
4) "c#"
5) "c++"
6) "java"
127.0.0.1:6379>
127.0.0.1:6379> lrange book 0 -1
1) "c"
2) "c#"
3) "c++"
4) "c#"
5) "c++"
6) "java"
127.0.0.1:6379> lpop book #移除头部第一个并返回删除的值 #rpop相反
"c"
127.0.0.1:6379> lrange book 0 -1
1) "c#"
2) "c++"
3) "c#"
4) "c++"
5) "java"
127.0.0.1:6379>
llen key
查询list的长度
127.0.0.1:6379> llen book #查询list的长度
(integer) 5
127.0.0.1:6379> lrange book 0 5
1) "c#"
2) "c++"
3) "c#"
4) "c++"
5) "java"
127.0.0.1:6379>
lrem key count value
删除指定元素 解释 count
127.0.0.1:6379> lrange book 0 5
1) "c#"
2) "c++"
3) "c#"
4) "c++"
5) "java"
127.0.0.1:6379> lrem book 2 c#
(integer) 2
127.0.0.1:6379> lrange book 0 5
1) "c++"
2) "c++"
3) "java"
127.0.0.1:6379>
集合 set
sadd key value
添加数据
srem key value
移除元素
smembers key value
查询所有元素
scard key
打印集合大小
sismember key value
查询给定元素是否在集合中sunion key key
打印集合的并集sdiff key key
打印集合的交集
哈希 hash
hset hash key value
哈希表里插入数据
hget hash key
获得哈希表里数据
hexists hash key
查询某个数据是否存在
hlen hash
打印哈希表的长度
127.0.0.1:6379> hset student stuName zhanshan
(integer) 1
127.0.0.1:6379> hset student age 12
(integer) 1
127.0.0.1:6379> hget student stuNname
(nil)
127.0.0.1:6379> hget student stuName
"zhanshan"
127.0.0.1:6379> hget student age
"12"
127.0.0.1:6379> hexists student age
(integer) 1
127.0.0.1:6379> hexists student qq
(integer) 0
127.0.0.1:6379>
有序集合 zset
zadd set key value
哈希表里插入数据
zrem set key value
哈希表里删除数据
使用场景:计数器 缓存数据 更多使用场景
flushall
清空所有数据
Java 连接 redis
<dependencies>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency>
</dependencies>
package cn.js.redis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* @ClassName : ConnectRedis
* @Description : 连接redis
* @Author : CodeHaywire
* @Created at 2022/3/28 8:35
*/
public class ConnectRedis {
public static void main(String[] args) {
JedisPool pool = new JedisPool("localhost", 6379);
try (Jedis jedis = pool.getResource()) {
//添加数据
jedis.set("s1", "Jedis");
}
}
}
打开 cmd
127.0.0.1:6379> keys *
1) "s2"
2) "db"
3) "s3"
4) "student"
5) "s1"
6) "book"
7) "num"
127.0.0.1:6379> get s1
"Jedis"
127.0.0.1:6379>
package cn.js.redis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* @ClassName : ConnectRedis
* @Description : 连接redis
* @Author : CodeHaywire
* @Created at 2022/3/28 8:35
*/
public class ConnectRedis {
public static void main(String[] args) {
JedisPool pool = new JedisPool("localhost", 6379);
try (Jedis jedis = pool.getResource()) {
//添加数据
jedis.set("s1", "Jedis");
//获得数据
String s1 = jedis.get("s1");
System.out.println(s1);
}
}
}
package cn.js.redis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
/**
* @ClassName : ConnectRedis
* @Description : 连接redis
* @Author : CodeHaywire
* @Created at 2022/3/28 8:35
*/
public class ConnectRedis {
public static void main(String[] args) {
JedisPool pool = new JedisPool("localhost", 6379);
try (Jedis jedis = pool.getResource()) {
Long length = jedis.strlen("s1");
System.out.println(length);
}
}
}
···
5
···
// Long count = jedis.del("s1");
// System.out.println(count);
···
1
···
Set<String> keys = jedis.keys("*");
for (String key : keys) {
System.out.println(jedis.get(key));
}
···
SLF4J: Failed to load class "org.slf4j.impl.StaticLoggerBinder".
SLF4J: Defaulting to no-operation (NOP) logger implementation
SLF4J: See http://www.slf4j.org/codes.html#StaticLoggerBinder for further details.
redis
100
···
package cn.js.redis;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import java.util.List;
/**
* @ClassName : ConnectRedis
* @Description : 使用方法大同小异
* @Author : CodeHaywire
* @Created at 2022/3/28 8:35
*/
public class ConnectRedis {
public static void main(String[] args) {
JedisPool pool = new JedisPool("localhost", 6379);
try (Jedis jedis = pool.getResource()) {
jedis.lpush("book", "Java", "C++", "vue");
jedis.rpush("book", "JavaScript", "C#", "Go");
List<String> book = jedis.lrange("book", 0, -1);
for (String s : book) {
System.out.println(s);
}
}
}
}
···
127.0.0.1:6379> LRANGE book 0 -1
1) "vue"
2) "C++"
3) "Java"
4) "JavaScript"
5) "C#"
6) "Go"
127.0.0.1:6379>
···
redis事务
redis事务就是一次性、顺序性、排他性的执行一个队列中的一系列命令
相关命令 : MULTI EXEC DISCARD WATCH UNWARCH
multi
: 标记一个事务块的开始( queued )
exec
: 执行所有事务块的命令 (一旦执行exec后,之前加的监控锁都会被取消掉)
discard
: 取消事务,放弃事务块中的所有命令
watch
: 对 key 监控
unwatch
: 取消watch对所有key的监控
小示例:
redis 不支持回滚,出现错误时,不会回滚,跳过这条命令,仍然执行其他命令
watch机制+事务 阻止超卖
模拟A账户购买网卡未及时支付,晚一步支付
127.0.0.1:6379> set account:a 1000
OK
127.0.0.1:6379> set product:num 1
OK
127.0.0.1:6379> watch account:a product:num
OK
127.0.0.1:6379> get account:a
"1000"
127.0.0.1:6379> get product:num
"1"
127.0.0.1:6379> multi
OK
127.0.0.1:6379> decrby account:a 1000
QUEUED
127.0.0.1:6379> decrby product:num 1
QUEUED
127.0.0.1:6379>
模拟B账户购买成功
C:\Users\CodeHaywire>redis-cli
127.0.0.1:6379> get account:b
(nil)
127.0.0.1:6379> set account:b 1000
OK
127.0.0.1:6379> watch account:b product:num
OK
127.0.0.1:6379> get account:b
"1000"
127.0.0.1:6379> get product:num
"1"
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> decrby account:b 1000
QUEUED
127.0.0.1:6379> decrby product:num 1
QUEUED
127.0.0.1:6379> exec
1) (integer) 0
2) (integer) 0
127.0.0.1:6379>
A网好了后去买
127.0.0.1:6379> exec
(nil) 没了
127.0.0.1:6379> get account:a
"1000" 钱还在
127.0.0.1:6379>
数据如何存?
mysql
中存all
即所有的数据(redis
只是缓存
的mysql
中的部分数据
),redis中缓存mysql中存在的访问量超级大的数据
如果redis
中没有我要的数据,那么其实这些请求并发量没有那么大,那么就去mysql
访问,肯定并没有太大压力
Java抢购的实现