Redis
安装
-
解压redis压缩包
-
进入redis源码包。
-
执行make ,如果出现致命错误 。执行 make MALLOC=libc
-
安装执行 make install PREFIX=/usr/redis 安装在/usr/redis文件夹下
使用
- 进入redis/bin目录执行./redis-server 开启redis服务
- 连接redis ./redis-cli -p 6379 -h 127.0.0.1
- 设置键值 set 键 值
- 查询 get 键
- redis 有0-15 共16个库。可用select 编号选择。
- 清空当前库 FLUSHDB 清空所有库 FLUSHALL
key命令
- 删除key del key1 key2 key3 …
- 查看所有key keys *
- 判断key是否存在 exists key
- 设置key超时时间 expire key 秒数 或者 pexpire key 毫秒
- 移动key到指定库号 move key 库号
- 返回key的剩余生产时间 ttl key 或者 pttl key 。前者返回秒,后者返回毫秒
- 随机返回一个key randomkey
- 给key改名 rename key 新名
- 用来查看key的值的类型 type key
String 类型
- 设置多个键值 mset 键 值 键 值 键 值 。。。
- 获取多个键的值 mget 键 键 键。。。
- 获取key的原值并赋新值 getset key 新值
- 获取key的值的长度 strlen key
- 为key的值追加内容 append key 追加内容
- 截取key的值的内容 getrange key 0 3
- 设置key并给key设置超时时间 setex key 秒 值 或者 psetex key 毫秒 值
- 存在不做任何操作,不存在才创建键值 setnx key 值
- 同时设置多个键值,若有一个存在,都不做任何操作 msetnx 键 值 键 值 键 值。。。
- 对key的值是数值串的进行减一 decr key 或者减去指定的数值 decrby key 指定数字
- 对key的值是数值串的进行加一 incr key 或者加上指定的数值 incrby key 指定数字
- 对key的值是数值串的加个浮点数 incrbyfloat key 指定浮点数
list 类型
- 创建一个集合 lpush key 值 值 值 值 或者 rpush key 值 值 值 值
- 遍历一个集合 lrange key 0 -1
- 向已有集合中添加值 lpushx key 值 值 或者 rpushx key 值 值 值
- 从集合左边删除一个元素 lpop key
- 从集合右边删除一个元素 rpop key
- 查询集合的长度 llen key
- 修改集合中元素的值 lset key 索引号 新值
- 获取集合中指定元素 lindex key 索引号
- 删除集合中重复的元素 lrem key 删除几个 元素名
- 保留集合中的某区间的元素 ltrim key 2 4
- 在集合中某元素之前插入一个元素 linsert key before 坐标元素 插入的值
- 在集合中某元素之后插入一个元素 linsert key after 坐标元素 插入的值
set 类型
- 创建一个set集合 sadd key 值 值 值。。。
- 查看set集合中所有元素 smembers key
- 查看set集合中有多少元素 scard key
- 随机删除和返回set集合中的元素 spop key 数量
- 把一个元素从set集合移动到另一个set集合 smove key1 key2 元素名
- 删除set集合中的元素 srem key 值 值 值
- 查看set集合中是否存在元素 sismember key 元素名
- 随机返回set集合中的元素 srandmember key 数量
- key1集合和之后的集合对比,重复的元素去除,对比完返回key1集合中剩下的元素。 sdiff key1 key2 key3
- 求几个set集合的交集 sinter key1 key2 key3
- 求几个set集合的和集 sunion key1 key2 key3
zset 类型
- 创建一个集合 zadd key 分数 值 分数 值
- 查询集合中分数范围内的值 zrangebyscore key 0 100
- 遍历集合中的值 zrange key 0 -1 [withscores]
- 查询集合中元素个数 zcard key
- 查看元素在集合中的排名 zrank key 元素名
- 查看倒序排名 zrevrank key 元素名
- 查看元素的分数 zscore key 元素名
- 移除集合中的元素 zrem key 元素名 元素名
- 给某个元素加分 zincrby key 分数 元素名
hash 类型
- 创建一个集合 hset key k v
- 获取集合中一个键的值 hget key k
- 获取集合中所有的键值 hgetall key
- 删除集中的键值 hdel key k
- 判断集合中的键是否存在 hexists key k
- 获取集合中所有的键 hkeys key
- 获取集合中所有的值 hvals key
- 向添加多个键值 hmset key k v k v k v
- 获取集合中多个值 hmget key k k k
- 向集合中设置一个不存在的键 hsetnx key k v
- 向集合中的键的值加一个数值 hincrby key k 数值
- 向集合中的键的值加一个浮点数值 hincrbyfloat key k 浮点数值
细节
-
redis 默认端口是6379
如何修改端口号,需要引入redis的配置文件。将源码包中redis.conf拷贝到 安装目录的/bin下。
vim 编辑这个文件,修改port 端口号即可。启动时加载配置文件即可生效。./redis-server redis.conf
然后连接redis时 ./redis-cli -p 端口号
-
redis中默认16个库。 0-15号
如何修改库的数量 。修改配置文件中 databases 的数值即可。
-
redis在后台运行
修改配置文件中daemonize 为yes 即可。
-
redis的可视化工具
需要开启redis的远程访问权限。修改配置文件 bind 为0.0.0.0 表示所有客户端都可以访问。
持久化机制
redis中有两种持久化机制。
-
快照持久化(snapshotting)
将redis中某一时刻的状态以快照的形式保存到硬盘中,快照文件是dump.rdb
在配置文件中可以修改 dbfilename 来修改名称。 dir 可修改rdb文件生成路径
创建快照:
- 使用bgsave 指令。
- 使用save命令。不过在快照创建完成前,不能执行任何命令。
- 使用shutdown指令,redis先执行一次save指令后关闭服务
- 根据配置文件自动生产快照。满足配置文件中save项条件后自动执行bgsave。
-
AOF(append only file)持久化
redis将所有写命令都保存在文件中。如果数据丢失,重新执行这个文件。那么可以保证数据绝大部分都会被恢复。但AOF默认没有开启。
开启AOF需要改配置文件。appendonly yes 即可。文件名为appendonly.aof。生成位置与快照位置一致。修改 dir 项即可。
AOF的同步频率:
always:每个写命令都要同步到文件中,但这样会大大降低redis的效率
everysec:每一秒同步一次。
no:由系统决定何时同步。
想要修改写入频率,修改配置文件中,appendfsync项即可。建议:默认就好。
redis的AOF重写机制
将现有的AOF文件进行重写(压缩),从而减少了AOF文件的体积。
执行重写:
- 用指令bgrewriteaof
- 自动重写 修改配置文件。 auto-aof-rewrite-percentage项
java操作redis
-
先引入jedis.jar 这个jar包。
创建redis客户端。用客户端对象调用指令操作redis。
springboot集成springdata操作redis
-
引入依赖spring-boot-starter-data-redis
-
配置springboot的配置文件
-
需要的jar
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-aop</artifactId> </dependency>
-
自定义注解
//添加缓存 @Target(ElementType.METHOD)//声明注解使用的位置 @Retention(RetentionPolicy.RUNTIME) public @interface SaveRedisCache { //可以加属性 //public String/int/... value(); } //移除缓存 @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RemoveRedisCache { //可以加属性 //public String/int/... value(); }
切方法:
@Configuration
@Aspect//声明当前类是一个切面供容器读取
public class RedisCache {
@Autowired
private RedisTemplate redisTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Around("execution(* com.baizhi.service.*.select*(..))")
public Object around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
RedisSerializer stringSerializer = new StringRedisSerializer();
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
StringBuilder sb = new StringBuilder();
//获取类名
String className = proceedingJoinPoint.getTarget().getClass().getName();
sb.append(className);
//获取方法名
String methodName = proceedingJoinPoint.getSignature().getName();
sb.append(methodName);
//获取所有的参数
Object[] args = proceedingJoinPoint.getArgs();
for (Object arg : args) {
sb.append(arg);
}
String s = sb.toString();
ValueOperations valueOperations = redisTemplate.opsForValue();
Object result = null;
if(redisTemplate.hasKey(s)){
result = valueOperations.get(s);
}else{
result = proceedingJoinPoint.proceed();
valueOperations.set(s,result);
}
return result;
}
@After("execution(* com.baizhi.service.*.delete*(..))")
public void after(JoinPoint joinPoint){
Set<String> keys = stringRedisTemplate.keys("*");
for (String key : keys) {
stringRedisTemplate.delete(key);
}
}
注意:
发现key值出现 \xac\xed\x00\x05t\x00\tb,redisTemplate 默认的序列化方式为 jdkSerializeable, StringRedisTemplate的默认序列化方式为StringRedisSerializer
-
基于切自定义注解
-
读操作添加缓存
@Configuration//当前类为配置类
@Aspect//作用是把当前类标识为一个切面供容器读取
public class RedisCache {
@Autowired
private RedisTemplate redisTemplate;
@Around("@annotation(com.baizhi.annotation.SaveRedisCache)")
public Object arround(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
StringBuilder sb = new StringBuilder();
//获取类名
String className = proceedingJoinPoint.getTarget().getClass().getName();
//获取方法名
String methodName = proceedingJoinPoint.getSignature().getName();
sb.append(methodName);
//获取所有的参数
Object[] args = proceedingJoinPoint.getArgs();
for (Object arg : args) {
sb.append(arg);
}
String s = sb.toString();
HashOperations hashOperations = redisTemplate.opsForHash();
Boolean aBoolean = redisTemplate.hasKey(className);
Object result = null;
if(aBoolean){
result = hashOperations.get(className,s);
}else {
result = proceedingJoinPoint.proceed();
HashMap<String, Object> map = new HashMap<>();
map.put(s, result);
hashOperations.putAll(className, map);
redisTemplate.expire(className,10, TimeUnit.SECONDS);
}
return result;
}
2. 写的操作需要清除缓存
@After("@annotation(com.baizhi.annotation.RemoveRedisCache)")
public void after(JoinPoint joinPoint){
String className = joinPoint.getTarget().getClass().getName();
redisTemplate.delete(className);
}