—— 目录 ——
0. Redis 简介
Redis 即 Remote Dictionary Server 远程字典服务
1. 安装 Redis
(1)下载安装包:https://redis.io/ 官网中间的 Download it
(2)解压安装包,看到拿到目录结构
(3)在该目录结构下,使用 make
进行编译
(4)默认安装路径:/usr/local/bin
(5)拷贝 redis 配置文件到 /usr/local/ 下自己新建的文件夹下,往后修改的配置文件即为拷贝后的文件,方便在配置失误时通过原配置文件恢复
(6)修改配置文件时 redis 在后台运行(默认不是),将起改为 yes
(7)启动 redis,进入 /usr/local/bin 下,可以看到各种服务(其中 iceconf 为上边说到的存放拷贝配置的自定义文件夹)
使用 redis-server iceconf/redis.conf
启动服务
(8)连接 redis:使用 redis-cli (-h xxx) -p 6379
(-h 为连接到那台服务器,现在为本机可以不写,-p 为那个端口,redis 默认端口为 6379)
出现下图就表示连接 ok 啦(连接上 6379 端口以及使用 ping 命令可以收到 PONG)
(9)测试性能
可选参数:
-h 指定服务的主机名
-p 指定服务的端口号
-s 指定服务器 socket
-c 指定并发连接数
-n 指定请求数
测试:100 个并发连接,每个连接 100000 次请求
redis-benchmark -p 6379 -c 100 -n 100000
上图表示:
100000 个请求 2.33 秒就处理完毕,每次有 100 个并发客户端
每次写入 3 个字节,只有 1 台服务器处理请求
在配置文件中可以看到默认有 16 个数据,
可以通过 select <num>
来选择数据库
使用 dbsize
可以查看当前数据库的大小
flushdb
清空当前数据库
flushall
清空所有数据库
2. 基本命令
(9)基本命令
添加数据
set <key> <value>
获取数据
get <key>
查看所有键
keys *
关闭 redis
shoutdown,然后 exit
判断键是否存在。存在返回 1 ,否则 0
exists <key>
移除键值对,num 为当前所在的数据库,成功 1 失败 0
move <key> <num>
设置过期时间,超过时间后自动移除该键值对
expire <key> <seconds>
ttl <key> 查看剩余时间
查看某个 key 的类型
type <key>
3. 五大数据类型
① String 字符串
1) 在指定 key 的值后面拼接字符串,可以使用双引单引号,也可以不用
如果没有该键,将会新建一个
append <name> <content>
2) 获取字符串长度
strlen <key>
3) 自增自减
使一个值自增 1 :incr <key>
使一个之自减 1 :decr <key>
使一个值自增 num :incrby <key> <num>
使一个值自减 num :decrby <key> <num>
4) 查看一部分字符串(从 0 开始,闭区间)
getrange <key> <start> <end>
end 为 -1 表示查看完 start 后的所有字符串
5) 替换字符串
setrange <key> <offset> <content>
注意:
这里会将以 <offset> 开始的字符串替换成 <content> ,相当于覆盖输入
如果以 <offset> 开始直到结束的字符串长度都比 <content> 小,则会抛出错误 `(error) ERR syntax error`
6) 设置字符串时指定过期时间
setex <key> <seconds> <value>
7) 在键不存在时才新建 key 并设置值,成功 1,已存在的话则失败 0
setnx <key> <value>
8) 批量写入
mset <key1> <value1> <key2> <valye2> ...
msetnx <key1> <value1> <key2> <valye2> ...
加上 nx 表示只有所有的键都不存在时才会执行成功(原子性),只要有一个 key 存在,则全部写入失败
9) 批量读取
mget <key1> <key2> ...
10) 先获取再设置值,如果键不存在则放回 nil,之后新建一个键保存该值
getset <key> <value>
② List 列表
本质上是一个链表,故元素可以重复。可以通过 List 实现栈、队列。
除了添加和移除命令区分 l
和 r
,l
表示元素从列表的头部插入, r
则从尾部插入
其余所有的 List 命令都是以 l
开头的,下面以 l
作演示
1) 添加值
lpush <key> <element1> <element2> ...
2) 将列表中指定下标的值替换为另外的值
lset <key> <index> <value>
如果 key 不存在,或者指定下标不存在,则会抛出错误
3) 往列表中某一个元素的前面或者后面插入值
linsert <key> <before|after> <pivot> <value>
4) 通过范围获取值
lrange <key> <start> <stop>
同样当 stop 为 -1 时,表示从 start 开始到结束
5) 通过下标获取值
lindex <key> <index>
6) 获取列表的长度
llen <key>
7) 移除列表的第一个元素
lpop <key>
8) 移除具体的值
lrem <key> <num> <value>
因为列表中允许有重复的值存在,可通过 num 控制要移除多少个
num 表示按顺序移除多少个值,若输入 0 则表示全部移除,如果 num 大于存在的个数,也是全部移除
9) 截取只保留某些值,表示只保留闭区间 [start, end] 之间的值
ltrim <key> <start> <stop>
10) 组合命令
将 key1 中的最后一个元素移除,并添加到 key2 的第一个元素
rpoplpush <key1> <key2>
③ Set 集合
无序不重复,不能存在相同的值
所有的命令以 s
开头
1) 添加元素
sadd <key> <value>
2) 判断某一个值是否在集合中
sismember <key> <member>
3) 获取集合中元素的个数
scard <key>
4) 获取集合中所有的元素
smembers <key>
5) 移除指定的元素
srem <key> <member>
6) 随机获取 num 个元素,num 不写默认为 1 个
srandmember <key> [num]
7) 随机移除 num 个袁术,num 不写默认为 1 个
spop <key> [num]
8) 将一个指定的值从 key1 中移动到 key2 中
smove <key1> <key2> <member>
9) 找出 key 中不同于 key1 key2 ... 的元素(差集)
sdiff <key> <key1> [key2] ...
10) 求所有集合的交际
sinter <key1> <key2> [key3] ...
11) 求所有集合的并集
sunion <key1> <key2> [key3] ...
④ Hash 散列表
<key,<key,value>>
相当于 key-value 中的 value 是一个 key-value
更加蛇和于对象的存储(一个对象为一个 hash,每个属性为 hash 的一个 field)
搜友的命令以 `h 开头
1) 添加元素
hset <key> <field> <value>
2) 获取元素
hget <key> <field>
3) 批量添加元素
hmset <key> <field1> <value1> <field2> <value2> ...
4) 批量获取元素
hmget <key> <field1> <field2>
5) 查看所有元素(以键值对的形式显示,第一个是键,第二个是值)
hgetall <key>
如:
"f1"
"bbb"
"f2"
"ccc"
6) 删除指定的 field
hdel <key> <field>
7) 获取键值对的个数
hlen <key>
8) 判断字段是否存在
hexists <key> <field>
9) 获取所有的 field
hkeys <key>
10) 获取所有的 value
hvals <key>
11) 自增自减,num 为正即自增,为负即自减
hinceby <key> <field> <num>
12) 不存在才设置值(原本是即使存在会覆盖,现在是存在则不设置)
hsetnx <key> <field> <valuie>
⑤ Zset 有序集合
在 set 的基础上,添加了一个值表示序号
该序号可以用于存放有意义的值,如收入,点赞数,战斗力等等,可用故意排序
1) 添加元素,同时给该值一个 score,用于排序
zadd <key> <score> <value>
2) 根据 score 进行排序,min 和 max 表示对 socre 在该范围的值进行排序
输入 -inf +inf 表示负无穷和正无穷,即对全部数据囧行排序
在最后面加上 WITHSCORES 可以连同 score 的值一起输出
zrangebyscore <key> <min> <max> [WITHSCORES]
3) 移除元素
zrem <key> <valuie>
4) 获取有序集合的元素个数
zcard <key>
5) 获取指定区间的元素个数
zcount <key> <min> <max>
4. 在 IDEA 中使用 Redis(Jedis)
Jedis 是 Redis 官方推荐的 java 连接开发工具
① 导入 Jedis 依赖包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.6.3</version>
</dependency>
② 测试连接
@Test
public void test1() {
// 参数为 地址 + 端口
Jedis jedis = new Jedis("120.0.0.1", 6379);
System.out.println(jedis.ping());
}
输出 PONG 即为连接成功
如果出现了异常,可以看看下面这篇
解决 Redis 连接异常 JedisConnectionException: Failed to create socket
连接成功后,所有以上的命令在 Jedis 都有对应的方法,直接用就好啦
2021-8-18 补充
5. Spring 整合 Redis(Redis 工具类)
除了上面那个依赖,还需要一个 spring 整合所需的
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.5.3</version>
</dependency>
Redis 配置文件 spring-redis.xml
可以自定义 .properties
文件(补全 ${xxx}
)也可以直接填值
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!--扫描redis配置文件-->
<context:property-placeholder ignore-unresolvable="true" location="classpath:redis.properties"/>
<!--设置连接池-->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${xxx}"/>
<property name="maxTotal" value="${xxx}" />
<property name="maxWaitMillis" value="${xxx}" />
<property name="testOnBorrow" value="${xxx}" />
<property name="testOnReturn" value="${xxx}" />
</bean>
<!--设置链接属性-->
<bean id="connectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"
p:hostName="${xxx}"
p:port="${xxx}"
p:password="${xxx}"
p:pool-config-ref="poolConfig"
p:timeout="${xxx}"/>
<!-- Jedis模板配置 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.StringRedisTemplate">
<property name="connectionFactory" ref="connectionFactory" />
</bean>
</beans>
工具类的书写:
注意事项:
需要使用 @Component 添加到容器中(需要用到 Spring 注解)
其次静态的 RedisTemplate 不能直接被注入,所以这里通过 set 方法注入
然后是 RedisTemplate 泛型的问题,只能使用 <Object, Object>
而 StringRedisTemplate 只能使用 <String, String>
但使用泛型会导致注入失败,所以这里不使用(欢迎指出错误)
RedisUtils.java
@Component
public class RedisUtils {
private static RedisTemplate<Object, Object> redisTemplate;
@Autowired
public void setRedisTemplate(RedisTemplate redisTemplate) {
RedisUtils.redisTemplate = redisTemplate;
}
public static void test() {
System.out.println(redisTemplate.keys("*"));
}
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return 是否成功
*/
public static boolean expire(String key, long time) {
Boolean expire = redisTemplate.expire(key, time, TimeUnit.SECONDS);
return expire != null && expire;
}
/**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public static long getExpire(String key) {
Long expire = redisTemplate.getExpire(key, TimeUnit.SECONDS);
return expire == null ? -1 : expire;
}
/**
* 设置 hash 值
* @param key 键
* @param field 域
* @param value 值
*/
public static void hashSet(String key, String field, Object value) {
redisTemplate.opsForHash().put(key, field, value);
}
/** 重载方法,在新建时指定失效时间 */
public static void hashSet(String key, String field, Object value, long time) {
redisTemplate.opsForHash().put(key, field, value);
expire(key, time);
}
/**
* 获取指定 key 的一个 hash 值
* @param key 键
* @param field 域
* @return 值
*/
public static Object hashGet(String key, String field) {
return redisTemplate.opsForHash().get(key, field);
}
/**
* 获取指定 key 全部的 hash 值
* @param key 建
* @return 全部的值 Map
*/
public static Map<Object, Object> hashGetAll(String key) {
return redisTemplate.opsForHash().entries(key);
}
/**
* 删除 hash 指定域的值
* @param key 键
* @param field 域 可以多个
*/
public static Long hashDel(String key, Object... field) {
return redisTemplate.opsForHash().delete(key, field);
}
}
最后就是向普通工具类一样使用啦,详情再去查阅 RedisTemplate 的使用方法
龟速与光速的距离,一鸣之间(IceClean)