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>
msets1 "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 1010s后删除该键
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抢购的实现

京公网安备 11010502036488号