- 前言
- 一、Redis安装
- 二、Redis实现session共享测试例子
- 1.导入pom依赖
- 2.application.properties文件中配置
- 3.配置Session的maxInactiveIntervalInSeconds设置session失效时间
- 4.测试
- 三、Redis结合Session实现单点登录测试
- 1.测试代码
- 四、Redis/Linux下的命令
前言
Redis是一个高性能的 key-value 数据库。
Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构的存储。
Redis支持数据的备份,即master-slave模式的数据备份。
一、Redis安装
参考:https://www.runoob.com/redis/redis-install.html
二、Redis实现session共享测试例子 1.导入pom依赖
org.springframework.boot
spring-boot-starter-data-redis
org.springframework.session
spring-session-data-redis
2.application.properties文件中配置
#数据库配置 spring.datasource.driverClassName =com.mysql.cj.jdbc.Driver spring.datasource.url = jdbc:mysql://localhost:3306/jx201005?useSSl=true&useUnicode=true&characterEncoding=UTF-8 spring.datasource.username = name spring.datasource.password = 12 # Redis 配置 # Redis数据库索引(默认为0) spring.redis.database=0 # Redis服务器地址 spring.redis.host=127.0.0.1 # Redis服务器连接端口 spring.redis.port=6379 # Redis服务器连接密码(默认为空) spring.redis.password= # 连接池最大连接数(使用负值表示没有限制) spring.redis.lettuce.pool.max-active=200 # 连接池最大阻塞等待时间(使用负值表示没有限制) spring.redis.lettuce.pool.max-wait=-1 # 连接池中的最大空闲连接 spring.redis.lettuce.pool.max-idle=10 # 连接池中的最小空闲连接 spring.redis.lettuce.pool.min-idle=0 # 连接超时时间(毫秒) spring.redis.timeout=10003.配置Session的maxInactiveIntervalInSeconds设置session失效时间
@Configuration
@EnableRedisHttpSession(maxInactiveIntervalInSeconds = 60000 * 50)
public class SessionConfig {
}
4.测试
@RequestMapping("/setSes")
public Map setSession(HttpServletRequest request) {
Map map = new HashMap<>();
request.getSession().setAttribute("mesg", request.getRequestURL());
map.put("request", request.getRequestURL());
return map;
}
@GetMapping("/getSes")
public Object getSession(HttpServletRequest request) {
Map map = new HashMap<>();
map.put("sessionId", request.getSession().getId());
map.put("mesg", request.getSession().getAttribute("mesg"));
return map;
}
先访问8080端口,并设置session,后再获取session;
再访问9090端口,获取session,与8080端口返回的信息是否一样,一样的话,说明实现了session共享
三、Redis结合Session实现单点登录测试
避免用户在不同页面多次登录
1.测试代码 @RequestMapping("/login")
public String login(HttpServletRequest request, String stuacc, String stuidcard) {
String msg = "遗憾登录失败!";
List user = userService.studentLogin(stuacc, stuidcard);
if (user != null && user.get(0).getStuidcard().equals(stuidcard)) {
request.getSession().setAttribute("user", user);
msg = "恭喜登录成功!";
}
return msg;
}
@RequestMapping("/loginout")
public String loginout(HttpServletRequest request) {
request.getSession().removeAttribute("user");
return "退出登录成功!";
}
@RequestMapping("/index")
public String index(HttpServletRequest request) {
String msg = "index";
Object user = request.getSession().getAttribute("user");
if (user == null) {
msg = "您还未登录,请先登录!";
}
return msg;
}
测试连接:
http://localhost:9090/admin/index
http://localhost:9090/admin/loginout
http://localhost:8080/admin/index
http://localhost:8080/admin/loginout
http://localhost:8080/admin/login?stuacc=100001&stuidcard=350301199201010010
1、9090端口访问index页面,访问失败,此时未登录!
此时,8080端口访问index页面,访问失败,此时未登录!
2、9090端口登录成功后,访问index页面,访问成功
此时,8080访问index页面,访问成功!
3、8080端口退出登录后!
此时,9090端口再访问index,提示您还未登录,请先登录!
四、Redis/Linux下的命令
1.redis-key
redis -service 开启redis服务器
set key value 设置key值
get key 获取key
move key 移除key
keys * 查看所有的key
exists key 查看key是否存在(存在返回1,不存在返回0)
expire key 10 设置key过期时间
ttl key 查看key剩余时间
type key 查看key类型
2.sting类型
append key "kkkk" 追加字符串(返回字符串长度)(如果key不存在,就相当与设置key)
strlen key 获取字符串长度
i++模式:
set views 0 设置浏览量views为0
incr views 自增1
decr views 自减1
步长 i+=:
set views 0 设置浏览量views为0
incrby views 5 指定增加5
decrby views 5 指定减少5
range字符串范围:
getrange key 0 3 截取字符串[0,3]
getrange key 0 -1 获取全部字符串 和 get key 是一样的
getrange key 1 xxx 替换指定位置开始的字符串
setex key 30 "hello" 设置过期时间30,值为hello
setnx key “hello”如果key存在,创建失败返回0;如果key不存在,创建成功返回1(分布式锁中用到)
mset k1 v1 k2 v2 k3 v3 同时设置多个值
mget k1 v1 k2 v2 k3 v3 同时获取多个值
msetnx k1 v1 k4 v4 msetnx是一个原子性的操作,要么一起成功,要么一起失败
mset user:1:name zsan user:1:age 15 设置一个对象的多个值,这是key的一个巧妙设计,user:{id}:{filed}
mget user:1:name user:1:age 获取一个对象的多个值
getset:先get然后再set
getset db redis 如果不存在值,则返回nil
getset db mm 如果存在值,返回原来的值,并设置新的值
Sting使用场景:
计数器
统计多单位的数量 比如id1的关注数
粉丝数
对象缓冲存储
3.list类型
lpush list one 将一个值或者多个值,插入到列表头部(最上面)(左)
lrange list 0 -1 查看list全部值
lrange list 0 1 查看【0,1】的值
lindex list 1 通过下标获取list中的某一个值
rpush list righr 将一个值或者多个值,插入到列表尾部(最底下)(右)
lpop list 移除最上面的值(第一个元素)
rpop list 移除最底下的值(最后一个元素)
llen list 返回列表的长度
lrem list 1 one 移除list集合中1个value为one,例如取关某人
ltrim mylist 1 2 通过下标截取指定的长度,这时list已被修改,只剩截取的元素
rpoplpush mylist otherlist 移除mylist集合里最后一个元素,添加到otherlist集合里
lset list 0 item 将列表中指定下标的值替换为另外一个值,更新操作,如果值不存在则报错,如果值存在则更新当前下标的值
linsert mylist before/after a b 将某个具体的value插入到列中某个元素的前面或者后面
小结:
他实际上是一个链表,before Node after , left , right 都可以插入值如果key不存在,创建新的链表
如果key存在,新增内容
如果移除了所有值,空链表,也代表不存在!
在两边插入或者改动值,效率最高!中间元素,相对来说效率会低一点~
消息排队!消息队列( Lpush Rpop ) ,栈( Lpush Lpop )
4.set类型
sadd myset "hello" set集合中添加元素
smembers myset 查看指定set的所有值
sismember myset hello 判断某一个值是不是在set集合中(不存在返回0,存在返回1)
scard myset 获取set集合中元素个数
srem myset hello 移除set集合中的指定元素
spandmember myset 2 随机选出指定个数的元素
spandmember myset 随机选出一个元素
spop myset 随机删除set集合中一个元素
smove myset myset2 "aaa" 将myset集合中的值aaa,移动到另外一个myset2集合中
sdiff key 1 key2 差集
sinter key1 key2 交集(共通好友)
sunion key1 key2 并集(共通关注)
小结:
微博,A用户将所有关注的人放在一个set集合中!将它的粉丝也放在一个集合中!
共同关注,共同爱好,二度好友,推荐好友!(六度分割理论)
5.hash哈希
hset myhash field1 aaa set一个字段 key-value
hget myhash filed1 获取一个字段值
hmset myhash field1 hello field2 world set多个key-value
hmget myhash field1 field2 获取多个字段值
hgetall myhash 获取全部的数据
hdel myhash field1 删除hash指定key字段,对应的value也消失
hlen myhash 获取hash表的字段数量
hexists myhash field1 判断hash中指定字段是否存在
hkeys myhash 只获取所有的字段名
hvals myhash 只获取所有的值
hset myhash fidld3 5 指定增量
hincrby myhash field3 1 增1
hdecrby myhash field3 1 减1
hsetnx myhash field4 hello 如果值不存在则可以设置,如果值存在则不能设置
小结:
hash变更的数据user name age,尤其是是用户信息之类的,经常变动的信息! hash更适合于对象的存储,String更加适合字符串存储!
6.zset(有序集合)
zadd myset 1 one 添加一个值
zadd myset 2 two 3 three 添加多个值
zrange myset 0 -1
zrangebyscore salary -inf +inf 显示全部的用户,从小到大
zrevrange salary 0 -1 显示全部的用户,从大到小
zrangebyscore salsry -inf +inf withscores 显示全部的用户并附带工资
zrangebyscore salary -inf 2500 withscores 显示工资小于2500员工的升序排序
zrange salary 0 -1
zrange salary xiao 移除有序集合中的指定元素
zcard salary 获取有序集合中的个数
zcount myset 1 3 获取指定区间的成员数量
案例思路: set排序存储班级成绩表,工资表排序!普通消息,1、重要消息 2、带权重进行判断!
排行榜应用实现,取Top N测试!
7.geospatial 地理位置
geoadd china:city 106.50 29.53 chongqin 设置重庆的经纬度
geopos china:city chongqin 获取指定城市的经纬度
geopos china:city chongqin beijing 获取多个城市的经纬度
geodist china:city beijing chongqin km 查看北京到重庆的直线距离
georadius china:city 110 30 500 km 以 110,30 经纬度为中心,寻找500km内的人
georadius china:city 110 30 500 km withdist 显示到中间距离的位置
georadius china:city 110 30 500 km withcoord 显示其他人的定位信息
georadius china:city 110 30 500 km withdist withcoord count 1 筛选出指定的结果
georadius china:city beijing 1000 km 找出位于指定元素周围的其他元素!
geohash china:city beijing chongqin 将二维金纬度转换为一维的字符串,如果两个字符串越接近,那么则距离越近
zrange china:city 0 -1 查看所有china下的city
zrem china:city beijing 移除北京
8.hyperloglog 基数结构(基数:不重复的)
网页的UV(一个人访问一个网站多次,但是还是算作一个人!)
传统的方式,set 保存用户的id,然后就可以统计set 中的元素数量作为标准判断!
这个方式如果保存大量的用户id,就会比较麻烦!我们的目的是为了计数,而不是保存用户id ;
0.81%错误率!统计UV任务,可以忽略不计的!
Redis Hyperloglog 基数统计的算法
pfadd mykey a b c d e f 创建元素
pfcount mykey 统计mykey中元素的基数数量
pfmerge mykey3 mykey mykey2 合并mykey和mykey2=>在mykey3中
小结:
如果允许容错,一定使用Hyperloglog
如果不允许容错,就使用set或者自己的数据类型即可
9.bitmap 位存储
统计用户信息,活跃,不活跃!登录、未登录!打卡,365打卡!两个状态的,都可以使用Bitmaps !Bitmap位图,数据结构!都是操作二进制位来进行记录,就只有0和1两个状态!
365天= 365 bit 1字节= 8bit46个字节左右!
记录周一到周天的打卡:
setbit sign 0 1 0表示周一,1表示已打卡
setbit sign 1 0 1表示周二,0表示未打卡
.......
查看某一天是否有打卡:
getbit sign 1
统计操作,统计打卡的天数:统计这周的打卡记录,就可以看到是否有全勤!
bitcount sign
10.Redis事务
正常执行事务:
multi 开启事务
set k1 v1 命令入队
exec 执行事务
放弃事务:
multi 开启事务
set k1 v1 命令入队
discard 取消事务
get k4 事务队列中命令都不会被执行



