Redis基础
初识Redis
认识NoSQL
SQL:结构化查询语言 => 关系型数据库
NoSQL:非关系型数据库
SQL与NoSQL的差异:
- 数据结构 
- SQL结构化:表的信息依赖于表的结构
 - NoSQL非结构化:存储的信息为KV形式
 
 - 数据关联 
- SQL关联:可以建立并维护表与表之间的关系(外键)
 - NoSQL无关联:需要自行维护数据关联
 
 - 查询方式 
- SQL:使用SQL语句查询
 - NoSQL:没有统一标准(Redis、MongoDB)
 
 - 事物特性 
- SQL:满足ACID
 - NoSQL:基本可用BASE
 
 - 存储方式 
- SQL:磁盘
 - NoSQL:内存(速度快)
 
 - 扩展性 
- SQL:垂直(本机)
 - NoSQL:水平(支持分布式)
 
 
Redis特点
- KV结构
 - 单线程,命令执行具备原子性
 - 低延迟、性能快(基于内存、IO多路复用、C语言编写)
 - 支持数据持久化
 - 支持主从集群(扩展速度)、分片集群(扩展存储量)
 - 支持多语言客户端
 
Redis安装
Redis官方只提供了Linux版本
Redis常见命令
Redis通用命令
KEYS:查看符合模板的所有key
不建议在生产环境(或集群的主节点)上使用。Redis单线程,会导致线程阻塞。
KEYS *name*
 
DEL:删除key
DEL usernameDEL username password
 
EXISTS:判断key存在
EXISTS username
 
EXPIRE:给key设置有效期,单位是秒(到期自动删除)
TTL:查看有效期(-2表示不存在、-1表示永不过期)
EXPIRE name 20TTL name
 
Redis数据结构
- String
 - Hash(类似JSON)
 - List(列表)
 - Set(无重复元素的集合)
 - SortedSet(有序集合)
 - GEO(经纬度坐标)
 - BitMap
 - HyperLog
 
String
字符串,最简单的数据类型。上限是512M。
String的类型
- string:字符串
 - int:整型,可以自增自减
 - float:浮点类型,可以自增自减
 
常见命令
- SET:添加、修改KV
 - GET:通过K查询V
 - MSET:批量添加
 - MGET:批量查询
 - INCR:整型i++(
INCR age:age++) - INCRBY:整型i+=n(
INCRBY age 2:age += 2) - INCRBYFLOAT:浮点i+=n(
INCRBYFLOAT level 2:level += 2) - SETNX:新增KV(若存在K则不添加)
 - SETEX:添加KV,并指定有效期
 
key的结构:层级存储。用于key名称的设置,避免了key重复的问题
项目名:业务名:类型:idhpan:user:username:1 hpan:admin:username:1
Hash
无序字典,类似JSON。
相比于序列化JSON,以字符串形式保存。Hash结构可以更方便地修改。
常见命令
- HSET key field value:添加、修改key的field值(
HSET user:1 username wmh) - HGET key field:查询key的field值(
HSET user:1 username) - HMSET、HMGET:批量
 - HGETALL:查询所有的field和value
 - HKEYS、HVALS:查询所有的field或value
 - HINCRBY:整型value+=n(
HINCRBY user:4 age 2:user[4].age+=2) - HSETNX:新增field-value(若存在K则不添加)
 
List
双向链表,类似于LinkedList。可以正向、反向查找。
- LPUSH/RPUSH key value:左/右侧插入元素
 - LPOP/RPOP key:左/右侧弹出元素
 - LRANGE key i j:从i到j遍历元素
 - BLPOP、BRPOP:阻塞式获取(有元素就取、没有元素就等)
 
- 模拟栈:入口出口在同一边
 - 模拟队列:入口出口不在同一边
 - 模拟阻塞队列:入口出口不在同一边,出队使用BLPOP、BRPOP
 
Set
无序、元素不可重复、查找速度快、支持交集、并集、差集等。
单个Set:
- SADD key item…:添加item
 - SREM key item…:移除item
 - SCARD key:查询元素个数
 - SISMEMBER key item:判断item是否存在
 - SMEMBERS:获取所有元素
 
Set之间:
- SINTER k1 k2:交集
 - SDIFF k1 k2:差集
 - SUNION k1 k2:并集
 
SortedSet
每个元素都带一个score属性,根据score排序。可排序、元素不重复、查询速度快。
- ZADD key score item…:添加item
 - ZREM key item…:移除item
 - ZSCORE key item:查询item的score
 - ZRANK key item:获取item的排名
 - ZCARD key:查询元素个数
 - ZCOUNT key min max:获取分数在min到max的元素个数
 - ZRANGE key i j:获取排名为i到j的元素
 - ZRANGEBYSCORE key min max:获取分数为min到max的元素
 - ZINCRBY key n item:item.score+=n
 - ZDIFF、ZINTER、ZUNION:差集交集并集
 
排名默认为升序,降序排名需要加上REV:ZRANK → ZREVRANK
Redis的Java客户端
客户端介绍
- Jedis:方法命名和Redis命令相似。线程不安全,多线程需要连接池。
 - letture:基于Netty,支持同步、异步和响应式编程方式,线程安全。支持哨兵模式、集群模式和管道模式。
 - Redisson:实现了分布式、可伸缩的Java数据结构。和使用原生集合一样使用Redis集合。
 
SpringDataRedis:整合了Jedis、letture
Jedis
redis/jedis: Redis Java client (github.com)
Jedis使用:
1、引入依赖
<dependency><groupId>redis.clients</groupId><artifactId>jedis</artifactId><version>5.0.0</version>
</dependency>
 
2、建立连接
Jedis jedis = new Jedis("localhost", 6379);
jedis.auth("123.com");
jedis.set("name", "wmhs");
jedis.close();
 
多线程 → 使用Jedis连接池
SpringDataRedis
简介
Spring Data Redis
- 整合Lettuce和jedis
 - 提供了RedisTemplate统一API来操作Redis
 - 支持Redis的发布订阅模型、哨兵、集群
 - 支持基于Lettuce的响应式编程
 - 支持基于JDK、JSON、宇符串、Spring对象的数据序列化及反序列化
 - 支持基于Redis的DKCollection实现
 
SpringDataRedis中提供了RedisTemplate工具类,其中封装了各种对Redis的操作。
不同数据类型的操作API封装到了不同的类型中

自定义RedisSerializer
RedisTemplate可以接收Object作为值写入Redis。
But,采用JDK序列化Object为字节形式。占用内存大、可读性差。
So,可以自行编写RedisSerializer实现(使用jackson)。
But,写入的对象有@class属性,造成了额外开销。
 
StringRedisTemplate
Spring默认提供了一个StringRedisTemplate类,KV的序列化方式默认就是String方式。
如何存对象? → 自行序列化和反序列化
常见的JSON序列化库:
- gson(google 的)
 - fastjson alibaba(阿里,快但是有Bug)
 - jackson
 - kryo
 
使用步骤:
1、导入pom.xml配置
<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>
 
2、配置application.yml
spring:data:redis:port: 6379host: 127.0.0.1password: 123456database: 0timeout: 10000lettuce:pool:enabled: truemax-active: 100max-wait: 10000max-idle: 10min-idle: 1
 
3、编写测试类
不连接数据库启动SpringBoot项目
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
@Test
void StringRedisTemplateTest() {ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();// nameops.set("name", "wmh");System.out.println("name: " + ops.get("name"));// yxops.set("yx", gson.toJson(new User("yx", 18)));String yx = ops.get("yx");System.out.println("yx: " + gson.fromJson(yx, User.class));
}
 
