1.redis常用指令
1.1.String类型
命令 | 说明 | 案例 |
set | 添加key-value | set username admin |
get | 根据key获取数据 | get username |
strlen | 获取key的长度 | strlen key |
exists | 判断key是否存在 | exists name 返回1存在 0不存在 |
del | 删除redis中的key | del key |
Keys | 用于查询符合条件的key | keys * 查询redis中全部的key keys n?me 使用占位符获取数据 keys nam* 获取nam开头的数据 |
mset | 赋值多个key-value | mset key1 value1 key2 value2 key3 value3 |
mget | 获取多个key的值 | mget key1 key2 |
append | 对某个key的值进行追加 | append key value |
type | 检查某个key的类型 | type key |
select | 切换redis数据库 | select 0-15 redis中共有16个数据库 |
flushdb | 清空单个数据库 | flushdb |
flushall | 清空全部数据库 | flushall |
incr | 自动加1 | incr key |
decr | 自动减1 | decr key |
incrby | 指定数值添加 | incrby 10 |
decrby | 指定数值减 | decrby 10 |
expire | 指定key的生效时间 单位秒 | expire key 20 key20秒后失效 |
pexpire | 指定key的失效时间 单位毫秒 | pexpire key 2000 key 2000毫秒后失效 |
ttl | 检查key的剩余存活时间 | ttl key |
persist | 撤销key的失效时间 | persist key |
@Test
public void testString(){
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.set("TF","SMART");
String result = jedis.get("TF");
System.out.println("获取数据:"+result);
}
1.2.hash类型
说明:可以用散列类型保存对象和属性值
例子:User对象{id:2,name:小明,age:19}
命令 | 说明 | 案例 |
hset | 为对象添加数据 | hset key field value |
hget | 获取对象的属性值 | hget key field |
hexists | 判断对象的属性是否存在 | HEXISTS key field 1表示存在 0表示不存在 |
hdel | 删除hash中的属性 | hdel user field [field ...] |
hgetall | 获取hash全部元素和值 | HGETALL key |
hkyes | 获取hash中的所有字段 | HKEYS key |
hlen | 获取hash中所有属性的数量 | hlen key |
hmget | 获取hash里面指定字段的值 | hmget key field [field ...] |
hmset | 为hash的多个字段设定值 | hmset key field value [field value ...] |
hsetnx | 设置hash的一个字段,只有当这个字段不存在时有效 | HSETNX key field value |
hstrlen | 获取hash中指定key的长度 | HSTRLEN key field |
hvals | 获取hash的所有值 | HVALS user |
@Test
public void testHash(){
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.hset("person","name","西门大官人");
jedis.hset("person", "age", "25");
Map<String,String> perMap = jedis.hgetAll("person");
System.out.println(perMap);
//通过hash直接获取对象 通过工具方法 做转化
}
1.3.list类型
说明:Redis中的List集合是双端循环列表,分别可以从左右两个方向插入数据.
List集合可以当做队列使用,也可以当做栈使用
队列:存入数据的方向和获取数据的方向相反
栈:存入数据的方向和获取数据的方向相同
压栈 弹栈
命令 | 说明 | 案例 |
lpush | 从队列的左边入队一个或多个元素 | LPUSH key value [value ...] |
rpush | 从队列的右边入队一个或多个元素 | RPUSH key value [value ...] |
lpop | 从队列的左端出队一个元素 | LPOP key |
rpop | 从队列的右端出队一个元素 | RPOP key |
lpushx | 当队列存在时从队列的左侧入队一个元素 | LPUSHX key value |
rpushx | 当队列存在时从队列的右侧入队一个元素 | RPUSHx key value |
lrange | 从列表中获取指定返回的元素 | LRANGE key start stop Lrange key 0 -1 获取全部队列的数据 |
lrem | 从存于 key 的列表里移除前 count 次出现的值为 value 的元素。 这个 count 参数通过下面几种方式影响这个操作:
| LREM list -2 “hello” 会从存于 list 的列表里移除最后两个出现的 “hello”。 需要注意的是,如果list里没有存在key就会被当作空list处理,所以当 key 不存在的时候,这个命令会返回 0。 |
Lset | 设置 index 位置的list元素的值为 value | LSET key index value |
@Test
public void testList(){
Jedis jedis = new Jedis("127.0.0.1",6379);
jedis.lpush("list","1","2","3","4"); //左侧压栈
String num = jedis.rpop("list");
System.out.println(num);
}
1.4.事务
说明:redis中操作可以添加事务的支持.一项任务可以由多个redis命令完成,如果有一个命令失败导致入库失败时.需要实现事务回滚.
命令 | 说明 | 案例 |
multi | 开始事务 | 127.0.0.1:6379> MULTI OK |
exec | 提交事务 | 127.0.0.1:6379> EXEC OK |
discard | 回滚事务 | 127.0.0.1:6379>DISCARD OK |
@Test
public void testTx(){
Jedis jedis = new Jedis("127.0.0.1",6379);
Transaction transaction = jedis.multi();//开启事务
transaction.set("aa", "aaa");
transaction.set("bb", "bbb");
transaction.set("cc", "ccc");
//transaction.exec(); //事务提交
transaction.discard(); //事务回滚
}
2.redis持久化
将内存中的数据,持久化到磁盘中,当redis启动时先读取持久化文件,将数据恢复到内存中.
2.1RDB模式
- RDB模式是redis中默认的持久化策略
- RDB模式可以定期进行数据备份.(造成数据丢失)
- RDB模式做的是内存的快照(覆盖),持久化速度最快.占用空间小.恢复数据速度快.
- RDB模式中的持久化文件是加密的.
save 900 1 在900秒内,执行一次set操作,则持久化一次
save 300 10 在300秒内,执行10次set操作,则持久化一次
save 60 10000 在60秒内,执行10000次set操作,则持久化一次
持久化文件名称
2.2AOF模式
1.AOF模式不是redis中默认策略,需要人为开启.
2.AOF模式可以实时数据的实时备份.
3.AOF模式记录的用户的全部的执行过程(追加).持久化速度慢.占用空间大.恢复数据速度慢
4.AOF模式中的持久化文件是明文保存.
# appendfsync always 每执行一次set操作则持久化一次 该性能很低
appendfsync everysec 每秒持久化一次
# appendfsync no 不做操作.
开启AOF
持久化文件名称
持久化文件路径
3.spring整合redis
3.1添加依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.2</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.4.1.RELEASE</version>
</dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.4.2</version>
</dependency>
3.2spring配置
<!--为了对象与json转化方便,创建objectMapper对象 -->
<bean id="objectMapper" class="com.fasterxml.jackson.databind.ObjectMapper"/>
<!--spring整合redis -->
<bean id="jedis" class="redis.clients.jedis.Jedis">
<constructor-arg name="host" value="${redis.host}"/>
<constructor-arg name="port" value="${redis.port}"/>
</bean>
4. redis缓存问题
4.1缓存穿透
条件:访问一个不存在的数据
说明:当访问一个不存在的数据时,因为缓存中没有这个key,导致缓存形同虚设.最终访问后台数据库.但是数据库中没有该数据所以返回null.
隐患:如果有人恶意频繁查询一个不存在的数据,可能会导致数据库负载高导致宕机.
总结:业务系统访问一个不存在的数据,称之为缓存穿透.
4.2.缓存击穿
条件:当缓存key失效/过期/未命中时,高并发访问该key
说明:如果给一个key设定了失效时间,当key失效时有一万的并发请求访问这个key,这时缓存失效,所有的请求都会访问后台数据库.称之为缓存击穿.
场景:微博热点消息访问量很大,如果该缓存失效则会直接访问后台数据库,导致数据库负载过高.
4.3.缓存雪崩
条件:高并发访问,缓存命中较低或者失效时
说明:假设缓存都设定了失效时间,在同一时间内缓存大量失效.如果这时用户高并发访问.缓存命中率过低.导致全部的用户访问都会访问后台真实的数据库.
场景:在高并发条件下.缓存动态更新时