目录
简介
什么是Redis:是一款高性能的NOSQL系列的非关系型数据库
他和mysql这类关系型数据库的区别
优点:
缺点:
redis的应用场景
Redis与其他key-value缓存产品的对比:
Redis优势:
Redis入门
下载:
redis开启:
开启cli:
命令操作:
Redis与数据库
常用命令
字符串常用命令:
哈希常用命令:
列表常用命令:
集合常用命令:
有序集合常用命令:
Redis事务
实例
redis 事务的相关命令:
Redis连接
Redis客户端远程连接工具
Java客户端:Jedis
jedis连接池:JedisPool
使用:
异常:
SpringBoot整合Redis
简介
什么是Redis:是一款高性能的NOSQL系列的非关系型数据库
他和mysql这类关系型数据库的区别
他和mysql这类关系型数据库的区别
NoSQL = Not Only SQL,意即“不仅仅是SQL”,是一项全新的数据库理念,泛指非关系型的数据库。随着互联网web2.0网站的兴起,传统的关系数据库在应付web2.0网站,特别是超大规模和高并发的SNS类型的web2.0纯动态网站已经显得力不从心,暴露了很多难以克服的问题,NoSQL数据库的产生就是为了解决大规模数据集合多重数据种类带来的挑战,尤其是大数据应用难题。
优点:
部署简单,开源免费
nosql数据储存在缓存中,查询速度快
nosql的存储格式是key,value形式,所以可以存储基础类型以及对象或者是集合等各种格式
缺点:
不提供sql支持,学习成本高
关系型数据库与NoSQL数据库并非对立而是互补的关系,一般会将数据存储在关系型数据库中,在nosql数据库中备份存储关系型数据库的数据
Redis是用C语言开发的一个开源的高性能键值对(key-value)数据库
redis的应用场景
缓存(数据查询、短连接、新闻内容、商品内容等等)
聊天室的在线好友列表
任务队列。(秒杀、抢购、12306等等)
应用排行榜
网站访问统计
数据过期处理(可以精确到毫秒
分布式集群架构中的session分离
Redis与其他key-value缓存产品的对比:
- Redis支持数据持久化,可以将内存中的数据保存在磁盘中,重启时可以再次加载进行使用。
- Reids不仅仅支持简单的key-value类型数据,同时提供list,set,zset,hash等数据结构存储
- Redis支持数据的备份,即master-slave模式的数据备份
Redis优势:
- 性能极高,redis能读取速度是110000次/s,写的速度是81000次/s
- 丰富的数据类型-redis支持二进制案例的strings,lists,hashes,sets以及order sets数据类型操作
- 原子-redis所有操作都是原子性的,意思就是要么成功执行要么失败执行,单个操作是原子性的,多个操作也支持事务,即原子性,通过multi和exec指令包起来
- 丰富的特性-redis支持publish/subscribe,通知,key过期等等特性
- 还支持一种脚本语言-lua脚本
Redis入门
下载:
- 官网:Redis (外网,速度慢,不建议下载)
- 中文网:Redis中文网 (建议从中文网下载)
- 性能极高,redis能读取速度是110000次/s,写的速度是81000次/s
- 丰富的数据类型-redis支持二进制案例的strings,lists,hashes,sets以及order sets数据类型操作
- 原子-redis所有操作都是原子性的,意思就是要么成功执行要么失败执行,单个操作是原子性的,多个操作也支持事务,即原子性,通过multi和exec指令包起来
- 丰富的特性-redis支持publish/subscribe,通知,key过期等等特性
- 还支持一种脚本语言-lua脚本
Redis入门
下载:
- 官网:Redis (外网,速度慢,不建议下载)
- 中文网:Redis中文网 (建议从中文网下载)
- 官网:Redis (外网,速度慢,不建议下载)
- 中文网:Redis中文网 (建议从中文网下载)
下载安装:到redis中文网下载,解压即可使用
redis.windows.conf:配置文件
redis-cli.exe:redis的客户端
redis-server.exe:redis服务器端
redis开启:
开启cli:
命令操作:
存储和读取
获取所有配置项:
config get * (*代表所有配置项)
redis的数据结构:
redis存储的是:key,value格式的数据,其中key都是字符串,value有5中不同的数据结构
value的5种数据结构:
字符串类型:String
哈希类型:hash:map形式
列表类型:list:linkedlist格式,支持重复元素
集合类型:set:不允许重复元素
有序集合类型:sortedset:不允许重复元素,并且元素有序
String类型:
存储:set key value 如: set username zhangsan
获取:get key
删除:del key
hash类型:
存储:hset key field value 如:hset myhash username lisi
获取:hget key field :获取指定field对应的值
Hgetall key :获取key里面所有的value
删除:hdel key field
list类型:可以添加一个元素到列表的头(左)部或尾(右)部
添加:lpush/rpush key value
获取:lrange key start end:范围获取 如:lange list 0 -1(代表获取list所有value)
删除:lpop/rpop key:删除该元素,并返回该元素
set类型:
存储:sadd key value
获取:smembers key
删除:srem key value
sortedset类型:不允许重复元素,且元素有顺序.每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序
存储:zadd key score value
获取:zrange key start end [withscore(//获取带分数的值)]
删除:zrem key value
通用命令:
keys *:查询所有的键
type key:获取键对应的value类型
del key:删除指定的key value
持久化:
redis是一个内存数据库,当redis服务器重启,获取电脑重启,数据会丢失,我们可以将redis内存中的数据持久化保存到硬盘的文件中。
redis持久化机制:
RDB:默认方式:在一定的间隔时间中,检测key的变化情况,然后持久化数据
编辑redis.windwos.conf文件
save 900 1
save 300 10
save 60 10000
重新启动redis服务器,并指定配置文件名称
D:rediswindows-64redis-2.8.9>redis-server.exe redis.windows.conf
AOF:日志记录的方式,可以记录每一条命令的操作。可以每一次命令操作后,持久化数据
编辑redis.windwos.conf文件
appendonly no(关闭aof) --> appendonly yes (开启aof)
appendfsync always : 每一次操作都进行持久化
appendfsync everysec : 每隔一秒进行一次持久化
appendfsync no : 不进行持久化
Redis与数据库
Redis是一个字典结构key-value的存储服务器,而实际上一个redis实例提供了多个用来存储数据的字典,客户端可以指定将数据存储在哪个字典中。
Redis默认支持16个数据库(可以通过配置文件支持更多,无上限),可以通过databases修改,客户端与redis建立连接后会自动选择0号数据库,不过可以使用select命令更换数据库
例(切换连接1号数据库):select 1
这些以数字命名的数据库和我们理解的数据库有区别。
首先redis不支持自定义数据的名字,每个数据库都以编号命名,开发者必须自己记录那些数据库存储了哪些数据。
另外redis不支持为每个数据库设置不同的访问密码,客户端要么可以访问全部数据库,要么连一个数据库也没有权限访问。最重要的一点是多个数据库之间并不是完全隔离的,比如FLUSHALL命令清空一个redis实例中所有数据库中的数据。
所以这些数据库更像一个命名空间,而不适宜存储不同应用程序的数据, 不同的应用应该使用不同的redis实例存储数据,由于redis十分轻量级,一个空redis实例占用内存1m左右,所以不用担心多个redis实例会额外占用很多内存。
在远程服务上执行命令:
语法:redis-cli -h host -p port -a password
实例:redis-cli -h 127.0.01 -p 6379 -a "mypass"
中文乱码问题:redic-cli --raw -h 127.0.0.1 -p 6379
常用命令
字符串常用命令:
删除key:del key
序列化:dump key
检查存在:exists key
设置过期时间:expire key seconds
设置过期时间(时间戳):expireat key timestamp
设置key过期时间(毫秒):pexpire key milliseconds
设置key过期时间错(unix timestamp)以毫秒计算:pexpireat key milliseconds-timestamp
查找所有符合给定模式的key:keys pattern
将当前数据库的key移动到给定的数据库db当中:move key db
移除key过期时间,key将永久保持:persist key
以毫秒返回key过期时间:pttl key
以秒返回key剩余生存时间:ttl key
从数据库中随机返回一个key:randomkey
修改key名称:rename key newkey
当newkey不存在时,将key改为newkey:renamenx key newkey
返回key所存储的值类型:type key
设置指定key值:set key value
获取指定key值:get key
返回key字符串值的子字符:getrange key start end
将给定key值设为value,并返回key的旧值(old value):getset key value
对key所储存的字符串值,获取指定偏移量上的位(bit):getbit key offset
获取所有给定key值:mget key1 【key2...】
对key所存储的字符串值,设置或清除指定偏移量的位(bit):setbit key offset value
将值关联key,将key过期时间设为seconds(秒为单位):setex key seconds value
只有在key不存在时设置key值:setnx key value
用value参数覆写给定key所储存的字符串值,从偏移量offset开始:setrange key offset value
返回key所存储字符串值长度:strlen key
同时设置一个或多个key-value对:mset key value【key value..】
同时设置一个或多个key-value对,当且仅当所有给定key都不存在:msetnx key value 【key value...】
这个命令与setex命令相似,但他以毫秒为单位设置key的生存时间,而不是像setex命令那样,以秒为单位:psetex key milliseconds value
将key中储存的数字值增一:incr key
哈希常用命令:
删除一个或多个哈希表字段:hdel kye field1 [field2...]
查看哈希表key中,指定字段是否存在:hexists key field
获取存储哈希表中指定字段的值:hget key field
获取哈希表中指定key的所有字段和值:hgetall key
为哈希表key中指定字段的整数值加上增量increment:hincrby key field increment
为哈希表key中指定字段的浮点数值增加上增量increment:hincrbyfloat key field increment
获取所有哈希表中的字段:hkeys key
获取哈希表中字段的数量:hlen key
获取所有给定字段的值:hmget key field 【field2】
同时将多个field-value(域-值)对设置到哈希表key中:hmset key field1 value1 【field2 value2】
将哈希表中key中字段field的值设为value:hset key field value
只有在字段field不存在时,设置哈希表中字段的值:hsetnx key field value
获取哈希表中所有值:hvals key
迭代哈希表中的键值对:hscan key cursor 【match pattern】【count count】
列表常用命令:
移出并获取列表第一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止:blpop key1 【key2...】 timeout
移出并获取列表最后一个元素,如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止:brpop key1 【key2...】 timeout
从列表中弹出一个值,将弹出的元素插入到另外一个列表中并返回他,如果列表没有元素会阻塞列表知道等待超时或发现可弹出元素为止:brpoplpush source destination timeout
通过索引获取列表中的元素:lindex key index
在列表的元素前或者后插入元素:linsert key before|after pivot value
获取列表长度:llen key
移出并获取列表的第一个元素:lpop key
移出并获取列表的最后一个元素:rpop key
将一个或多个值插入到列表头部:lpush key value1 [value2]
将一个值插入到已存在的列表头部:lpushx key value
获取列表指定范围内的元素:lrange key start stop
移除列表元素:lrem key count value
通过索引设置列表元素的值:lset key index value
对一个列表进行修剪(trim),让列表只保留指定区间内的元素,不在指定区间之内元素都会被删除:ltrim key start stop
移除列表最后一个元素,并将该元素添加到另一个列表返回:rpoplpush source destination
在列表中添加一个或多个值:rpush key value1 【value2】
为已存在的列表添加值:rpushx key value
集合常用命令:
向集合添加一个或多个成员:sadd key mumber1 【member2...】
获取集合的成员数:scard key
返回给定所有集合的差集:sdiff key1 【key2】
返回给定所有集合的差集并存储在destination中:sdiffstore destination key1 【key2】
返回给定所有集合的交集:sinter key1 【key2】
返回给定所有集合的交集并存储在destination中:sinterstore destination key1 【key2】
判断number元素是否是集合key的成员:sismember key member
返回集合所有元素:smembers key
将member元素从source集合移动到destination集合:smove source destination member
移除并返回集合中的一个随机元素:spop key
返回集合中一个或多个随机数:srandmember key 【count】
移除集合中一个或多个成员:srem key member1 【member2】
返回所有给定集合的并集:sunion key1 【key2】
所有给定集合的并集存储在destination集合中:sunionstore destination key1 【key2】
迭代集合中的元素:sscan key cursor 【MATCH pattern】【count count】
有序集合常用命令:
向有序集合添加一个或多个成员,或更新已存在成员的分数:zadd key score1 member1 【score2 member2】
获取有序集合的成员数:zcard key
计算在有序集合中指定区间分数的成员数:zcount key min max
有序集合中对指定成员的分数加上增量increment:zincrby key increment member
计算给定的一个或多个有序集的交集并将结果集存储在新的有序集合key中:zinterstore destination numkeys key 【key...】
在有序集合中计算指定字典区间内成员数量:zlexcount key min max
通过索引区间返回有序集合指定区间内的成员:zrange key start stop【withscores】
通过字段区间返回有序集合的成员:zrangebylex key min max【limit offset count】
通过分数返回有序集合指定区间内的成员:zrangebyscore key min max【withscores】【limit】
返回有序集合中指定成员的索引:zrank key member
移除有序集合中一个或多个成员:zrem key member 【member...】
移除有序集合中给定的字典区间所有成员:zremrangebylex key min max
移除有序集合中给定的排名区间的所有成员:zremrangebyrank key start stop
移除有序集合中给定的分数区间的所有成员:zremrangebyscore key min max
返回有序集合中指定区间内的成员,通过索引,分数从高到低:zrevrange key start stop【withscores】
返回有序集合中指定分数区间内的成员,分数从高到低排序:zrevrangebyscore key max min【withscores】
返回有序集合中指定成员的排名,有序集合成员按分数值递减(从大到小)排序:zrevrank key member
返回有序集合,成员的分数值:zscore key member
计算给定的一个或多个有序集的并集,并存储在新的key中:zunionstore destination numkeys key【key...】
迭代有序集合中的元素(包括元素成员和元素分值):zscan key cursor【match pattern】【count count】
Redis事务
事务可一次执行多个命令,并带有以下三个重要保证:
- 批量操作在发送exec命令前被放入队列缓存。
- 收到exec命令后进入事务执行,事务中任意命令执行失败,其余命令依然被执行。
- 在事务执行过程,其他客户端提交的命令请求不会插入到事务执行命令序列中。
一个事务从开始到执行会经历以下三个阶段:
- 开始事务
- 命令入队
- 执行事务
实例
以下是一个事务的例子, 它先以 MULTI 开始一个事务, 然后将多个命令入队到事务中, 最后由 EXEC 命令触发事务, 一并执行事务中的所有命令:
redis 127.0.0.1:6379> MULTI OK redis 127.0.0.1:6379> SET book-name "Mastering C++ in 21 days" QUEUED redis 127.0.0.1:6379> GET book-name QUEUED redis 127.0.0.1:6379> SADD tag "C++" "Programming" "Mastering Series" QUEUED redis 127.0.0.1:6379> SMEMBERS tag QUEUED redis 127.0.0.1:6379> EXEC 1) OK 2) "Mastering C++ in 21 days" 3) (integer) 3 4) 1) "Mastering Series" 2) "C++" 3) "Programming"
单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。
事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。
redis 事务的相关命令:
| 序号 | 命令及描述 |
|---|---|
| 1 | DISCARD 取消事务,放弃执行事务块内的所有命令。 |
| 2 | EXEC 执行所有事务块内的命令。 |
| 3 | MULTI 标记一个事务块的开始。 |
| 4 | UNWATCH 取消 WATCH 命令对所有 key 的监视。 |
| 5 | WATCH key [key ...] 监视一个(或多个) key ,如果在事务执行之前这个(或这些) key 被其他命令所改动,那么事务将被打断。 |
Redis连接
用于连接redis服务
实例:
客户端查看密码:config get requirepass
客户端设置密码:config set requirepass password
客户端授权密码(不授权不能进行设置获取等操作):auth passowrd
退出重新登陆:redis-cli,exe -h 127.0.0.1 -p 6379 -a 123
Redis客户端远程连接工具
RedisDesktopManager
路径:G:s2s2扩展非关系型数据库redis客户端远程连接工具RedisDesktopManager
Java客户端:Jedis
一款java操作redis数据库的工具.
使用步骤:
下载jedis的jar包
获取连接:Jedis jedis = new Jedis("localhost",6379);(空参默认为本机ip和6379默认端口)
maven坐标:
redis.clients jedis3.2.0
操作:jedis.set("username","123");
关闭连接:jedis.close();
基本操作
//创建Jedis实例,连接本地Redis服务
Jedis jedis = new Jedis("127.0.0.1", 6379);
//设置Redis数据库的密码
System.out.println(jedis.auth("123456"));
//获取客户端信息
System.out.println(jedis.getClient());
//清空Redis数据库,相当于执行FLUSHALL命令
System.out.println(jedis.flushAll());
//查看Redis信息,相当于执行INFO命令
System.out.println(jedis.info());
//获取数据库中key的数量,相当于指定DBSIZE命令
System.out.println(jedis.dbSize());
//获取数据库名字
System.out.println(jedis.getDB());
//返回当前Redis服务器的时间,相当于执行TIME命令
System.out.println(jedis.time());
Jedis操作各种redis中的数据结构
String类型:set(),get()
setex(”username“,20,“zhangsan”);可以指定存储指定过期时间的key value
setex使用场景:激活码,验证码,时间到之后会自动删除(过期)
hash类型:map格式
hset(key,field,value)//设置
hget(key,field)//获取
Map
Set
//循环获取全部
list类型:
lpush/rpush//存储
lpush(key,strings...)//从左边存,参数2可写多个,用,隔开
lpop/rpop//弹出(获取)
List
set类型:
sadd(key,mebers...)//参数2可存多个值
smembers获取
sortedset类型://可排序根据score
zadd(key,score,member);
zrange(key,start,end)//一般情况下start为0,end为-1即显示key里的全部按score升序排序
jedis连接池:JedisPool
使用:
导入jar包
(如果要创建配置对象:
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(50);//最大允许连接数
config.setMaxIdle(10);//最大空闲连接
)
创建JedisPool连接池对象JedisPool jedisPool = new JedisPool("localhost",6379);
调用方法getResource()Jedis jedis = jedisPool.getResource();
使用jedis对象的方法
关闭/归还jedis到连接池jedis.close();
注意:使用redis缓存一些不经常发生变化的数据。
数据库的数据一旦发生改变,则需要更新缓存。
数据库的表执行 增删改的相关操作,需要将redis缓存数据情况,再次存入
在service对应的增删改方法中,将redis数据删除。
添加Utils连接池工具类读取配置文件
异常:
redis JedisConnectionException: Could not get a resource from the pool
可能原因:
1.Redis没有启动;
SpringBoot整合Redis:
1.添加SpringBoot Started
org.springframework.boot spring-boot-starter-data-redis
2.添加数据源
dms:
dynamic:
redis:
enabled: true
connection:
# 第一个Redis连接
demo1Redis:
#连接主机
host: 127.0.0.1
#连接端口
port: 6379
#连接数据源
database: 1
#连接超时时间(2000毫秒)
timeout: 2000
jedis:
#使用连接池
pool:
#等待时间
max-wait: 3000
#最大连接数
max-active: 100
#最大空闲连接
max-idle: 20
#最小空闲连接
min-idle: 0
#连接超时时间(3000毫秒)
timeout: 3000
# 第二个Redis连接
demo2Redis:
host: 127.0.0.1
port: 6379
database: 2
timeout: 2000
jedis:
pool:
max-wait: 3000
max-active: 100
max-idle: 20
min-idle: 0
timeout: 3000
3.在启动类上面添加@EnableDynamicRedis注解
@EnableDynamicRedis
@SpringBootApplication
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class);
}
}
4.创建Redis配置类,并测试
@Configuration
public class RedisConfig {
@Resource
private DynamicRedisProvider dynamicRedisProvider;
@Bean(name = "demo1Redis")
public RedisTemplate demo1Redis() {
return new StringRedisTemplate(dynamicRedisProvider.loadRedis().get("demo1Redis"));
}
@Bean(name = "demo2Redis")
public RedisTemplate demo2Redis() {
return new StringRedisTemplate(dynamicRedisProvider.loadRedis().get("demo2Redis"));
}
}



