一. Redis介绍.
-
Redis介绍.
Redis的作者是一位意大利人.
在2004年左右和朋友开发了一个统计的网站LLOOGG,一直使用的是mysql,mysql的性能太烂了,自己研发了一个非关系型数据库,Redis,同年Redis对外开源.
意大利人刚刚创业写的LLOOGG不管了,直接专心维护Redis. 新浪.
Redis(全称:Remote Dictionary Server 远程字典服务)是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。从2010年3月15日起,Redis的开发工作由VMware主持。从2013年5月开始,Redis的开发由Pivotal赞助。 -
NOSql.
Not Only SQL -> 非关系型数据库.
除了关系型数据库都是非关系型数据库.
关系型数据库: 有表的.
Mysql.
Oracle.
SqlServer.
DB2…
非关系型数据库:
表之间没有关系.
没有表.
1. Key-Value型非关系型数据库.
Redis. M…Cache.
2. 文档存储的非关系型数据库
ElasticSearch.
3. 面向列的非关系型数据库
HBase.
4. 图形化的非关系型数据库
Neo4j. -
Redis的优势.
-
Redis的性能优势.
读的速度是110000次/s,写的速度是81000次/s 。 -
Redis是单线程的.
实现分布式锁. -
Redis除了Key-Value的存储结构,还提供了很多其他的存储结构.
Key-Hash,Key-List,Key-Set,Key-SortedSet -
Redis提供了多种持久化的机制.
RDB – AOF -
Redis还提供了集群的搭建,并且不依赖外部环境(5.0以上版本)
集群时无中心,等等… -
提供了多种原因的API…
Jedis,卷心菜.
…
做缓存.
做session共享.
实现分布式锁.
-
二. 安装Redis.
-
安装Redis.
-
下载Redis的压缩包.
wget http://download.redis.io/releases/redis-5.0.7.tar.gz -
解压.
tar -zxvf redis-5.0.7.tar.gz -C /usr/local -
直接使用C语言的环境去编译并安装Redis.
cd /usr/local/redis-5.0.7
make
make install PREFIX=/usr/local/redis -
启动.
cd /usr/local/redis/bin
./redis-server -
连接.
单独开启一个ssh连接.
cd /usr/local/redis/bin
./redis-cli -h localhost -p 6379
-
-
Redis的配置.
vi后跳转到指定行 :to 行数-
Redis需要占满整个界面保证Redis进程的运行.
开启守护进程
daemonize no -> yes (5.0.6 -> 136行) -
远程连接Redis.
关闭绑定本地的配置
bind 127.0.0.1 -> 将其注释. (5.0.6 -> 69行)
关闭redis的保护机制
protected-mode yes -> no. (5.0.6 -> 88行) -
在windows中使用Redis-DeskTop-Manager连接Redis服务
-
三. Redis的简单操作命令.
文档: http://doc.redisfans.com/
-
key.(晨考)
删除key:
del key…设置生存时间(活多久):
expire key second设置生存时间(活到什么时候):
expireat key timestamp查看redis中存活的全部key:
keys pattern(前缀*)设置生存时间(活多久,毫秒):
pexpire key milliSecond查看当前Key的生存情况:
ttl key
当 key 不存在时,返回 -2 。
当 key 存在但没有设置剩余生存时间时,返回 -1 。
否则,以秒为单位,返回 key 的剩余生存时间。 -
String.(晨考)
设置值:
set key value
取值:
get key
自增一: (如何key已经存在,那么对应的value必须是一个数值,如果key不存在,设置一个key,值为1)
incr key
自减一: (如何key已经存在,那么对应的value必须是一个数值,如果key不存在,设置一个key,值为-1)
decr key
自增|自减指定数值:
incrby|decrby key increment
自增指定浮点数:
incrbyfloat key increment
设置值的同时指定生存时间.
setex key second value
分布式锁在操作:
setnx key value (会返回设置是否成功)
(set if not exists)
getset key value
(先get获取值,再set设置值,解决redis分布式锁的死锁问题)
四. 使用Java连接Redis.
-
Jedis.
@Test public void test(){ //1. 建立连接. Jedis jedis = new Jedis("192.168.98.98",6379); //2. 操作. //------------------------------------------------------------- /*jedis.set("name","李四"); // redis天然幂等操作. System.out.println("OK!");*/ //------------------------------------------- // commons-lang3, spring-context // 准备value /*User value = new User(); value.setId(1); value.setName("王五"); // 准备key String key = "user"; //使用工具类序列化操作 byte[] serializeKey = SerializationUtils.serialize(key); byte[] serializeValue = SerializationUtils.serialize(value); // 调用jedis存储 jedis.set(serializeKey,serializeValue); System.out.println("OK!!");*/ //---------------------------------------------------- //获取redis中存储的byte[] /*String key = "user"; byte[] serializeKey = SerializationUtils.serialize(key); // 获取value byte[] serializeValue = jedis.get(serializeKey); // 反序列化 User user = (User) SerializationUtils.deserialize(serializeValue); System.out.println(user);*/ //------------------------------------------------------------- //3. 释放资源. jedis.close(); }
-
JedisPool.
@Test public void test(){ //1. 创建连接池. JedisPool jedisPool = new JedisPool("192.168.98.98",6379); //2. 通过连接池获取jedis对象 Jedis jedis = null; try { jedis = jedisPool.getResource(); //3. 操作................. int i = 1 / 0; // / by zero } finally { //4. 释放资源 jedis.close(); } }
五. 使用SpringBoot连接Redis.
- 创建项目.
…
-
导入依赖.
spring-boot-starter-data-redis
spring-boot-starter-data-jpa
不好用…
springcloud的主要贡献者,对jpa,hibernate,mybatis
jpa – 56%
mybatis – 10% -
编写配置文件.
spring:
redis:
host: 192.168.98.98
port: 6379 -
测试.
@Autowired // 如果不加泛型,默认全部以byte[]的方式存储. private RedisTemplate<String,String> redisTemplate; @Test public void contextLoads() { //1. 指定操作String的数据类型. redisTemplate.opsForValue().set("hobby","ctrl",1, TimeUnit.DAYS); //2. 操作key直接使用 redisTemplate.delete("hobby"); }
六. 进销存使用Redis实现Shiro的session共享.
-
实现Shiro的Session共享.
-
找到SessionDAO接口.
Shiro默认使用的的MemorySessionDAO的实现类.
Shiro默认将session对象存放到了本地的一个ConcurrentHashMap中. -
需要自定义一个SessionDAO的实现类.
创建了一个POJO类.RedisSessionDAO继承了一个抽象类AbstractSessionDAO. -
重写5个方法.
-
创建Session. -> 传入了一个Session.
//1. 生成一个SessionId.//2. 将SessionId和Session绑定到一起.
//3. 将SessionId和Session存储到redis.
//4. 返回SessionId.
-
读取Session.
//1. 封装key.//2. 去redis中查询session
//3. 重新设置生存时间
//4. 返回session
-
修改Session.
//1. 根据session获取sessionId.//2. 声明key和value.
//3. 存储到redis中.
-
删除Session.
//1. 根据session获取sessionId.//2. 声明key
//3. 删除指定的key
-
查询全部存活的Session.
//1. 封装pattern//2. 封装返回结果
//3. 通过keys查询全部存活的key.
//4. 遍历全部的key
//通过key获取session,并添加到返回结果
//5. 返回返回结果
-
-
-
重写doCreateSession.
@Override
protected Serializable doCreate(Session session) {
//1. 获取一个sessionId – String
Serializable sessionId = super.generateSessionId(session);
//2. 将sessionId和session绑定到一起.
super.assignSessionId(session,sessionId);
//3. 将sessionId作为key,session作为value存储到redis中,并同时设置生存时间.
String key = SHIRO_KEY + sessionId;
redisTemplate.opsForValue().set(key,session,TIME_OUT, TimeUnit.MINUTES);
//4. 返回sessionId
return sessionId;
} -
重写doReadSession.
// 获取session信息,去Redis中获取
@Override
protected Session doReadSession(Serializable sessionId) {
//1. 封装key.
String key = SHIRO_KEY + sessionId;
//2. 去redis中查询session
Session session = (Session) redisTemplate.opsForValue().get(key);
//3. 重新设置生存时间.
redisTemplate.expire(key,TIME_OUT,TimeUnit.MINUTES);
//4. 返回session
return session;
} -
重写updateSession
// 修改用户信息. 修改Redis中的信息.
@Override
public void update(Session session) throws UnknownSessionException {
//1. 根据session获取sessionId.
Serializable sessionId = session.getId();
//2. 声明key和value.
String key = SHIRO_KEY + sessionId;
//3. 存储到redis中.
redisTemplate.opsForValue().set(key,session,TIME_OUT,TimeUnit.MINUTES);
} -
重写deleteSession
@Override
public void delete(Session session) {
//1. 根据session获取sessionId.
Serializable sessionId = session.getId();
//2. 声明key
String key = SHIRO_KEY + sessionId;
//3. 删除指定的key
redisTemplate.delete(key);
} -
重写getActiveSession
// 获取全部存活的session
@Override
public Collection getActiveSessions() {
//1. 封装pattern
String pattern = SHIRO_KEY + “*”;
//2. 封装返回结果
Set sessionSet = new HashSet<>();
//3. 通过keys查询全部存活的key.
Set keys = redisTemplate.keys(pattern);
//4. 遍历全部的key
for (Object key : keys) {
//通过key获取session,并添加到返回结果
Session session = (Session) redisTemplate.opsForValue().get(key);
sessionSet.add(session);
}
//5. 返回返回结果
return sessionSet;
}- 将SessionDAO配置给Shiro.
2.1 将SessionDAO配置给SecurityManager.
@Bean
public DefaultWebSecurityManager securityManager(JxcRealm realm, RedisSessionDAO redisSessionDAO){
//1. 创建DefaultWebSecurityManager
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//2. 创建SessionManager
DefaultWebSessionManager sessionManager = new DefaultWebSessionManager();
//3. 将redisSessionDAO设置到sessionManager中
sessionManager.setSessionDAO(redisSessionDAO);
//4. 将sessionManager设置给SecurityManager
securityManager.setSessionManager(sessionManager);
//5. 注入自定义Realm
securityManager.setRealm(realm);
//6. 返回
return securityManager;
}
-
自定义SessionManager避免频繁访问Redis.
public class RedisSessionManager extends DefaultWebSessionManager { @Override protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException { //1. 获取sessionId. Serializable sessionId = getSessionId(sessionKey); if (sessionId == null) { return null; } //2. 先去request域中查询. WebSessionKey webSessionKey = (WebSessionKey) sessionKey; ServletRequest req = webSessionKey.getServletRequest(); Session session = (Session) req.getAttribute(sessionId.toString()); //3. 如果有结果直接返回. if(session == null){ // 去redis中查询retrieveSessionFromDataSource session = super.retrieveSessionFromDataSource(sessionId); // 将查询到的结果放到request域中. req.setAttribute(sessionId.toString(),session); } //4. 返回session return session; }
}
配置到shiroConfig中
@Bean
public DefaultWebSecurityManager securityManager(JxcRealm realm, RedisSessionDAO redisSessionDAO){
//1. 创建DefaultWebSecurityManager
DefaultWebSecurityManager securityManager = new DefaultWebSecurityManager();
//2. 创建SessionManager
RedisSessionManager sessionManager = new RedisSessionManager();
//3. 将redisSessionDAO设置到sessionManager中
sessionManager.setSessionDAO(redisSessionDAO);
....
}
本文地址:https://blog.csdn.net/qq_28871287/article/details/108566470