初识Redis
初识Redis
什么是Redis数据库
基于内存的key - vaule结构数据库(非关系型)
- Redis5及之前是单线程版本
- Redis6开始引入多线程版本(实际上是 单线程+多线程 版本)
- key为字符串类型,value有5种常用的数据类型
- 字符串 String:普通字符串
- 列表 list:按照插入顺序排序,可以有重复元素,相当于
Java
中的LinkedList
,先进先出- 哈希 hash:散列,相当于
Java
中的HashMap
- 集合 set:无序,没有重复元素,相当于
Java
中的HashSet
- 有序集合 sorted set/zset:每个元素关联一个分数,通过分数(score)升序排序,没有重复的元素
- 优点
- 适合内存存储,读写性能高
- 适合存储热点数据
- 高可用、分布式
- 企业应用高
如何使用
启动服务器
下载解压后自带的命令工具
1
2
3
4
5 redis-server #用于启动 Redis 的工具
redis-cli #Redis命令行工具
redis-benchmark #用于检测 Redis 在本机的运行效率
redis-check-aof #修复 AOF 持久化文件
redis-check-rdb #修复 RDB 持久化文件命令行工具
redis-cli
1
2
3
4
5
6
7
8 redis-cli -h host -p port -a password
-h 指定远程主机
-p 指定 Redis 服务的端口号
-a 指定密码,未设置数据库密码可以省略-a 选项
若不添加任何选项表示,则使用127.0.0.1:6379连接本机上的Redis数据库测试工具
redis-benchmark
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25 redis-benchmark [选项] [选项值]
-h 指定服务器主机名。
-p 指定服务器端口。
-s 指定服务器 socket
-c 指定并发连接数。
-n 指定请求数。
-d 以字节的形式指定 SET/GET 值的数据大小。
-k 1=keep alive 0=reconnect 。
-r SET/GET/INCR 使用随机 key, SADD 使用随机值。
-P 通过管道传输请求。
-q 强制退出 redis。仅显示 query/sec 值。
–csv 以 CSV 格式输出。
-l 生成循环,永久执行测试。
-t 仅运行以逗号分隔的测试命令列表。
-I Idle 模式。仅打开 N 个 idle 连接并等待。
例:
向 IP 地址为 192.168.184.10、端口为 6379 的 Redis 服务器发送 100 个并发连接与 10 万个请求测试性能
redis-benchmark -h 192.168.184.10 -p 6379 -c 100 -n 100000
测试存取大小为 100 字节的数据包的性能
redis-benchmark -h 192.168.184.10 -p 6379 -q -d 100
测试本机上 Redis 服务在进行 set 与 lpush 操作时的性能
redis-benchmark -t set,lpush -n 100000 -q
- 操作数据类型
字符串常用命令
1
2
3
4 SET key value 设置指定key的值
GET key 获取指定key的值
SETEX key seconds value 设置指定key的值,并将 key 的过期时间设为 seconds 秒
SETNX key value 只有在 key 不存在时设置 key 的值列表常用命令
1
2
3
4
5 LPUSH key value1 [value2] 将一个或多个值插入到列表头部
LRANGE key start stop 获取列表指定范围内的元素
RPOP key 移除并获取列表最后一个元素
LLEN key 获取列表长度
多个元素之间用空格隔开哈希常用命令
1
2
3
4
5
6 hash特别适合用于存储对象
HSET key field value 将哈希表 key 中的字段 field 的值设为 value
HGET key field 获取存储在哈希表中指定字段的值
HDEL key field 删除存储在哈希表中的指定字段
HKEYS key 获取哈希表中所有字段
HVALS key 获取哈希表中所有值集合
1
2
3
4
5
6 SADD key member1 [member2] 向集合添加一个或多个成员
SMEMBERS key 返回集合中的所有成员
SCARD key 获取集合的成员数
SINTER key1 [key2] 返回给定所有集合的交集
SUNION key1 [key2] 返回所有给定集合的并集
SREM key member1 [member2] 删除集合中一个或多个成员有序集合
1
2
3
4 ZADD key score1 member1 [score2 member2] 向有序集合添加一个或多个成员
ZRANGE key start stop [WITHSCORES] 通过索引区间返回有序集合中指定区间内的成员
ZINCRBY key increment member 有序集合中对指定成员的分数加上增量increment
ZREM key member [member ..] 移除有序集合中的一个或多个成员
- 通用命令
1
2
3
4 KEYS pattern 查找所有符合给定模式( pattern)的 key
EXISTS key 检查给定 key 是否存在
TYPE key 返回 key 所储存的值的类型
DEL key 该命令用于在 key 存在是删除 key
- 事务操作
1
2
3
4
5
6
7
8
9 MULTI:标记一个事务快的开始;
EXEC:执行事务块中的所有命令;
DISCARD:取消事务,放弃执行事务块中的所有命令;
UNWATCH:取消 WATCH 命令对所有 key 的监控;
在MULTI和EXEC之间放置多个命令,最后使用EXEC命令来执行这些命令。如果在执行事务期间没有出现错误,所有的命令都会被一次性执行
再Java
中操作Redis
使用Spring Data Redis
- Redis在Java中的客户端常用的几种有Jedis、Lettuce、Spring Data Redis
- Spring Data Redis是Spring的一部分呢,对Redis底层开发包进行了高度封装
- 在Spring项目中可以使用Spring Data Redis来简化操作
使用方式
- 导入maven坐标
1
2
3
4 <dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
- 配置Redis数据源
1
2
3
4
5
6 spring:
redis:
host: ${sky.redis.host}
port: ${sky.redis.port}
database: ${sky.redis.database}
# 通过不同的运行环境配置,dataBase配置的数据库默认是DB0,Redis中默认有0~15个数据库
- 编写配置类,创建RedisTemplate对象
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.StringRedisSerializer;
public class RedisConfiguration {
public RedisTemplate redisTemplate(RedisConnectionFactory redisConnectionFactory){
log.info("开始创建redis模板类");
final RedisTemplate redisTemplate = new RedisTemplate();
//设置key的序列化器默认为JdkSerializationRedisSerializer
redisTemplate.setKeySerializer(new StringRedisSerializer());
redisTemplate.setConnectionFactory(redisConnectionFactory);
// 将 RedisConnectionFactory 设置为 RedisTemplate 使用的连接工厂,这样 RedisTemplate 就可以通过这个工厂获取与 Redis 服务器的连接。
return redisTemplate;
}
}
- 通过RedisTemplate对象操作Redis
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59 redisTemplate.opsForValue() //字符串
redisTemplate.opsForHash() //哈希
redisTemplate.opsForList() //列表
redisTemplate.opsForSet() //集合
redisTemplate.opsForZSet() //有序集合
// 设置字符串值
redisTemplate.opsForValue().set("key", "value");
// 获取字符串值,设置的是什么值就强转为什么
String value = (String) redisTemplate.opsForValue().get("key");
// 哈希的键
String hashKey = "user:1000";
// 设置哈希字段
redisTemplate.opsForHash().put(hashKey, "name", "Kimi");
redisTemplate.opsForHash().put(hashKey, "age", "30");
// 获取哈希字段
String name = (String) redisTemplate.opsForHash().get(hashKey, "name");
Integer age = (Integer) redisTemplate.opsForHash().get(hashKey, "age");
// 列表的键
String listKey = "list";
// 从列表左侧插入元素
redisTemplate.opsForList().leftPush(listKey, "element1");
redisTemplate.opsForList().leftPush(listKey, "element2");
// 从列表右侧插入元素
redisTemplate.opsForList().rightPush(listKey, "element3");
// 从列表左侧弹出元素
String element = (String) redisTemplate.opsForList().leftPop(listKey);
// 集合的键
String setKey = "set";
// 向集合添加元素
redisTemplate.opsForSet().add(setKey, "element1", "element2");
// 获取集合中的所有元素
Set<String> elements = redisTemplate.opsForSet().members(setKey);
// 有序集合的键
String sortedSetKey = "sortedSet";
// 向有序集合添加元素
redisTemplate.opsForZSet().add(sortedSetKey, "element1", 1);
redisTemplate.opsForZSet().add(sortedSetKey, "element2", 2);
// 获取有序集合中的所有元素
Set<String> sortedElements = redisTemplate.opsForZSet().range(sortedSetKey, 0, -1);
// 删除键
redisTemplate.delete("key");
// 检查键是否存在
Boolean exists = redisTemplate.hasKey("key");
// 设置键的过期时间(秒)
redisTemplate.expire("key", 60);
// 开启事务
redisTemplate.multi();
// 在事务中执行多个操作
redisTemplate.opsForValue().set("key1", "value1");
redisTemplate.opsForValue().set("key2", "value2");
// 提交事务
redisTemplate.exec();
Redis和MySQL的区别
- 非关系型和关系型
- 数据模型不同,MySQL是基于二维表,Redis是键值对
- 持久性不同,MySQL存储在磁盘上,Redis存储在内存上(支持持久化到磁盘,持久化机制和MySQL不同)
- 性能不同
- MySQL在处理大量复杂查询和事务性数据时性能较好
- Redis适合处理大量并发读写数据和缓存操作
- MySQL用于持久化存储数据到硬盘,功能强大,但是速度缓慢。
- Redis用于存储使用较为频繁的数据到缓存中,读取速度快。
- 事务支持不同,MySQL支持ACID(原子性、一致性、隔离性、持久性)事务
- Redis 事务在提交之前任何指令都不会实际的被执行,所以不存在MySQL中脏写,脏读,不可重复读,幻读等问题(没有隔离级别的概念)
- Redis 事务不保证原子性,Redis 不能保证所有指令同时成功和失败,可能出现部分指令执行成功但部分指令执行失败的(不保证原子性)
- Redis 在执行事务的过程中,能保证事务内的命令依次执行不被其他命令插入(排它性)
- Redis 事务仅仅保证事务里的操作会被连续独占的执行,Redis 命令执行是单线程架构,在执行事务内所有命令请求之前无法去执行其他客户端请求(单独的隔离操作)
- MySQL偏向于存数据,Redis偏向于快速取数据
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 XiaoYu!
评论