web项目缓存配置及单点登录借助redis实现
来源:互联网 发布:暨南网络教学平台 编辑:程序博客网 时间:2024/05/18 00:25
最近项目在做多工程之间的缓存及单点登录时用到redis,心得总结如下:
- Redis是完全在内存中保存数据的数据库,使用磁盘只是为了持久性目的;
- Redis相比许多键值数据存储系统有相对丰富的数据类型;
- Redis可以将数据复制到任意数量的从服务器中;
Redis优点
异常快速 : Redis是非常快的,每秒可以执行大约110000设置操作,81000个/每秒的读取操作。
支持丰富的数据类型 : Redis支持最大多数开发人员已经知道如列表,集合,可排序集合,哈希等数据类型。
这使得在应用中很容易解决的各种问题,因为我们知道哪些问题处理使用哪种数据类型更好解决。操作都是原子的 : 所有 Redis 的操作都是原子,从而确保当两个客户同时访问 Redis 服务器得到的是更新后的值(最新值)。
- MultiUtility工具:Redis是一个多功能实用工具,可以在很多如:缓存,消息传递队列中使用(Redis原生支持发布/订阅),在应用程序中,如:Web应用程序会话,网站页面点击数等任何短暂的数据;
Redis环境
$sudo apt-get update$sudo apt-get install redis-server
启动 Redis
$redis-server
查看 redis 是否还在运行
$redis-cli
redis 127.0.0.1:6379>
redis 127.0.0.1:6379> pingPONG
在Ubuntu上安装Redis桌面管理器
Redis数据类型
字符串
示例
redis 127.0.0.1:6379> SET name "yiibai"OKredis 127.0.0.1:6379> GET name"yiibai"
哈希
示例
redis 127.0.0.1:6379> HMSET user:1 username yiibai password yiibai points 200OKredis 127.0.0.1:6379> HGETALL user:11) "username"2) "yiibai"3) "password"4) "yiibai"5) "points"6) "200"
列表
示例
redis 127.0.0.1:6379> lpush tutoriallist redis(integer) 1redis 127.0.0.1:6379> lpush tutoriallist mongodb(integer) 2redis 127.0.0.1:6379> lpush tutoriallist rabitmq(integer) 3redis 127.0.0.1:6379> lrange tutoriallist 0 101) "rabitmq"2) "mongodb"3) "redis"
集合
示例
redis 127.0.0.1:6379> sadd tutoriallist redis(integer) 1redis 127.0.0.1:6379> sadd tutoriallist mongodb(integer) 1redis 127.0.0.1:6379> sadd tutoriallist rabitmq(integer) 1redis 127.0.0.1:6379> sadd tutoriallist rabitmq(integer) 0redis 127.0.0.1:6379> smembers tutoriallist1) "rabitmq"2) "mongodb"3) "redis"
集合排序
示例
redis 127.0.0.1:6379> zadd tutoriallist 0 redis(integer) 1redis 127.0.0.1:6379> zadd tutoriallist 0 mongodb(integer) 1redis 127.0.0.1:6379> zadd tutoriallist 0 rabitmq(integer) 1redis 127.0.0.1:6379> zadd tutoriallist 0 rabitmq(integer) 0redis 127.0.0.1:6379> ZRANGEBYSCORE tutoriallist 0 10001) "redis"2) "mongodb"3) "rabitmq"
Redis键
语法
redis 127.0.0.1:6379> COMMAND KEY_NAME
示例
redis 127.0.0.1:6379> SET yiibai redisOKredis 127.0.0.1:6379> DEL yiibai(integer) 1
Redis字符串
语法
redis 127.0.0.1:6379> COMMAND KEY_NAME
示例
redis 127.0.0.1:6379> SET yiibai redisOKredis 127.0.0.1:6379> GET yiibai"redis"
Redis哈希
示例
redis 127.0.0.1:6379> HMSET yiibai name "redis tutorial" description "redis basic commands for caching" likes 20 visitors 23000OKredis 127.0.0.1:6379> HGETALL yiibai1) "name"2) "redis tutorial"3) "description"4) "redis basic commands for caching"5) "likes"6) "20"7) "visitors"8) "23000"
Redis列表
示例
redis 127.0.0.1:6379> LPUSH tutorials redis(integer) 1redis 127.0.0.1:6379> LPUSH tutorials mongodb(integer) 2redis 127.0.0.1:6379> LPUSH tutorials mysql(integer) 3redis 127.0.0.1:6379> LRANGE tutorials 0 101) "mysql"2) "mongodb"3) "redis"
Redis集合
示例
redis 127.0.0.1:6379> SADD yiibai redis(integer) 1redis 127.0.0.1:6379> SADD yiibai mongodb(integer) 1redis 127.0.0.1:6379> SADD yiibai mysql(integer) 1redis 127.0.0.1:6379> SADD yiibai mysql(integer) 0redis 127.0.0.1:6379> SMEMBERS yiibai1) "mysql"2) "mongodb"3) "redis"
Redis有序集合
在 Redis 有序集合添加,删除和测试成员的存在的时间复杂度为 O(1)(恒定时间,无论集合内包含元素的数量)。列表的最大长度为 232 - 1 个元素(4294967295,每个集合的元素超过四十亿)。
示例
redis 127.0.0.1:6379> ZADD yiibai 1 redis(integer) 1redis 127.0.0.1:6379> ZADD yiibai 2 mongodb(integer) 1redis 127.0.0.1:6379> ZADD yiibai 3 mysql(integer) 1redis 127.0.0.1:6379> ZADD yiibai 3 mysql(integer) 0redis 127.0.0.1:6379> ZADD yiibai 4 mysql(integer) 0redis 127.0.0.1:6379> ZRANGE yiibai 0 10 WITHSCORES1) "redis"2) "1"3) "mongodb"4) "2"5) "mysql"6) "4"
Redis HyperLogLog
Redis HyperLogLog 是用来做基数统计的算法,HyperLogLog 的优点是,在输入元素的数量或者体积非常非常大时,计算基数所需的空间总是固定 的、并且是很小的。
在 Redis 里面,每个 HyperLogLog 键只需要花费 12 KB 内存,就可以计算接近 2^64 个不同元素的基 数。这和计算基数时,元素越多耗费内存就越多的集合形成鲜明对比。但是,因为 HyperLogLog 只会根据输入元素来计算基数,而不会储存输入元素本身,所以 HyperLogLog 不能像集合那样,返回输入的各个元素。
示例
redis 127.0.0.1:6379> PFADD tutorials "redis"1) (integer) 1redis 127.0.0.1:6379> PFADD tutorials "mongodb"1) (integer) 1redis 127.0.0.1:6379> PFADD tutorials "mysql"1) (integer) 1redis 127.0.0.1:6379> PFCOUNT tutorials(integer) 3
Redis发布订阅
示例
redis 127.0.0.1:6379> SUBSCRIBE redisChatReading messages... (press Ctrl-C to quit)1) "subscribe"2) "redisChat"3) (integer) 1
redis 127.0.0.1:6379> PUBLISH redisChat "Redis is a great caching technique"(integer) 1redis 127.0.0.1:6379> PUBLISH redisChat "Learn redis by tutorials point"(integer) 11) "message"2) "redisChat"3) "Redis is a great caching technique"1) "message"2) "redisChat"3) "Learn redis by tutorials point"
Redis事务
- 在一个事务中的所有命令作为单个独立的操作顺序执行。在Redis事务中的执行过程中而另一客户机发出的请求,这是不可以的;
- Redis事务是原子的。原子意味着要么所有的命令都执行,要么都不执行;
示例
redis 127.0.0.1:6379> MULTIOKList of commands hereredis 127.0.0.1:6379> EXEC
示例
redis 127.0.0.1:6379> MULTIOKredis 127.0.0.1:6379> SET tutorial redisQUEUEDredis 127.0.0.1:6379> GET tutorialQUEUEDredis 127.0.0.1:6379> INCR visitorsQUEUEDredis 127.0.0.1:6379> EXEC1) OK2) "redis"3) (integer) 1
Redis脚本
语法
redis 127.0.0.1:6379> EVAL script numkeys key [key ...] arg [arg ...]
示例
redis 127.0.0.1:6379> EVAL "return {KEYS[1],KEYS[2],ARGV[1],ARGV[2]}" 2 key1 key2 first second1) "key1"2) "key2"3) "first"4) "second"
Redis连接
示例
redis 127.0.0.1:6379> AUTH "password"OKredis 127.0.0.1:6379> PINGPONG
Redis备份
语法
127.0.0.1:6379> SAVE
示例
127.0.0.1:6379> SAVEOK
恢复 Redis 数据
127.0.0.1:6379> CONFIG get dir1) "dir"2) "/user/yiibai/redis-2.8.13/src"
Bgsave
示例
127.0.0.1:6379> BGSAVEBackground saving started
Redis安全
示例
127.0.0.1:6379> CONFIG get requirepass1) "requirepass"2) ""
127.0.0.1:6379> CONFIG set requirepass "yiibaipass"OK127.0.0.1:6379> CONFIG get requirepass1) "requirepass"2) "yiibaipass"
语法
127.0.0.1:6379> AUTH password
Redis性能测试
语法
redis-benchmark [option] [option value]
示例
redis-benchmark -n 100000PING_INLINE: 141043.72 requests per secondPING_BULK: 142857.14 requests per secondSET: 141442.72 requests per secondGET: 145348.83 requests per secondINCR: 137362.64 requests per secondLPUSH: 145348.83 requests per secondLPOP: 146198.83 requests per secondSADD: 146198.83 requests per secondSPOP: 149253.73 requests per secondLPUSH (needed to benchmark LRANGE): 148588.42 requests per secondLRANGE_100 (first 100 elements): 58411.21 requests per secondLRANGE_300 (first 300 elements): 21195.42 requests per secondLRANGE_500 (first 450 elements): 14539.11 requests per secondLRANGE_600 (first 600 elements): 10504.20 requests per secondMSET (10 keys): 93283.58 requests per second
Redis客户端连接
- 客户端套接字在非阻塞状态,因为 Redis 使用复用和非阻塞I/O;
- TCP_NODELAY选项设定以确保不会在连接时延迟;
- 创建一个可读的文件事件,以便 Redis 能够尽快收集客户端查询作为新的数据可被套接字读取;
客户端最大连接数量
config get maxclients1) "maxclients"2) "10000"
示例
redis-server --maxclients 100000
Redis管道
- 客户端发送一个查询给服务器,并从套接字中读取,通常服务器的响应是在一个封闭的方式;
- 服务器处理命令并将响应返回给客户端;
管道的含义
示例
$(echo -en "PING\r\n SET tutorial redis\r\nGET tutorial\r\nINCR visitor\r\nINCR visitor\r\nINCR visitor\r\n"; sleep 10) | nc localhost 6379+PONG+OKredis:1:2:3
通道的好处
Redis分区
分区的好处
- 它允许更大的数据库,使用多台计算机的内存总和。如果不分区,只是一台计算机有限的内存可以支持的数据存储;
- 它允许按比例在多内核和多个计算机计算,以及网络带宽向多台计算机和网络适配器;
分区的劣势
- 涉及多个键的操作通常不支持。例如,如果它们被存储在被映射到不同的 Redis 实例键,则不能在两个集合之间执行交集;
- 涉及多个键时,Redis事务无法使用;
- 分区粒度是一个键,所以它不可能使用一个键和一个非常大的有序集合分享一个数据集;
- 当使用分区,数据处理比较复杂,比如要处理多个RDB/AOF文件,使数据备份需要从多个实例和主机聚集持久性文件;
- 添加和删除的容量可能会很复杂。例如:Redis的Cluster支持数据在运行时添加和删除节点是透明平衡的,但其他系统,如客户端的分区和代理服务器不支持此功能
分区类型
范围分区
散列分区
java环境下的应用代码如下:
package com.bimt.meet.utils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import org.apache.commons.lang.math.RandomUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.bimt.meet.common.DefineData;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.exceptions.JedisException;
/**
* Redis缓存辅助类
*
* @author xufeng
*/
public final class RedisUtils {
private static Logger logger = LoggerFactory.getLogger(RedisUtils.class);
public static final String TOKEN_ = "token:";
public static final String CACHE_BIMT_USERINFO_ = "cache:bimt:userinfo:";
private static JedisPool jedisPool;
static {
JedisPoolConfig config = new JedisPoolConfig();
//最大连接数, 应用自己评估,不要超过AliCloudDB for Redis每个实例最大的连接数
config.setMaxTotal(10000);
String host = DefineData.REDIS_HOST;//"192.168.0.123";
int port = Integer.parseInt(DefineData.REDIS_PORT);
String password = null;
jedisPool = new JedisPool(config, host, port, 3000, password);
}
/**
* 获取缓存
* @param key 键
* @return 值
*/
public static String get(String key) {
String value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
value = jedis.get(key);
value = StringUtils.isNotBlank(value) && !"nil".equalsIgnoreCase(value) ? value : null;
logger.debug("get {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("get {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 获取缓存
* @param key 键
* @return 值
*/
public static Object getObject(String key) {
Object value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(getBytesKey(key))) {
value = toObject(jedis.get(getBytesKey(key)));
logger.debug("getObject {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getObject {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 设置缓存
* @param key 键
* @param value 值
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static String set(String key, String value, int cacheSeconds) {
String result = null;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.set(key, value);
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("set {} = {}", key, value);
} catch (Exception e) {
logger.warn("set {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 设置过期时间
* @param key 缓存主键
* @param cacheSeconds 过期秒数
*/
public static void setExpire(String key, int cacheSeconds) {
Jedis jedis = getResource();
jedis.expire(key, cacheSeconds);
returnResource(jedis);
}
/**
* 设置缓存
* @param key 键
* @param value 值
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static String setObject(String key, Object value, int cacheSeconds) {
String result = null;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.set(getBytesKey(key), toBytes(value));
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("setObject {} = {}", key, value);
} catch (Exception e) {
logger.warn("setObject {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 获取List缓存
* @param key 键
* @return 值
*/
public static List<String> getList(String key) {
List<String> value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
value = jedis.lrange(key, 0, -1);
logger.debug("getList {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getList {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 获取List缓存
* @param key 键
* @return 值
*/
public static List<String> getObjectList(String key, int begin, int end) {
List<String> value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
List<String> list = jedis.lrange(key, begin, end);
value = Lists.newArrayList();
for (String bs : list){
value.add(bs);
}
logger.debug("getObjectList {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getObjectList {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 通过索引获取列表中的元素
* @param key 键
* @param index 索引
* @return 值
*/
public static String getObjectFromList(String key, int index) {
String value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
value = jedis.lindex(key, index);
logger.debug("getObjectList {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getObjectList {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 获取List缓存
* @param key 键
* @return 值
*/
public static List<Object> getObjectList(String key) {
List<Object> value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(getBytesKey(key))) {
List<byte[]> list = jedis.lrange(getBytesKey(key), 0, -1);
value = Lists.newArrayList();
for (byte[] bs : list){
value.add(toObject(bs));
}
logger.debug("getObjectList {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getObjectList {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 设置List缓存
* @param key 键
* @param value 值
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static long setList(String key, List<String> value, int cacheSeconds) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
jedis.del(key);
}
result = jedis.rpush(key, (String[])value.toArray());
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("setList {} = {}", key, value);
} catch (Exception e) {
logger.warn("setList {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 设置List缓存
* @param key 键
* @param value 值
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static long setObjectList(String key, List<Object> value, int cacheSeconds) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(getBytesKey(key))) {
jedis.del(key);
}
List<byte[]> list = Lists.newArrayList();
for (Object o : value){
list.add(toBytes(o));
}
result = jedis.rpush(getBytesKey(key), (byte[][])list.toArray());
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("setObjectList {} = {}", key, value);
} catch (Exception e) {
logger.warn("setObjectList {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 向List缓存中添加值
* @param key 键
* @param value 值
* @return
*/
public static long listAdd(String key, String... value) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.rpush(key, value);
logger.debug("listAdd {} = {}", key, value);
} catch (Exception e) {
logger.warn("listAdd {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 向List缓存中添加值
* @param key 键
* @param value 值
* @return
*/
public static long listObjectAdd(String key, Object value) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
String tmp = FastJsonUtils.toJson(value);
// List<String> list = Lists.newArrayList();
// for (Object o : value){
// String tmp = FastJsonUtils.toJson(o);
// list.add(tmp);
// }
result = jedis.rpush(key, tmp);
logger.debug("listObjectAdd {} = {}", key, value);
} catch (Exception e) {
logger.warn("listObjectAdd {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 获取缓存
* @param key 键
* @return 值
*/
public static Set<String> getSet(String key) {
Set<String> value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
value = jedis.smembers(key);
logger.debug("getSet {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getSet {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 获取缓存
* @param key 键
* @return 值
*/
public static Set<Object> getObjectSet(String key) {
Set<Object> value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(getBytesKey(key))) {
value = Sets.newHashSet();
Set<byte[]> set = jedis.smembers(getBytesKey(key));
for (byte[] bs : set){
value.add(toObject(bs));
}
logger.debug("getObjectSet {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getObjectSet {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 设置Set缓存
* @param key 键
* @param value 值
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static long setSet(String key, Set<String> value, int cacheSeconds) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
jedis.del(key);
}
result = jedis.sadd(key, (String[])value.toArray());
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("setSet {} = {}", key, value);
} catch (Exception e) {
logger.warn("setSet {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 设置Set缓存
* @param key 键
* @param value 值
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static long setObjectSet(String key, Set<Object> value, int cacheSeconds) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(getBytesKey(key))) {
jedis.del(key);
}
Set<byte[]> set = Sets.newHashSet();
for (Object o : value){
set.add(toBytes(o));
}
result = jedis.sadd(getBytesKey(key), (byte[][])set.toArray());
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("setObjectSet {} = {}", key, value);
} catch (Exception e) {
logger.warn("setObjectSet {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 向Set缓存中添加值
* @param key 键
* @param value 值
* @return
*/
public static long setSetAdd(String key, String... value) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.sadd(key, value);
logger.debug("setSetAdd {} = {}", key, value);
} catch (Exception e) {
logger.warn("setSetAdd {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 向Set缓存中添加值
* @param key 键
* @param value 值
* @return
*/
public static long setSetObjectAdd(String key, Object... value) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
Set<byte[]> set = Sets.newHashSet();
for (Object o : value){
set.add(toBytes(o));
}
result = jedis.rpush(getBytesKey(key), (byte[][])set.toArray());
logger.debug("setSetObjectAdd {} = {}", key, value);
} catch (Exception e) {
logger.warn("setSetObjectAdd {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 获取Map缓存
* @param key 键
* @return 值
*/
public static Map<String, String> getMap(String key) {
Map<String, String> value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
value = jedis.hgetAll(key);
logger.debug("getMap {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getMap {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 获取Map缓存
* @param key 键
* @return 值
*/
public static Map<String, Object> getObjectMap(String key) {
Map<String, Object> value = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(getBytesKey(key))) {
value = Maps.newHashMap();
Map<byte[], byte[]> map = jedis.hgetAll(getBytesKey(key));
for (Map.Entry<byte[], byte[]> e : map.entrySet()){
value.put(StringUtils.toString(e.getKey()), toObject(e.getValue()));
}
logger.debug("getObjectMap {} = {}", key, value);
}
} catch (Exception e) {
logger.warn("getObjectMap {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return value;
}
/**
* 设置Map缓存
* @param key 键
* @param value 值
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static String setMap(String key, Map<String, String> value, int cacheSeconds) {
String result = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)) {
jedis.del(key);
}
result = jedis.hmset(key, value);
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("setMap {} = {}", key, value);
} catch (Exception e) {
logger.warn("setMap {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 设置Map缓存
* @param key 键
* @param value 值
* @param cacheSeconds 超时时间,0为不超时
* @return
*/
public static String setObjectMap(String key, Map<String, Object> value, int cacheSeconds) {
String result = null;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(getBytesKey(key))) {
jedis.del(key);
}
Map<byte[], byte[]> map = Maps.newHashMap();
for (Map.Entry<String, Object> e : value.entrySet()){
map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
}
result = jedis.hmset(getBytesKey(key), (Map<byte[], byte[]>)map);
if (cacheSeconds != 0) {
jedis.expire(key, cacheSeconds);
}
logger.debug("setObjectMap {} = {}", key, value);
} catch (Exception e) {
logger.warn("setObjectMap {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 向Map缓存中添加值
* @param key 键
* @param value 值
* @return
*/
public static String mapPut(String key, Map<String, String> value) {
String result = null;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.hmset(key, value);
logger.debug("mapPut {} = {}", key, value);
} catch (Exception e) {
logger.warn("mapPut {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 向Map缓存中添加值
* @param key 键
* @param value 值
* @return
*/
public static String mapObjectPut(String key, Map<String, Object> value) {
String result = null;
Jedis jedis = null;
try {
jedis = getResource();
Map<byte[], byte[]> map = Maps.newHashMap();
for (Map.Entry<String, Object> e : value.entrySet()){
map.put(getBytesKey(e.getKey()), toBytes(e.getValue()));
}
result = jedis.hmset(getBytesKey(key), (Map<byte[], byte[]>)map);
logger.debug("mapObjectPut {} = {}", key, value);
} catch (Exception e) {
logger.warn("mapObjectPut {} = {}", key, value, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 移除Map缓存中的值
* @param key 键
* @return
*/
public static long mapRemove(String key, String mapKey) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.hdel(key, mapKey);
logger.debug("mapRemove {} {}", key, mapKey);
} catch (Exception e) {
logger.warn("mapRemove {} {}", key, mapKey, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 移除Map缓存中的值
* @param key 键
* @param mapKey 值
* @return
*/
public static long mapObjectRemove(String key, String mapKey) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.hdel(getBytesKey(key), getBytesKey(mapKey));
logger.debug("mapObjectRemove {} {}", key, mapKey);
} catch (Exception e) {
logger.warn("mapObjectRemove {} {}", key, mapKey, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 判断Map缓存中的Key是否存在
* @param key 键
* @param mapKey 值
* @return
*/
public static boolean mapExists(String key, String mapKey) {
boolean result = false;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.hexists(key, mapKey);
logger.debug("mapExists {} {}", key, mapKey);
} catch (Exception e) {
logger.warn("mapExists {} {}", key, mapKey, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 判断Map缓存中的Key是否存在
* @param key 键
* @param mapKey 值
* @return
*/
public static boolean mapObjectExists(String key, String mapKey) {
boolean result = false;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.hexists(getBytesKey(key), getBytesKey(mapKey));
logger.debug("mapObjectExists {} {}", key, mapKey);
} catch (Exception e) {
logger.warn("mapObjectExists {} {}", key, mapKey, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 删除缓存
* @param key 键
* @return
*/
public static long del(String key) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(key)){
result = jedis.del(key);
logger.debug("del {}", key);
}else{
logger.debug("del {} not exists", key);
}
} catch (Exception e) {
logger.warn("del {}", key, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 删除缓存
* @param key 键
* @return
*/
public static long delObject(String key) {
long result = 0;
Jedis jedis = null;
try {
jedis = getResource();
if (jedis.exists(getBytesKey(key))){
result = jedis.del(getBytesKey(key));
logger.debug("delObject {}", key);
}else{
logger.debug("delObject {} not exists", key);
}
} catch (Exception e) {
logger.warn("delObject {}", key, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 缓存是否存在
* @param key 键
* @return
*/
public static boolean exists(String key) {
boolean result = false;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.exists(key);
logger.debug("exists {}", key);
} catch (Exception e) {
logger.warn("exists {}", key, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 缓存是否存在
* @param key 键
* @return
*/
public static boolean existsObject(String key) {
boolean result = false;
Jedis jedis = null;
try {
jedis = getResource();
result = jedis.exists(getBytesKey(key));
logger.debug("existsObject {}", key);
} catch (Exception e) {
logger.warn("existsObject {}", key, e);
} finally {
returnResource(jedis);
}
return result;
}
/**
* 获取资源
* @return
* @throws redis.clients.jedis.exceptions.JedisException
*/
public static Jedis getResource() throws JedisException {
Jedis jedis = null;
try {
jedis = jedisPool.getResource();
} catch (JedisException e) {
logger.warn("getResource.", e);
returnBrokenResource(jedis);
throw e;
}
return jedis;
}
/**
* 归还资源
* @param jedis
*/
public static void returnBrokenResource(Jedis jedis) {
if (jedis != null) {
jedis.close();
// jedisPool.returnBrokenResource(jedis);
}
}
/**
* 释放资源
* @param jedis
*/
public static void returnResource(Jedis jedis) {
if (jedis != null) {
jedis.close();
// jedisPool.returnResource(jedis);
}
}
/**
* 获取byte[]类型Key
* @param object
* @return
*/
public static byte[] getBytesKey(Object object){
if(object instanceof String){
return StringUtils.getBytes((String)object);
}else{
return ObjectUtils.serialize(object);
}
}
/**
* Object转换byte[]类型
* @param object
* @return
*/
public static byte[] toBytes(Object object){
return ObjectUtils.serialize(object);
}
/**
* byte[]型转换Object
* @param bytes
* @return
*/
public static Object toObject(byte[] bytes){
return ObjectUtils.unserialize(bytes);
}
/**
* 获取列表长度
* @param key
* @return 长度
*/
public static int getListSize(String key) {
Jedis jedis = null;
long size = 0;
try {
jedis = getResource();
if (jedis.exists(key)) {
size = jedis.llen(key);
} else {
return 0;
}
} catch (Exception e) {
logger.warn("getListSize {}", key, e);
} finally {
returnResource(jedis);
}
return Long.valueOf(size).intValue();
}
/**
* 生成token
* @return
*/
public static String createToken() {
StringBuffer sbf = new StringBuffer();
sbf.append(System.currentTimeMillis());
sbf.append(UUID.randomUUID().toString().replace("-", ""));
sbf.append(RandomUtils.nextInt(999));
return sbf.toString();
}
}
这里只是简单的应用,其中还有更深层次的应用,有兴趣者可共同探讨
- web项目缓存配置及单点登录借助redis实现
- web项目配置redis缓存
- Redis实现单点登录
- .NET基于Redis缓存实现单点登录SSO的解决方案
- .NET基于Redis缓存实现单点登录SSO的解决方案
- .NET基于Redis缓存实现单点登录SSO的解决方案
- .NET基于Redis缓存实现单点登录SSO的解决方案
- redis实现单点登录系统
- 借助共享缓存redis实现分布式锁
- java Web单点登录(SSO)原理及简单实现
- 单点登录SSO项目配置
- Web单点登录的实现
- redis实现session共享,实现单点登录
- 借助sentinel 实现redis集群HA配置
- 基于cookie-redis实现单点登录
- java 实现单点登录及后门登录
- java cas 单点登录web.xml配置
- java cas 单点登录web.xml配置
- 安卓如何通过APP来判断用户使用的模拟器还是真正的安卓设备
- 关于webstorm的注册破解问题
- Flink流计算编程:双流中实现Inner Join、Left Join与Right Join
- |Tyvj|动态规划|P3573 求最长不下降序列
- QDUOJ 67 - 礼上往来(错排公式)
- web项目缓存配置及单点登录借助redis实现
- hdu1238Substrings
- tomcat结合nginx使用小结
- E - More is better
- 类的内存占用大小
- java学习笔记
- 插入排序法
- RegisterClassEx、CreateWindow、DefWindowProc
- java ftp上传时候可能出现的问题(新手专用)