Redis-Day1基础篇
- 初识Redis
- 认识NoSQL
- 认识Redis
- 安装Redis
- 启动Redis
- Redis客户端
- Redis命令
- 数据结构介绍
- 通用命令
- 操作命令
- String
- Hash
- List
- Set
- SortedSet
- Redis的Java客户端
- 客户端对比
- Jedis客户端
- Jedis快速入门
- Jedis连接池
- SpringDataRedis客户端
- SpringDataRedis概述
- SpringDataRedis快速入门
- RedisTemplate的RedisSerializer
- StringRedisTemplate
- RedisTemplate操作Hash类型
- 来源
- Gitee地址
初识Redis
认识NoSQL
认识Redis
- 键值(key-value)型, value支持多种不同数据结构, 功能丰富
- 单线程, 每个命令具备原子性
- 低延迟, 速度快(基于内存, io多路复用, 良好的编码)
- 支持数据持久化
- 支持主从集群, 分片集群
- 支持多语言客户端
安装Redis
- 安装Redis依赖
yum install -y gcc tcl
- 上传安装包并解压
将压缩包放到/usr/local/src目录下
默认的安装路径在/usr/local/bin目录下, 该目录默认配置环境变量# 解压缩 tar -zxvf redis-6.2.6.tar.gz # 进入redis目录 cd redis-6.2.6 # 运行编译命令 make && make install
redis-cli:是redis提供的命令行客户端 redis-server:是redis的服务端启动脚本 redis-sentinel:是redis的哨兵启动脚本
启动Redis
- 默认启动(前台启动)
redis-server
- 指定配置启动(后台启动)
修改配置文件# 进入redis安装包目录 cd /usr/local/src/redis-6.2.6 # 备份配置文件 cp redis.conf redis.conf.bck
启动Redis# 监听的地址,默认是127.0.0.1,会导致只能在本地访问。修改为0.0.0.0则可以在任意IP访问,生产环境不要设置为0.0.0.0 bind 0.0.0.0 # 守护进程,修改为yes后即可后台运行 daemonize yes # 密码,设置后访问Redis必须输入密码 requirepass 123456 # 监听的端口 port 6379 # 工作目录,默认是当前目录,也就是运行redis-server时的命令,日志、持久化等文件会保存在这个目录 dir . # 数据库数量,设置为1,代表只使用1个库,默认有16个库,编号0~15 databases 1 # 没改 # 设置redis能够使用的最大内存 maxmemory 512mb # 没改 # 日志文件,默认为空,不记录日志,可以指定日志文件名 logfile "redis.log"
# 进入redis安装目录 cd /usr/local/src/redis-6.2.6 # 启动 redis-server redis.conf
- 开机自启
首先, 新建一个配置文件
内容如下vi /etc/systemd/system/redis.service
然后重载系统服务[Unit] Description=redis-server After=network.target[Service] Type=forking ExecStart=/usr/local/bin/redis-server /usr/local/src/redis-6.2.6/redis.conf PrivateTmp=true[Install] WantedBy=multi-user.target
现在,我们可以用下面这组命令来操作redis了systemctl daemon-reload
执行下面的命令,可以让redis开机自启# 启动 systemctl start redis # 停止 systemctl stop redis # 重启 systemctl restart redis # 查看状态 systemctl status redis
systemctl enable redis
Redis客户端
-
命令行客户端
redis-cli [options] [commonds]
常见的options有
-h 127.0.0.1
: 指定要连接的redis节点的ip地址, 默认127.0.0.1-p 6379
: 指定要连接的redis节点的端口, 默认6379-a 123456
: 指定redis的访问密码- 安全的密码验证方式: 启动
redis-cli
后输入AUTH 123456
commonds是redis的操作命令
ping
: 与redis服务端做心跳测试, 服务端支持会返回pong
- 不知道commond时, 进入
redis-cli
的交互控制台
选择库
select 0
-
图形化客户端
安装包: https://github.com/lework/RedisDesktopManager-Windows/releases
Redis命令
数据结构介绍
通用命令
keys
: 查看符合模板的所有key, 不建议在生产环境设备上使用del
: 删除一个指定的keyexists
: 判断key是否存在expire
: 给一个key设置有效期, 有效期到期时该key会被自动删除ttl
: 查看一个key的剩余有效期(-2表示不存在, -1表示永久)
操作命令
String
value是字符串类型, 底层都是字节数组形式存储, 分为3类:
string
: 普通字符串int
: 整数类型, 可以自增减float
: 浮点类型, 可以自增减
常见命令
SET
: 添加或者修改已经存在的一个string类型的键值对GET
: 根据key获取String类型的valueMSET
: 批量添加多个String类型的键值对MGET
: 根据多个key获取多个String类型的valueINCR
: 让一个整型的key自增1INCRBY
: 让一个整型的key自增并指定步长,例如:incrby num 2
让num值自增2INCRBYFLOAT
: 让一个浮点类型的数字自增并指定步长SETNX
: 添加一个String类型的键值对,前提是这个key不存在,否则不执行SETEX
: 添加一个string类型的键值对,并且指定有效期
Redis的key的格式(建议)
[项目名]:[业务名]:[类型]:[id]
Hash
Hash类型, value是一个无序字典, 与java的HashMap类似
- 场景: string结构是将对象序列化为JSON字符串后存储, 修改某个字段不方便
常见命令
HSET key field value
: 添加或者修改hash类型key的field的值HGET key field
: 获取一个hash类型key的field的值HMSET
: 批量添加多个hash类型key的field的值HMGET
: 批量获取多个hash类型key的field的值HGETALL
: 获取一个hash类型的key中的所有的field和valueHKEYS
: 获取一个hash类型的key中的所有的fieldHVALS
: 获取一个hash类型的key中的所有的valueHINCRBY
: 让一个hash类型key的字段值自增并指定步长HSETNX
: 添加一个hash类型的key的field值,前提是这个field不存在,否则不执行
List
与java的LinkedList类似, 可以看作是双向链表结构. 支持双向检索
- 有序
- 元素可以重复
- 插入和删除快
- 查询速度一般
常用语法
LPUSH key element ...
: 向列表左侧插入一个或多个元素LPOP key
: 移除并返回列表左侧的第一个元素,没有则返回nilRPUSH key element ...
: 向列表右侧插入一个或多个元素RPOP key
: 移除并返回列表右侧的第一个元素LRANGE key starend
: 返回一段角标范围内的所有元素BLPOP和BRPOP
: 与LPOP和RPOP类似,只不过在没有元素时等待指定时间,而不是直接返回nil
Set
与java的HashSet类似
- 无序
- 元素不可重复
- 查找快
- 支持交集, 并集, 差集等功能
常见命令
SADD key member ...
: 向set中添加一个或多个元素SREM key member ...
: 移除set中的指定元素SCARD key
: 返回set中元素的个数SISMEMBER key member
: 判断一个元素是否存在于set中SMEMBERS
: 获取set中的所有元素SINTER key1 key2 ...
: 求key1与key2的交集SDIFF key1 key2...
: key1与key2的差集SUNION key1 key2..
: 求key1和key2的并集
SortedSet
是一个可排序的set集合, 与java中的TreeSet有些类似, 但底层数据结构差别很大.SortedSet中的每一个元素都带有一个score属性, 基于score属性对元素排序, 底层是一个跳表(SkipList)加Hash表.
- 可排序
- 元素不重复
- 查询速度快
可用来实现排行榜的功能
常见命令
ZADD key score member
: 添加一个或多个元素到sorted set,如果已经存在则更新其score值ZREM key member
: 删除sorted set中的一个指定元素ZSCORE key member
: 获取srted set中的指定元素的score值ZRANK key member
: 获取sorted set 中的指定元素的排名ZCARD key
: 获取sorted set中的元素个数ZCOUNT key min max
: 统计score值在给定范围内的所有元素的个数ZINCRBY key increment member
: 让sorted set中的指定元素自增,步长为指定的increment值ZRANGE key min max
: 按照score排序后,获取指定排名范围内的元素ZRANGEBYSCORE key min max
: 按照sore排序后,获取指定score范围内的元素ZDIFF、ZINTER、ZUNION
: 求差集、交集、并集- 注意: 默认升序, 降序需要在命令的
Z
后面添加REV
:ZREVRANK
Redis的Java客户端
客户端对比
Spring Data Redis 整合了 Jedis 和 lettuce
Jedis客户端
Jedis快速入门
- 引入依赖
<!-- Jedis --> <dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>3.7.0</version> </dependency> <!-- 单元测试 --> <dependency><groupId>org.junit.jupiter</groupId><artifactId>junit-jupiter</artifactId><version>5.7.0</version><scope>test</scope> </dependency> <!-- lombok --> <dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.18</version><scope>test</scope> </dependency>
- 使用
import lombok.extern.slf4j.Slf4j; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import redis.clients.jedis.Jedis;import java.util.Map;@Slf4j public class JedisTest {private Jedis jedis;// 1. 建立连接@BeforeEachvoid setUp(){// 建立连接jedis = new Jedis("192.168.174.133", 6379);// 密码验证jedis.auth("123456");// 选择库, 默认0jedis.select(0);}// 4. 释放资源@AfterEachvoid tearDown(){// 释放资源if(jedis != null){jedis.close();}}// 2. 测试String@Testvoid testString(){// 插入数据, 方法名就是redis命令名String res = jedis.set("name", "zhangsan");System.out.println("result = " + res);// 获取数据String name = jedis.get("name");System.out.println("name = " + name);}// 3. 测试Hash@Testvoid testHash() {// 插入数据jedis.hset("user:1", "name", "tom");jedis.hset("user:1", "age", "20");// 获取数据Map<String, String> map = jedis.hgetAll("user:1");System.out.println(map);} }
Jedis连接池
- 工具类
import redis.clients.jedis.Jedis; import redis.clients.jedis.JedisPool; import redis.clients.jedis.JedisPoolConfig;public class JedisConnectionFactory {private static final JedisPool jedisPool;static {JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();// 最大连接jedisPoolConfig.setMaxTotal(8);// 最大空闲连接jedisPoolConfig.setMaxIdle(8);// 最小空闲连接jedisPoolConfig.setMinIdle(0);// 设置最长等待时间, msjedisPoolConfig.setMaxWaitMillis(200);jedisPool = new JedisPool(jedisPoolConfig, "192.168.174.133", 6379,1000, "123456");}public static Jedis getJedis(){return jedisPool.getResource();} }
- 使用
... public class JedisTest {private Jedis jedis;// 建立连接@BeforeEachvoid setUp(){// 建立连接// jedis = new Jedis("192.168.174.133", 6379);jedis = JedisConnectionFactory.getJedis();...}... }
SpringDataRedis客户端
SpringDataRedis概述
SpringData是Spring中数据操作的模块,包含对各种数据库的集成,其中对Redis的集成模块就叫做SpringDataRedis
官网地址: https://spring.io/projects/spring-data-redis
- 提供了对不同Redis客户端的整合 (Lettuce和Jedis)
- 提供了RedisTemplate统一API来操作Redis
- 支持Redis的发布订阅模型
- 支持Redis哨兵和Redis集群
- 支持基于Lettuce的响应式编程
- 支持基于JDK、JSON、字符串、Spring对象的数据序列化及反序列化
- 支持基于Redis的JDKCollection实现
SpringDataRedis提供了RedisTemplate工具类
SpringDataRedis快速入门
- 引入依赖
<!-- Redis依赖 --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <!-- 连接池依赖 --> <dependency><groupId>org.apache.commons</groupId><artifactId>commons-pool2</artifactId> </dependency>
- 配置文件
spring:data:redis:host: 192.168.174.133port: 6379password: 123456lettuce:pool:max-active: 8 # 最大连接max-idle: 8 # 最大空闲连接min-idle: 0 # 最小空闲连接max-wait: 100 # 设置最长等待时间, ms
- 使用
@SpringBootTest class SpringdataredisDemoApplicationTests {@Autowiredprivate RedisTemplate redisTemplate;@Testvoid testString() {// 插入一条string类型数据redisTemplate.opsForValue().set("name", "李四");// 读取一条string类型数据Object name = redisTemplate.opsForValue().get("name");System.out.println("name = " + name);}}
RedisTemplate的RedisSerializer
RedisTemplate可以接收任意Object作为值写入Redis, 但是写入前会把Object序列化为字节形式, 默认是采用JDK序列化
- 可读性差
- 内存占用较大
使用JSON序列化, 配置类如下:
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.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;@Configuration
public class RedisConfig {@Beanpublic RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory redisConnectionFactory){// 创建RedisTemplate对象RedisTemplate<String, Object> redisTemplate = new RedisTemplate<>();// 设置连接工厂redisTemplate.setConnectionFactory(redisConnectionFactory);// 创建JSON序列化工具GenericJackson2JsonRedisSerializer jsonRedisSerializer = new GenericJackson2JsonRedisSerializer();// 设置Key的序列化redisTemplate.setKeySerializer(RedisSerializer.string());redisTemplate.setHashKeySerializer(RedisSerializer.string());// 设置Value的序列化redisTemplate.setValueSerializer(jsonRedisSerializer);redisTemplate.setHashValueSerializer(jsonRedisSerializer);// 返回return redisTemplate;}}
StringRedisTemplate
- JSON序列化器会将类的class类型写入json结果中, 插入redis, 会带来额外的内存开销
- 统一使用String序列化器, 要求只能存储String类型的key和value, 需要存储对象时, 手动完成对象的序列化和反序列化
- Spring默认提供了StringRedisTemplate类
@SpringBootTest class StringRedisTemplateTests {@Autowiredprivate StringRedisTemplate stringRedisTemplate;// SpringMVC框架默认使用的JSON处理工具private static final ObjectMapper mapper = new ObjectMapper();@Testvoid testSaveUser() throws JsonProcessingException {// 创建对象User user = new User("jerry", 21);// 手动序列化String json = mapper.writeValueAsString(user);// 写入数据stringRedisTemplate.opsForValue().set("user:2", json);// 获取数据String jsonUser = stringRedisTemplate.opsForValue().get("user:2");// 手动反序列化User user1 = mapper.readValue(jsonUser, User.class);System.out.println("user1 = " + user1);} }
RedisTemplate操作Hash类型
...@SpringBootTest
class StringRedisTemplateTests {@Autowiredprivate StringRedisTemplate stringRedisTemplate;...@Testvoid testHash() {stringRedisTemplate.opsForHash().put("user:3", "name", "tom");stringRedisTemplate.opsForHash().put("user:3", "age", "21");Map<Object, Object> entries = stringRedisTemplate.opsForHash().entries("user:3");System.out.println(entries);}
}
来源
黑马程序员. Redis入门到实战教程
Gitee地址
https://gitee.com/Y_cen/redis