Redis
1. Redis 介绍
- Redis(Remote Dictionary Server)是用C语言开发的一个开源的高性能键值对数据库。它的所有数据都是保存在 内存 中,这也就决定了其读写速度之快,是其它硬盘保存数据的系统所无法匹敌的。
- 官方曾经给出过一组测试数据,50个并发执行 100000个请求:读的速度是 110000次/s,写的速度是 81000次/s
2. Redis 安装和使用
a. 下载
b. Windows 版安装
c. 目录
- redis.windows.conf:配置文件
- redis-cli.exe:Redis 的客户端
- redis-server.exe:Redis 服务器端
d. 启动
- 推荐使用命令行的方式
- 在当前解压后的目录下 cmd 进入 dos 窗口
- 先启动 redis-server.exe redis.windows.conf
- 新建窗口,再启动 redis-cli.exe
3. Redis 客户端图形化工具
4. Redis 数据结构(重点)
- Redis 采用的键值对存储数据,键(key)的类型只能为 字符串,值(value)支持五种数据类型:
- 字符串:String
- 哈希:HashMap
- 双向链表:LinkedList,有序且能重复,可以左压栈也可以右压栈
- 无序集合:HashSet,无序且不能重复
- 有序集合:LinkedHashSet,有序且不能重复
5. Redis 命令操作(重点)
- Redis 命令是用来操作 Redis 数据库的,类似于操作 MySql 数据库时的 SQL 语句。
- 只需要学习 SQL 基本就可以操作关系型数据库(1972 年诞生);但是 Redis 命令,在非关系型数据库中,只能在 Redis 中使用(只有十几年的发展经历,所以没有一定的开发规范)
- Redis 的命令根据要操作的值(value)的数据结构的不同而不同,每种数据类型都有自己的操作命令。
a. String 字符串
- 字符串类型是 Redis 中最为基础的数据存储类型。
- 在 Redis 中字符串类型的 Value 最多可以容纳的数据长度是 512 MB(超过这个上限,可以改用 HBase)。
* 新增
set key 'value'
value 的值有空格需要加引号,没有空格不需要加引号
* 查询
get key
* 删除
del key
成功则返回 1
* 新增并指定存活时间
setex key 存活时间 'value'
单位秒
* 查看存活时间
ttl key
* 主键自增器
incr key
value 的值默认加 1
需要 value 是整型
b. Hash 哈希
- Hash 类型极其类似于 Java 中的 Map,值里面可以存放一组组的键值对,该类型非常适合于存储 Java 中对象的信息。
* 新增
hset key hkey hvalue
* 查询
hget key hkey
hgetall key
* 删除
hdel key hkey
del key
c. List 链表
- List 类型底层是一个双向字符串链表。里面的元素是有序的,可重复的,可以从链表的任何一端进行元素的增删。
* 新增
lpush key value 将元素压入左侧顶端
rpush key value 将元素压入右侧顶端
建议只用其中一种
* 查询
lrange key start end 从左向右查询
start 为 0,end 为 -1 是查询所有
* 删除
lpop key 将左侧顶端元素弹出
rpop key 将右侧顶端元素弹出
d. Set 集合(无序)
- Set 类型底层是一张 hash 表。里面的元素是无序的,不可重复的。
* 新增
sadd key value
* 查询
smembers key
* 删除
srem key value 删除指定元素
del key 删除整个 set 集合
e. ZSet 集合(有序)
- Zset,也称 sortedSet,在 Set 的基础上,加入了有序功能,在添加元素的时候,允许指定一个分数,它会按照这个分数排序。
* 新增
zadd key score value
* 查询
zrange key start end [withscores] 升序
zrevrange key start end [withscores] 降序
加上 withscores 会显示分数,不加 withscores 只显示元素
* 删除
zrem key value 删除指定元素
del key 删除 zset 集合
f. 通用命令
* 模糊查询键
keys *
* 是通配符,表示所有
* 删除多个键
del key [key] [key]
返回的数就是被影响的 key 的数量
* 根据键判断记录是否存在
exists key
返回的值 0 是 false,1 是 true
* 根据键判断值类型
type key
很重要,时间久了可以用它来判断并进行相应操作
* 选择数据库
select 0~15
默认是 0 库,一般也使用 0 库
* 清空当前数据库
flushdb
慎重使用,开发中不允许使用
* 清空所有数据库
flushall
慎重使用,开发中不允许使用
6. Redis 持久化(面试题)
- Redis 的数据都是存在在内存之中的,那么这样一旦出现宕机,势必会导致数据的丢失,这就需要持久化操作,也就是要将 Redis 在内存中的数据写到硬盘上保存。
- 注意,Redis 虽然有持久化操作,但是其全部数据依旧都在内存中存在,也就是说硬盘上的只是为了安全和备份。
- Redis 提供了两种数据持久化的方式,分别是 RDB 和 AOF。
a. RDB(默认开启)
- 在 Redis 运行期间,根据指定时间节点对内存的数据进行快照拍摄,持久化到磁盘文件(默认文件 dump.rdb,乱码)
- 指定时间规则拍摄快照:在 redis.windows.conf 中指定
save 900 1
save 300 10
save 60 10000
b. AOF(默认关闭,需要手动开启)
- 在 Redis 运行期间,以日志记录的方式监听 set 操作,持久化到磁盘文件(默认文件 appendonly.aof,每步操作可查看,Redis 重启后逐步加载)
- 开启 AOF:修改 redis.windows.conf 中的 appendonly no 为 appendonly yes
- 日志持久化机制
- appendfsync always 每次执行 set 操作时都会持久化一次;
- appendfsync everysec 每秒钟持久化一次(默认,因为 Redis 每秒读写速度很快,所以这种折中方案比第一种更合适);
- appendfsync no 根据服务器环境,CPU 不忙的情况,持久化一次。
c. 小结
- RDB:把 Redis 作为缓存来用。
- AOF:把 Redis 作为独立数据库。
- 这二种持久化机制可以共存。
7. 应用场景
a. 缓存
b. 秒杀
c. 微博热搜
d. 分布式 Session
e. 验证码存储
- 通过将验证码放到 Redis 中,可以实现对其存货时间的精准控制。
Jedis
- Redis 作为一款优秀的缓存服务器存在,大多数语言都提供了连接 Redis 的驱动包,在 Java 中,比较出名的是 Jedis 和 Redisson,我们今天以 Jedis 为例学习,看看如何是用程序操作 Redis。
1. Jedis 快速入门
方法 | 解释 |
---|
new Jedis(host, port) | 创建 Jedis 对象,参数 host 是 Redis 服务器地址,参数 port 是 Redis 服务端口 |
set(key,value) | 设置字符串类型的数据 |
get(key) | 获得字符串类型的数据 |
hset(key,field,value) | 设置哈希类型的数据 |
hget(key,field) | 获得哈希类型的数据 |
lpush(key,values) | 设置列表类型的数据 |
lpop(key) | 列表左面弹栈 |
rpop(key) | 列表右面弹栈 |
del(key) | 删除指定的 key |
- 在测试 Jedis 代码之前,一定要保证 Redis 环境正常运行。Windows 有时需要重启 Server。
a. 导入相关坐标
b. 编写代码
package com.regino.test;
import org.junit.Test;
import redis.clients.jedis.Jedis;
public class JedisTest {
@Test
public void test01() throws Exception {
Jedis jedis = new Jedis("127.0.0.1", 6379);
jedis.set("Regino", "你好");
jedis.close();
}
@Test
public void test02() throws Exception {
Jedis jedis = new Jedis();
String java = jedis.get("Regino");
System.out.println(java);
jedis.close();
}
}
2. Jedis 连接池
- Jedis 连接资源的创建与销毁是非常消耗性能的,所以我们不希望频繁的创建和销毁它。基于这样的需求,就有了 jedisPool 技术。
a. 快速入门
package com.regino.test;
import org.junit.Test;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class JedisPoolTest {
@Test
public void test01() throws Exception {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(100);
jedisPoolConfig.setMaxWaitMillis(3000);
jedisPoolConfig.setMaxIdle(10);
JedisPool jedisPool = new JedisPool("localhost", 6379);
Jedis jedis = jedisPool.getResource();
jedis.hset("myhash", "id", "1");
jedis.close();
}
}
b. 抽取为连接池工具类
package com.regino.travel.util;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
import java.util.ResourceBundle;
public class JedisUtils {
private static JedisPool jedisPool;
private static String host;
private static Integer port;
private static Integer maxTotal;
private static Integer maxIdle;
static {
try {
ResourceBundle jedis = ResourceBundle.getBundle("jedis");
InputStream is = JedisUtils.class.getClassLoader().getResourceAsStream("jedis.properties");
Properties properties = new Properties();
properties.load(is);
host = properties.getProperty("jedis.host");
port = Integer.parseInt(properties.getProperty("jedis.port"));
maxTotal = Integer.parseInt(properties.getProperty("jedis.maxTotal"));
maxIdle = Integer.parseInt(properties.getProperty("jedis.maxIdle"));
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(maxTotal);
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPool = new JedisPool(jedisPoolConfig, host, port);
} catch (IOException e) {
e.printStackTrace();
}
}
public static Jedis getJedis() {
return jedisPool.getResource();
}
}
原文链接:https://qwert.blog.csdn.net/article/details/106290370