一、Redis概述
(一)、Redis介绍
- Redis百度百科如下介绍
Redis(Remote Dictionary Server ),即远程字典服务,是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。
- Redis官方文档是如下介绍
Redis 是一个开源(BSD许可)的,内存中的数据结构存储系统,它可以用作数据库、缓存和消息中间件。 它支持多种类型的数据结构,如 字符串(strings), 散列(hashes), 列表(lists), 集合(sets), 有序集合(sorted sets) 与范围查询, bitmaps, hyperloglogs 和 地理空间(geospatial) 索引半径查询。 Redis 内置了 复制(replication),LUA脚本(Lua scripting), LRU驱动事件(LRU eviction),事务(transactions) 和不同级别的 磁盘持久化(persistence), 并通过 Redis哨兵(Sentinel)和自动 分区(Cluster)提供高可用性(high availability)。网址如下
(二)、安装与启动
在Linux系统的Ubuntu上首先要有docket容器
在Linux系统中输入便安装完成。注意使用下述命令的时候不是最高权限的时候要使用sudo
docker run --name redis -d -it -p 16379:6379 redis --requirepass "aaa" --appendonly yes
其中命令解释如下
docker run
: 运行 Docker 容器的命令。--name redis
: 为容器指定一个名称为 "redis"。-d
: 在后台运行容器。-it
: 分配一个伪终端(pseudo-TTY)并保持 STDIN 打开。-p 16379:6379
: 将宿主机的端口 16379 映射到容器内的端口 6379。redis
: 指定要运行的镜像为 Redis。--requirepass "aaa"
: 设置 Redis 的密码为 "aaa"。--appendonly yes
: 开启 Redis 的 AOF(Append Only File)持久化。
(三)、Redis特性
- 速度快
单节点读 110000次/s,写81000次/s- 数据存放内存中
- 用 C 语言实现,离操作系统更近
- 单线程架构,6.0 开始支持多线程(CPU、IO 读写负荷)
- 持久化
- 数据的更新将异步地保存到硬盘(RDB 和 AOF)
- 多种数据结构 - 不仅仅支持简单的 key-value 类型数据,还支持:字符串、hash、列表、集合、有序集合。
- 原子性-所有的redis单个命令都是具有原子性
- 支持多种编程语言
- 功能丰富
- HyperLogLog、GEO、发布订阅、Lua脚本、事务、Pipeline、Bitmaps,key 过期 - 简单稳定
- 源码少、单线程模型 - 主从复制
- Redis 支持数据的备份(master-slave)与集群(分片存储),以及拥有哨兵监控机制。
- Redis 的所有操作都是原子性的,同时 Redis 还支持对几个操作合并后的原子性执行。
二、常用的五大数据类型
通用的全局命令
- key * //查看库中所以的key
- exists keyname //判断指定的key是否存在
- type keyname //查看指定key的数据类型
- del keyname //删除指定的key数据
- unlink keyname //非阻塞删除指定的key数据
- expire keyname time //给指定的key设置过期时间,单位默认是s
- ttl keyname //查看指定key的过期时间
- select index //切换数据库,index是库索引
- dbsize //查看当前数据库的key数量
- flushdb //清空当前库的所有键值对,其他库的不影响
- flushall //清空所有空的键值对
(一)、字符串(String)
String 类型是Redis中最简单的存储类型,是动态的也是二进制安全的。
根据字符串的格式不同,又分为三类,String:普通字符串、int:整数类型、float:浮点类型;其中int和float类可做进行自增自减操作。无论那种格式在Redis的字符串底层都是字节数组的形式来存储,字符串类型的最大存储空间不能超过512M。
常用命令
- set keyname value //添加键值对
- get keyname //查询指定键的值
- setex keyname time value //设置带过期时间的键值对-默认秒
- incr keyname //将指定键的值自增1,如果键不存在,则会创建一个新的键,并将其初始值设置为 1。如果键存在但存储的值不是数字,或者无法被解析为数字,则会返回错误。
- mset keyname value··· //批量添加多个键值对
- mget keyname ··· //批量获得多个指定键的值
- incrby/decrby keyname step-length //自增或自减自定义步长的指定键(int)
- incrbyfloat keyname step-lenth //自增自定义步长的指定键(float)
- msetnx keyname value··· //设置一个或多个键值对,已存在则失败
- msetex keyname value time //设置键值对并指定过期时间
- append keyname value //给指定的键追加值内容
- getrange keyname start end //根据给定的起始位置和结束位置进行截取子字符串
- setrange keyname offset value //将指定键的字符串值的子字符串替换为给定的值
(二)、列表(LIst)
Redis列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。
它的底层实际是个双向链表,对两端的操作性能很高,通过索引下标的操作中间的节点性能会较差。
特征与LinkedList类似:有序、元素可以重复、插入和删除快、查询慢。
常用命令
- lpush/rpush keyname value··· //从左边或者右边插入一个或多个值
- lpop/rpop keyname //用于从列表的头部或尾部移除并返回一个元素
- rpoplpush keyname1 keyname2 //将列表的头部一个元素移除并插到列表的尾部
- lrange keyname int int //获取列表中指定范围内的所有元素 0到-1表示所有元素
- llen keyname //获取列表的长度(即元素个数)
- lindex kenyanme indexint //获取列表中指定索引位置上的元素值
- linsert keyname before/after value newvalue //在列表中指定元素的前面或后面插入一个新元素
- lrem keyname int value //从列表中移除指定个数的指定元素 小于0表示聪尾部删除和value相同的元素;等于0表示则从列表的头部开始向尾部搜索,删除与
value
相等的元素,直到删除了count
个元素为止;如果count
大于0,则从列表的头部开始向尾部搜索,删除与value
相等的元素,直到删除了count
个元素为止。- lset keyname index value //设置列表中指定索引位置上的元素值
(三)、集合(Set)
Redis的集合(Set)是一种无序、唯一性的数据结构,即没有索引和位置的概念,它内部存储的是一组不重复的元素。重复的元素会被自动去重。Redis中的集合是通过哈希表实现的,底层是一个 value 为 null 的 hash 表,所以添加、删除和查找操作的时间复杂度都是O(1)。
Redis的集合数据结构非常适合用于处理元素唯一性的场景,例如记录用户的标签、好友关系等。它还提供了丰富的集合操作,方便进行交集、并集、差集等集合运算。
常用命令
- sadd keyname member··· //添加元素到Set中
- smembers keyname //取出集合中的所有元素
- sismember keyname member //判断元素是否存在于Set中
- scard keyname //获取Set的基数(元素个数
- srem keyname member··· //从Set中移除元素
- srandmember keyname int //随机从集合中取出n个值
- spop keyname //随机从集合中移除一个值并返回
- smove keyname keyname value //用于将一个集合中的成员移动到另一个集合中
- sinter keyname keyname //返回两个集合的交集元素
- sunion keyname keyname //返回两个集合的并集元素
- sdiff keyname keyname //返回两个集合的差集,即返回存在于第一个集合但不存在于其他集合的成员
(四)、哈希(Hash)
Redis 中的 Hash 是一种用于存储键值对的数据结构。在 Redis 中,Hash 是一个字符串类型的 field-value 映射表。
Hash 在某些场景下非常适用,比如存储对象的属性、缓存数据、计数器等。它可以快速地进行读取、更新和删除操作,并且适用于存储大量字段的情况。
常用命令
hset keyname field value //
将指定键的指定字段设置为指定的值。如果该字段已存在,则更新其值;如果该字段不存在,则创建新的字段。hset keyname field //
获取指定键的指定字段的值。hdel keyname field1 field2 ... //
删除指定键中的一个或多个字段。hexeists keyname field //
检查指定键中是否存在指定字段。hkeys keyname //
获取指定键中所有字段的列表。hvalues keyname //
获取指定键中所有字段的值的列表。hgetall keyname //
获取指定键中所有字段和对应的值的列表。
(五)有序集合(Zset)
Redis 中的 Zset(Sorted Set)是一种有序集合,它类似于 Set,但是每个元素都会关联一个分数(score),用于对集合中的元素进行排序。
Zset 的应用场景比较广泛,例如排行榜、计数器、范围查询等。在 Redis 中,Zset 内部使用哈希表和跳跃表实现,因此可以支持快速的插入、删除和查找操作。
Redis 的 Zset 是按照分数进行排序的,如果多个成员的分数相同,则按照成员的字典序进行排序。如果需要根据成员的插入顺序来排序,则可以使用 List 类型。
另外,由于 Redis 内部实现 Zset 使用了哈希表和跳跃表,因此它的空间复杂度为 O(N),其中 N 表示元素的数量。如果需要处理大量的元素,需要注意内存占用问题。
zadd keyname score1 member1 score2 member2 …:将一个或多个 member 元素及其 score 值加入到有序集 key 当中
zrange <key><start><stop> [WITHSCORES]
:返回有序集 key 中,下标在 之间的元素当带 WITHSCORES,可以让分数一起和值返回到结果集
zrangebyscore key min max [withscores] [limit offset count]
:返回有序集 key 中,所有 score 值介于 min 和 max 之间(包括等于 min 或 max )的成员。有序集成员按 score 值递增(从小到大)次序排列。
zrevrangebyscore key max min [withscores] [limit offset count]
:同上,改为从大到小排列
zincrby <key><increment><value>
:为元素的 score 加上增量
zrem <key><value>
:删除该集合下,指定值的元素
zcount <key><min><max>
:统计该集合,分数区间内的元素个数
zrank <key><value>
:返回该值在集合中的排名,从 0 开始。
三、Redis融入Java
(一)、Java直接操作Redis
步骤
添加依赖
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency>
连接Redis
public class JedisDemo { public static void main(String[] args) {
Jedis jedis = new Jedis("ip地址", 端口号);
jedis.auth("密码");
String pong = jedis.ping();
System.out.println("连接成功:" + pong);
} }
(二)、spring整合Redis
步骤
添加依赖
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>5.3.25</version>
</dependency><dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.8.0</version>
</dependency><dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>2.7.10</version>
</dependency><dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>5.3.25</version>
</dependency><dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
</dependency>
配置ioc的xml文件
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/context
https://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd"><!-- redis连接池的配置 -->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxTotal" value="500" />
</bean><!-- 工厂类配置 -->
<bean id="jedisConnectionFactory"
class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="81.70.199.213" />
<property name="port" value="6379" />
<property name="password" value="u}J#D=>MryWf" />
<property name="poolConfig" ref="jedisPoolConfig" />
<property name="timeout" value="15000"></property>
<property name="usePool" value="true"></property>
</bean><!-- redisTemplate配置 -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>
</property>
</bean></beans>